redisで遊んでみた with python

概要

redisで遊んでた(?)先輩がいたので、自分はmemcachedしか使ったこと無かったこともあり、とりあえず触ってみようと思い遊んでみることにした。
ひとまずは、redisの特徴、インストール手順、コンソールからのset/get、pythonからのset/getの手順について以下に記載する。

redisとは

redisとはopensourceなkey-value store(kvs)/インメモリDBである。
基本的にはmemcachedなども同じようなkvsであるが、以下の点で"advanced"である。

  1. ハッシュ以外のデータ構造もサポートしている。リスト型、集合型、順序付き集合型などのデータ構造が扱え、サーバ側でコレクションに対するpush/pop、コレクション同士のunion/intersection、数値のincr、decrなどの操作がアトミックに行える。
  2. マスター・スレーブによるレプリケーション設定ができ、リード側のスケールアウトが容易にできる。
  3. メモリ上のデータセットをプライマリとしつつ、非同期でディスクへ書き出しできること。ディスク書き出しのタイミングは、設定で経過秒数や累積オペレーション数を指定できる。

(上記三点の特徴は、ほぼhttp://www.atmarkit.co.jp/news/201009/07/redis.htmlより引用)

インストール手順

$ sudo apt-get install redis-doc redis-server
$ sudo apt-get install python-redis

※Ubuntu10.10環境でinstall。versionは、redis-serverは2:2.0.0~rc2-1、python-redisは2.0.0-1であった。

動作確認

上記インストール後、サーバが起動している。
起動しているかどうかはプロセスが居るか、port 6379がopenしていることで確認する。

プロセスの起動確認

プロセスが起動しているか、以下のコマンドで確認できる。

$ ps aux|grep redis
redis     5053  0.0  0.0   2872  1072 ?        Ss   11:06   0:01 /usr/bin/redis-server /etc/redis/redis.conf
1000      6613  0.0  0.0   4980   780 pts/1    S+   12:53   0:00 grep --color=auto redis
ポートのオープン確認

redisが起動時にopenするportは以下の6379である。
以下のコマンドで開いている事が確認できる。

$ netstat -aunt|grep 6379
tcp        0      0 127.0.0.1:6379          0.0.0.0:*               LISTEN     

redisにデータを保存/取得(コンソールで確認)

telnetを使い、redisに接続して直接コマンドラインで操作を行ってみる。

$ telnet localhost 6379
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
set mykey 5  <- setコマンドで${key}を保存。5は文字列長。
Hello        <- ${key}に対する${value}を保存。
+OK
keys *       <- key一覧
*1           <- 1つ保存されている
$5           
mykey
get mykey    <- get ${key}で ${key}に保存されているvalueを取得
$5
Hello        <- さっき保存したのがとれた
del mykey    <- del ${key}でkey,valueを削除
:1
keys *       <- key一覧
*0           <- もう消えたのでない

^]

telnet> exit
?Invalid command
telnet> quit
Connection closed.

※上記は、「Redis X Java入門。RedisのインストールからクライアントライブラリJedisの使い方まで」(http://d.hatena.ne.jp/hrendoh/20110901/1314887550)とまったく同じ手順で同じことが出きることを確認した。

redisにデータを保存/取得(pythonで確認)

pythonからもredisに対して操作できる事を確認した。

$ python
Python 2.6.6 (r266:84292, Sep 15 2010, 15:52:39) 
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import redis
>>> r = redis.Redis(host='127.0.0.1', port=6379, db=0)
>>> r.set('nihohi','unpopo')  # <-- key,valueの登録
True
>>> print r.get('nihohi') # <--keyを指定してvalueを取得
unpopo
>>> 

sub/pub通信

redisでは、sub/pub通信をサポートしているらしい。
よく知らないので調べてみた。

pub/sub型通信とは

メッセージを作成して送信する送信側サーバをpublisher、受信する側のクライアントをsubscriberとするメッセージングモデルのことで、以下の特徴がある。

(wikipediaより)
出版-購読型モデル(しゅっぱん-こうどくがたモデル、英: Publish/subscribe)は、非同期メッセージングパラダイムの一種であり、メッセージの送信者(出版側)が特定の受信者(購読側)を想定せずにメッセージを送るようプログラムされたものである。出版されたメッセージにはクラス分けされ、購読者に関する知識を持たない。購読側は興味のあるクラスを指定しておき、そのクラスに属するメッセージだけを受け取り、出版者についての知識を持たない。出版側と購読側の結合度が低いため、スケーラビリティがよく、動的なネットワーク構成に対応可能である。
出版-購読型モデルはメッセージキューパラダイムと対比され、一般に大きなメッセージ指向ミドルウェアの一部として使われる。一部のメッセージシステム(Java Message Serviceなど)は、出版-購読型とメッセージキューの両モデルをサポートしている。

(multicastを抽象的にとらえてみた感じ?pub/subモデルの1実装がmulticastとかなのかな?)
KVSにこういった機能が備わっているのは珍しいらしい。

「RedisのPub/Subは面白そう at Kitazawa.rb」(http://blog.mah-lab.com/2011/11/26/kitazawa-rb-10/)によると、「リアルタイムWebが注目される昨今ではかなり使えそうな機能で、Redisを中継サーバとすることでWebSocketサーバをスケールアウトさせることができる」とのこと。
まだちゃんとは理解できていないので、もうちょっと勉強しておきたい。

参考

本家
http://redis.io/

Redis の Pub/Sub を使って Node.js + WebSocket のスケールアウトを実現する方法
http://firn.jp/2011/06/19/nodejs-redis-pubsub

Redis X Java入門。RedisのインストールからクライアントライブラリJedisの使い方まで
http://d.hatena.ne.jp/hrendoh/20110901/1314887550

key-value database RedisにPythonで接続する(redis-py使用)
http://symfoware.blog68.fc2.com/blog-entry-406.html

バージョン2.0がリリース memcachedと“正反対”、Redisが仮想メモリをサポート
http://www.atmarkit.co.jp/news/201009/07/redis.html

RedisのPub/Subは面白そう at Kitazawa.rb
http://blog.mah-lab.com/2011/11/26/kitazawa-rb-10/