最近話題のRedisをさわってみました。
KVSとかNoSQLって呼ばれるRedisですが似たようなアプリケーションにMemcachedがあります。 Memcachedとの大きな違いとして
1)リスト型、集合型とかいろんなデータ構造が扱える 2)データの永続化ができる 3)レプリケーションができる
があるのではないかと思います。 速さは当然Memcachedが最高なんですが、それなりに高速で、しかも結構複雑なことができるようです。
インストール
インストールはここから。 http://redis.io/download
cd /usr/local/src wget http://redis.googlecode.com/files/redis-2.6.9.tar.gz tar zxvf redis-2.6.9.tar.gz cd redis-2.6.9 make test make make install
※make installするかどうかはお好みで。。
たくさんの環境にインストールしてみたんですが、環境によってはmake testでこんなエラーが。
You need 'tclsh8.5' in order to run the Redis test
この場合は言われたとおり、以下のパッケージを入れると解決した。(debian)
apt-get install tcl8.5
起動
redis-server
これでサーバが起動します。デフォルトではポート6379。 なんか弁当箱みたいなんが出て、以下のような記述が出ればOK。
[4350] 23 Jan 03:34:53.245 * The server is now ready to accept connections on port 6379
起動させたまま、別のターミナルでredis-cliを実行
redis-cli
これでredisを操作できます。 地味にクライアント用プログラムがあるのはうれしいですね。 redis-cli < commands.txt こんな感じでコマンドを渡すこともできるようです。
生きてますかー?的なテスト
redis 127.0.0.1:6379> ping PONG
値を入れたりとってきたり。
redis 127.0.0.1:6379> set foo bar OK redis 127.0.0.1:6379> get foo "bar" redis 127.0.0.1:6379> quit
このように動作すればとりあえずインストールはOK
設定
展開したソースのredis.confが元になるので これをコピーしておきます。 適当に/etc/に置くことにしました。
cp redis.conf /etc/ vi /etc/redis.conf
さまざまな設定項目がありますが、とりあえず現在は以下の項目を変更しました。
デーモンとして起動する。デバック中とか遊んでる途中ならnoでもいいと思います。
daemonize no ↓ daemonize yes
メモリのダンプファイルを保存する場所。永続化はこのファイルが書き出されることで実現してます。
dir ./ ↓ /usr/local/redis/ (適当に)
使用するメモリサイズ。
# maxmemory ↓ maxmemory 10240000 (適当に)
設定したconfを読み込んで起動。 このように設定ファイルを指定しないとデフォルト設定で立ち上がるので注意。
redis-server /etc/redis.conf
いったん立ち上げたredis-serverを再起動すると設定が反映されます。
もうちょっとredis-cliを使ってみます
当然こちらを見るよりこ公式ドキュメントが非常に充実していますよ。 http://redis.io/commands
文字列型
これはさっきやりましたが。
redis 127.0.0.1:6379> set foo bar OK redis 127.0.0.1:6379> set hoge hogehoge OK redis 127.0.0.1:6379> get foo "bar" redis 127.0.0.1:6379> get hoge "hogehoge"
削除
redis 127.0.0.1:6379> GET hoge "hogehoge" redis 127.0.0.1:6379> DEL hoge (integer) 1 redis 127.0.0.1:6379> GET hoge (nil)
参照
入ってるキーを一覧。
redis 127.0.0.1:6379> keys * 1) "foo" 2) "hoge"
こんな感じで正規表現っぽいキーのとり方もできました
redis 127.0.0.1:6379> keys f* 1) "foo"
インクリメント・デクリメント
redis 127.0.0.1:6379> GET count (nil) redis 127.0.0.1:6379> INCR count (integer) 1 redis 127.0.0.1:6379> INCR count (integer) 2 redis 127.0.0.1:6379> INCR count (integer) 3 redis 127.0.0.1:6379> DECR count (integer) 2
リスト
リストの作成も出来ます。
redis 127.0.0.1:6379> LPUSH mylist "world" (integer) 1 redis 127.0.0.1:6379> LPUSH mylist "hello" (integer) 2 redis 127.0.0.1:6379> RPUSH mylist "!!" (integer) 3 redis 127.0.0.1:6379> LRANGE mylist 0 -1 1) "hello" 2) "world" 3) "!!"
セット型
文字列型の順不同の集合だそうで値の重複はできないという性質を持っているようです。
redis 127.0.0.1:6379> SADD myset "Hello" (integer) 1 redis 127.0.0.1:6379> SADD myset "World" (integer) 1 redis 127.0.0.1:6379> SMEMBERS myset 1) "World" 2) "Hello" redis 127.0.0.1:6379> SADD myset "World" (integer) 0 redis 127.0.0.1:6379> SMEMBERS myset 1) "World" 2) "Hello"
こんな使い方もできるみたいです。 セット型のdiffをとる。 逆にするとenptyになっちゃうので渡すセット型の順番は重要です。 第一引数のセットが第二引数のセットと重複した場合消えて、残った文字列型が出力されます。
redis 127.0.0.1:6379> SMEMBERS myset 1) "World" 2) "Hello" redis 127.0.0.1:6379> SMEMBERS myset2 1) "!!" 2) "World" 3) "Hello" redis 127.0.0.1:6379> SDIFF myset2 myset 1) "!!" redis 127.0.0.1:6379> SDIFF myset myset2 (empty list or set)
ハッシュ
redis 127.0.0.1:6379> HSET myhash field1 "Hello" (integer) 1 redis 127.0.0.1:6379> HSET myhash field2 "World" (integer) 1 redis 127.0.0.1:6379> HGET myhash field2 "World" redis 127.0.0.1:6379> HGETALL myhash 1) "field1" 2) "Hello" 3) "field2" 4) "World" redis 127.0.0.1:6379> HKEYS myhash 1) "field1" 2) "field2" redis 127.0.0.1:6379> HVALS myhash 1) "Hello" 2) "World"
入ってるキーのタイプを取得
redis 127.0.0.1:6379> KEYS * 1) "myhash" 2) "count" 3) "myset" 4) "myset2" 5) "foo" 6) "mylist" redis 127.0.0.1:6379> TYPE myhash hash redis 127.0.0.1:6379> TYPE myset set redis 127.0.0.1:6379> TYPE mylist list redis 127.0.0.1:6379> TYPE foo string
タイムアウト
設定時間後に削除されるキー 以下の記述で5秒後消えるキーとして設定できる。
redis 127.0.0.1:6379> SET hoge hogehoge OK redis 127.0.0.1:6379> EXPIRE hoge 5 (integer) 1 redis 127.0.0.1:6379> GET hoge "hogehoge" (5秒後) redis 127.0.0.1:6379> GET hoge (nil)
DB切り替え
デフォルトでDBが0~15という名前で用意されていて切り替えて使用できる。 接続したときは必ず0を使うようになっているようです。 開発用データは0 本番は1 とかで使える!のかな?
redis 127.0.0.1:6379> SET hoge hogehoge OK redis 127.0.0.1:6379> GET hoge "hogehoge" redis 127.0.0.1:6379> SELECT 1 OK redis 127.0.0.1:6379[1]> GET hoge (nil) redis 127.0.0.1:6379[1]> SELECT 0 OK redis 127.0.0.1:6379> GET hoge "hogehoge"
永続化のテスト
redisの目玉?機能にデータの永続化があります。 これは定期的にデータをファイルに書き出すことで実現しているようです。
redis.confの以下の記述がその設定内容だと思います。
save 900 1 save 300 10 save 60 10000
15分間の間に1回更新があったらファイル書き出し 5分間の間に10回更新があったらファイル書き出し 1分間の間に10000回更新があったらファイル書き出し
って意味になるのかと。 しばらくredis-serverを起動してたら標準出力にこんなログがでました。
[4390] 23 Jan 04:00:49.004 * DB saved on disk [4390] 23 Jan 04:00:49.004 * RDB: 0 MB of memory used by copy-on-write [4378] 23 Jan 04:00:49.015 * Background saving terminated with success
このタイミングでredis.confで指定した場所に指定したファイル名でダンプファイルを作成してくれてました。 この記述を見てから安心してサーバーを停止。 その後起動するとちゃんとデータは保存されてました。 (saveされてない常態で落とすと当然データは消えます)
このとき起動時には「読み込みました」的な以下のログがでてました。
[4415] 23 Jan 04:31:32.445 * DB loaded from disk: 0.000 seconds
感想
機能としては「レプリケーション」や「アトミック実行」、「仮想メモリ」など まだまだためしていないことがたくさんありますが、基本的な部分はさわれたかな、と思います。 なんだかとても見通しがよく感じて楽しく遊べました。
PHPやnode.js、ruby、perlなどなど、いろんなクライアントから使用でき、 そのサンプルもよくみかけるので、ますます触りがいがありそうです。
redis client http://redis.io/clients