Python学習【365日チャレンジ!】145日目のマスターU(@Udemy11)です。
あまりにお腹がすきすぎると意識を失ってしまいそうになるときがあります。
意識を失う前になにか食べるので、実際に意識を失ったことはありませんが、なにかに集中して時間を忘れると気づいたときにはお腹がすきすぎているなんてことは何度がありました。
それくらい集中してPythonを学べばもっと上達は早くなるんだろうなーと思う今日このごろです。
それでは今日もPython学習を始めましょう。
昨日の復習
昨日はDBM(DataBase Management)を学習しました。
非常に簡易なデータベースで、辞書型データを使って利用しましたが、扱えるのは文字列だけで、Integer(整数)などを扱うことはできないので、ほんとに簡単な使い方で活用するとのことでした。
DBMの詳細については、こちらの記事をごらんください。
今日は、memcachedについて学習しましょう!
memcachedとは
memocachedは、高性能な分散メモリキャッシュサーバーですが、よくわからないですよね。
簡単に解説すると、処理を高速化するためのものです。
それでもよくわからないかも。。。
基本、Webアプリケーションなどは、データベースとのやり取りを行うことで要求された処理をしているわけですが、データベースへの問い合わせが混雑すると処理が遅れてしまいます。
処理が遅れないように、メモリにキャッシュしてデータベースへの問い合わせを調整してくれるツールがmemocachedで、いってみればスーパーの駐車場案内係みたいなものですね。
とりあえずいっぱいになったら待たせておいて、空いたら案内するって感じかな。
それではまず、memcachedをインストールしていきましょう。
memcachedのインストール
memcachedのインストールは、brew
を使ってインストールします。
brew
のインストールについては、こちらの記事をごらんください。
memcachedをインストールするには、ターミナルでbrew install memcached
を実行します。
brew
のアップデートがたくさんあったようで、私は結構時間がかかりました。
次に、pip
インストールを使って次のコマンドpip install python-memcached
を実行し、python-memcached
をインストールします。
私のPycharmの調子が悪いのか、pip
インストールで入れてもPythonファイルでインポートエラーが起こっていたので、Preferencesからインストールしました。
Preferencesからのインストールについては、こちらの記事を参考にしてください。
インストールが完了すれば、実際にコードを書いていきます。
memcachedの使い方
それでは早速memcachedを使っていきますが、最初にターミナルからmemcached -vv
を実行します。(終了するときは、control
+c
)
これでPythonからmemcachedを利用することができます。
Pythonファイルに次のコードを書いて実行してみましょう。
import memcache
db = memcache.Client(['127.0.0.1:11211'])
db.set('test_page', 'value1')
print(db.get('test_page'))
ホストが127.0.0.1
で、ポートが11211
ですが、127.0.0.1
をlocalhost
にしても大丈夫です。
コンソールへの出力はvalue1
ですが、ターミナルを見てみると、どのような処理がされているのかがわかります。
処理としては、ローカルホストにmemcacheを辞書型でセットして、キーがtest_page
のバリューを取り出しています。
最後は、接続を閉じています。
キャッシュの時間をコントロール
memcachedはメモリーにデータをキャッシュしますが、その時間はデフォルトで5分です。
キャッシュの時間を1秒にして、time
モジュールを使って処理を2秒待ってから実行すると、保存したデータは1秒でクリアーされているので、出力はNone
が返されます。
import time
import memcache
db = memcache.Client(['localhost:11211'])
db.set('test_page', 'value1', time=1)
time.sleep(2)
print(db.get('test_page'))
最初に標準モジュールtime
をインポートして、db.set
の引数time=1
でキャッシュの時間を1秒にしてからtime.sleep(2)
で出力を2秒待っています。
データはすでにクリアされているので、コンソールへの出力結果はNone
になります。
SQLiteと組み合わせる
次に、SQLiteと組み合わせてデータベースを扱ってみましょう。
import sqlite3
import memcache
db = memcache.Client(['localhost:11211'])
conn = sqlite3.connect('test_sqlite3.db')
cursor = conn.cursor()
cursor.execute('CREATE TABLE persons(employ_id INTEGER PRIMARY KEY AUTOINCREMENT, name STRING)')
cursor.execute('INSERT INTO persons(name) values("Mark")')
conn.commit()
def get_employ_id(name):
employ_id = db.get(name)
if employ_id:
return employ_id
cursor.execute('SELECT * FROM persons WHERE name = "{}"'.format(name))
person = cursor.fetchone()
if not person:
return Exception('No employ')
employ_id, name = person
db.set(name, employ_id, time=60)
return employ_id
print(get_employ_id("Mark"))
cursor.close()
conn.close()
流れを見ていきましょう
sqlite3
モジュールを追加で読み込んで、7行目から11行目までは、以前学習したSQLiteの扱いと同じです。employ_id
をプライマリーキーの整数にして、自動で番号が振られるようにして、名前は、STRINGER
で指定したのち、10行目でMark
のレコードを追加しています。
13行目から23行目は関数の定義ですが、まずmemcachedでキャッシュに保存されているname
から引数name
と同じレコードのkey
の値employ_id
を取り出し、値が存在すればemploy_id
を返します。
それ以外のときは、SQLiteのデータベースから引数name
を取得して、最初のデータをcursor.fetchone()
でperson
に代入します。
person
に値がない時はエラー(No employ
)を返しますが、存在する場合は、person
をアンパッキングして、60秒間だけ取り出したname
とemploy_id
を保有し、employ_id
を返します。
最後に25行目で、Mark
を引数にして関数get_employ_id
を実行して出力しているので、出力結果は自動的に入力された1
になります。
キャッシュから読み込む
例えばブラウザーでページを更新しても古いページが表示されることがあります。
これは、memkcachedの仕業だったのかしれません
要するに、いちいちデータベースに問い合わせることなく残されたキャッシュを表示するのため、高速にページを表できるのと同じような役割を持っています。
リクエストを送って返ってくるのをまつより、自分のMacの中に保存されていれば、より高速にデータを表示できるというわけです。
要するにキャッシュ化から読み込むことで、スピードアップを図ることができるということです。
いろいろと勉強すればするほど、もっと勉強しないといけないことに気付いてしまうので、ほんと悩ましい限りです。
今日は、このくらいにして明日もしっかり学習したいと思います。
それでは、明日もGoodbye