今さらPython3 (58) - dbm, memcached

第8章継続中。入門と言いながら、NoSQLにも少し触れているあたり良いですね。

入門 Python 3

入門 Python 3

dbm

>>> import dbm
>>> db = dbm.open('definitions', 'c')
>>> len(db)
0
>>> db['mustard'] = 'yellow'
>>> db['ketchup'] = 'red'
>>> db['pesto'] = 'green'
>>> 
>>> len(db)
3
>>> db['pesto']
b'green'

ほぼ辞書ですやん。でも、保存されているのが違いなんだよね?ということで確認。

>>> db.close()
>>> db = dbm.open('definitions', 'r')
>>> db['mustard']
b'yellow'
>>> 

閉じてから、またファイルを開いて表示。ちなみに頭のbが示すとおりバイナリになっているので、文字列として扱う場合はdecode('utf-8')してやる必要がある。

>>> db = dbm.open('definitions', 'c')
>>> db['wasabi'] = 'わさび色'
>>> db['wasabi'] 
b'\xe3\x82\x8f\xe3\x81\x95\xe3\x81\xb3\xe8\x89\xb2'
>>> db['wasabi'].decode('utf-8')
'わさび色'

memcached

memcached.org

メムキャッシュド?これまた初めて聞く名前。とりあえずインストールしてみる。

$ brew install memcached
==> Installing memcached dependency: libevent
==> Downloading https://homebrew.bintray.com/bottles/libevent-2.0.22.yosemite.bottle.tar.gz
######################################################################## 100.0%
==> Pouring libevent-2.0.22.yosemite.bottle.tar.gz
🍺  /usr/local/Cellar/libevent/2.0.22: 48 files, 1.8M
==> Installing memcached
==> Downloading https://homebrew.bintray.com/bottles/memcached-1.4.24.yosemite.bottle.tar.gz
######################################################################## 100.0%
==> Pouring memcached-1.4.24.yosemite.bottle.tar.gz
==> Caveats
To have launchd start memcached at login:
    ln -sfv /usr/local/opt/memcached/*.plist ~/Library/LaunchAgents
Then to load memcached now:
    launchctl load ~/Library/LaunchAgents/homebrew.mxcl.memcached.plist
Or, if you don't want/need launchctl, you can just run:
    /usr/local/opt/memcached/bin/memcached
==> Summary
🍺  /usr/local/Cellar/memcached/1.4.24: 10 files, 192K

Homebrewを使ってサクッとインストールだん。

Homebrew — OS X 用パッケージマネージャー

さらにPythonのドライバを入れる。今度はpipの出番だね。

$ pip3 install python-memcached
Collecting python-memcached
  Downloading python_memcached-1.57-py2.py3-none-any.whl
Requirement already satisfied (use --upgrade to upgrade): six in /Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages (from python-memcached)
Installing collected packages: python-memcached
Successfully installed python-memcached-1.57

名前からして、メモリにキャッシュするというものでしょ。その前に、ターミナルウィンドウをもう1つひらいて、memcachedを起動しておこう。

$ memcached start

何のレスポンスもないので、起動しているのかよく分からないけど、とりあえずPython側で触ってみる。

>>> db = memcache.Client(['127.0.0.1:11211'])
>>> db.set('marco', 'polo')
True
>>> db.get('marco')
'polo'
>>> db.set('ducks', 0)
True
>>> db.get('ducks')
0
>>> db.incr('ducks', 2)
2
>>> db.get('ducks')
2
>>> 

ほんとにmemcachedが動いているのか不安だったので、Ctrl+Cでmemcacedを止めて、試してみた。

>>> db.get('ducks')
>>>
>>> db.set('bird', 'pinochio')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/memcache.py", line 700, in set
    return self._set("set", key, val, time, min_compress_len, noreply)
  File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/memcache.py", line 983, in _set
    server, key = self._get_server(key)
  File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/memcache.py", line 413, in _get_server
    serverhash = serverHashFunction(str(serverhash) + str(i))
  File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/memcache.py", line 65, in cmemcache_hash
    (((binascii.crc32(key) & 0xffffffff)
TypeError: 'str' does not support the buffer interface
>>> 

もう少し親切なログを吐いてくれても良いような気がするけど。

キャッシュというぐらいなので、あまり変更頻度の高くないけどアクセスの多いデータをメモリ空間にキャッシュしておくことで、高速アクセスが可能という用途だと想像。コミュニケーションに掛かる時間を考えると、

DBのディスクにアクセス > DBがキャッシュしているメモリにアクセス > アプリで使っているメモリ領域にアクセス

となるはずなので、アクセスが頻繁に起こるようなアプリだとこういうmemcachedなんかも選択肢に入ってくるんだろうね。

memcachedの使い方という内容で、このブログできれいにまとめられている。
promamo.com

(つづく)