多機能、高速かつデータの永続化が可能なキーバリューストアRedisをさわってみた。

こんにちは。今回は昨今流行のキー・バリューストアRedisを触ってみたのでその記録です。

RedisはC言語で実装されたキーバリューストアの一種ですが、単純にキーバリューストアと表現するのに抵抗があるほど多機能です。しかもそれらの機能がいかにも痒い所に手が届くというか、あると助かる機能を豊富に揃えています。

概要
簡単に表現するとRedisは全てのデータをメモリ上に読み込んでおき、一定時間おきにディスクにデータを保存するタイプのキーバリューストアのようです。どのようなタイミングでディスクに書き込むかは設定によってかなり柔軟に行えるようです。

また、データをメモリ上に全て読み込むのがデフォルトの動作ですが、メモリが足りなくなると値はディスクから読み、キーはメモリ上に置いておくなど状況に応じた動作をしてくれるようです。従って大量のデータや増加し続けるデータの保存領域としても使用出来るかと思います(参照:NoSQLデータベースガイド)。

なお、情報源は以下にあります。

本家
http://redis.io/

本家コマンドリファレンス(英語)
http://redis.io/commands

ドキュメント日本語訳
http://redis.shibu.jp/index.html

日本語コマンドリファレンス
http://redis.shibu.jp/commandreference/index.html

ツイッタークローンの実装例
http://redis.shibu.jp/tutorial/index.html


インストール
上記の本家サイトから最新の安定板をダウンロードします。

ダウンロードしたディレクトリに移動して解凍

$ tar xvzf redis-2.2.14.tar.gz

ビルド

$ make

ビルドするととりあえず起動できますが、ビルドの終わりに「テストしてみるのはいい考えだね!:-)」って言ってるので、自分の環境で問題なく動くかテストしてみますw

$ make test

テストの様子

上の通り、0failedでテストが完了しました。

起動
起動はsrcディレクトリに移動して./redis-serverコマンドを叩きます。

$ cd src
$ ./redis-server

これで起動出来ました。メッセージのとおり、デフォルトのポートは6379番のようです。


クライアントから触ってみる
Redisにはとりあえず動作を試す為のクライアントプログラムが付属しています。srcディレクトリ内にありますので、そこに移動して試してみます

$ cd src

キーと文字列の値のセットの保存と取得
値をセット

$ ./redis-cli set hoge tara
OK

値を取得

$ ./redis-cli get hoge
"tara"

もうひとつ値をセット

$ ./redis-cli set foo bar
OK

キーの存在を取得

$ ./redis-cli exists foo
(integer) 1

複数のキーを与えて複数の値を一度に取得する

$ ./redis-cli mget hoge foo
1) "tara"
2) "bar"

キーを指定して値を削除

$ ./redis-cli del hoge
(integer) 1

数値のインクリメントとデクリメント
キー"my_age"で数値1をセット

$ ./redis-cli set my_age 1
OK

キーを指定して値を取得

$ ./redis-cli get my_age
"1"

値を+1する

$ ./redis-cli incr my_age
(integer) 2

再度値を取得する

$ ./redis-cli get my_age
"2"

値を-1する

$ ./redis-cli decr my_age
(integer) 1

再度値を取得する

$ ./redis-cli get my_age
"1"

リスト操作
キーの末尾に値を追加

$ ./redis-cli rpush my_list "helo 1"
(integer) 1

もうひとつ値を追加

$ ./redis-cli rpush my_list "helo 2"
(integer) 2

さらに同様の手順で3,4,5まで追加

$ ./redis-cli rpush my_list "helo 3"
(integer) 3
$ ./redis-cli rpush my_list "helo 4"
(integer) 4
$ ./redis-cli rpush my_list "helo 5"
(integer) 5

現在のリストの要素の0番目から1番目までを取得

$ ./redis-cli lrange my_list 0 1
1) "helo 1"
2) "helo 2"

現在のリストの要素の3番目から4番目までを取得

$ ./redis-cli lrange my_list 3 4
1) "helo 4"
2) "helo 5"

現在のリストの要素の3番目から100番目までを取得

$ ./redis-cli lrange my_list 3 100
1) "helo 4"
2) "helo 5"

現在のリストの要素の0番目から末尾(-1番目)までを取得

$ ./redis-cli lrange my_list 0 -1
1) "helo 1"
2) "helo 2"
3) "helo 3"
4) "helo 4"
5) "helo 5"

現在のリストの要素の末尾から3番目(-3番目)から末尾(-1番目)までを取得

$ ./redis-cli lrange my_list -3 -1
1) "helo 3"
2) "helo 4"
3) "helo 5"

感想
全体的に使う側が何が欲しいかを良く考えてあるなあと感心しました。ここであつかったのは機能のうちのほんの一部で、他にもセットや順序付きセット、ハッシュなども保存出来ます。
特にリストはかなり使い勝手が良いのではないでしょうか。そしてリストへの操作や数値のインクリ、デクリメントがアトミックに行えるのもポイントが高いです。

基本的に英語の情報が最新となりますが、日本語ドキュメントもきちんと和訳されたものがあります(少し古いバージョンのもののようですが)。

PythonとRedisによるツイッタークローンの実装例もありますが、SNSのように多数のアクセスが行われるサービスにはうってつけと思われます。

次のエントリではErlangおよびRubyから操作する場合について記したいと思います。