オンメモリー・キー・バリュー・ストア型DBのREDISを使ってみた
私としては珍しく使いこなしネタ(?)です。
あるシステムの開発で、非常に多数のデータを扱う必要があり、当初は階層型ディレクトリにファイルを配置して管理していたのですが、あまりの高負荷要件のため、ファイルの存在の有無を確認するだけでもカーネルのiノードキャッシュがどんどん肥大化し、システムの性能に致命的な影響を与えてしまうため(普通の使い方ならこんなことはありませんので、安心してファイルを使って大丈夫です)、他に何か良い方法はないかと考えていました。
オンメモリーでハッシュテーブルでも使えば良いのですが、プロセスの再起動でデータが飛んでしまうのは困るので、ファイルに定期的に同期させるのは面倒だとかいろいろ考えていたところ、「REDISが使えるんじゃないの?」とアドバイスをいただき、使ってみました。
REDISは、ここ:http://redis.shibu.jp/index.htmlに日本語のドキュメントがありますので、詳しくは読んでみてください。BSDライセンスみたいです。
REDISはオンメモリー型でありながら、ディスクにも定期的にダンプさせることで永続性を持たせることができ(さらに追記型という選択もできます)、キー・バリュー・ストア型のデータベースです。キー・バリュー・ストアというのは要するに、「名前=値」という感じのデータを格納できるもの、という感じです。オンメモリー型ですから、高速なのはもちろんです。
他にも、バリューとして文字列型以外に、リスト型・セット型・ソート済みセット型・ハッシュ型も使え、さらに、マスター・スレーブの同期もできるようです。
とりえあず、私の目的としては、ファイルの代わりにデータを格納したいということなので、セット型を使ってみました。さらにファイルではflock()やロックファイルを使っていましたが、これもREDISで実現しました。
中途半端に使い方を説明しても仕方ないので、詳しくは上記リンク先を見ていただくとして、使ってみた感想を書いてみましょう。
データベース関連だとあれこれ機能がありすぎて、インストールや設定などで嫌になる気がしますが、REDISはとても簡単でした。ソースからビルドして実行するまで何も悩みません。
そのままredis-cliというクライアントプログラムで簡単に使ってみることもできますし、telnetでつないで、プロトコルがテキストベースなので、そのままやりとりしてみることもできます。
私はC言語のプログラムから使いたかったので、TCP/IP接続して、直接プロトコル通りに通信して使いましたが、特に面倒な点はない感じです。
対象のシステムがもともと多数のTCP/IPコネクションを使うため、これ以上TCP/IP通信は使いたくなかったのですが、REDISサーバとやりとりする方法はTCP/IPしかありませんのでしかたありません。その代わり、リモートホストからでもデータが確認できます。
性能は確かに速い感じです。適当にファイルにもダンプしてくれ、再起動してもちゃんとデータは継続して使えます。
セット型が便利そうで中途半端なのは目的がやや合っていないからかもしれませんが、セット型は、一つのキーに対して複数のmemberを持たせることができます。私としてはmember自体をkey=valueにしたいのですが、memberはそれ自体で一つの値です。本当は、data1=1となっているmemberをdata1=2に簡単に上書きしたいのですが、それはできません。"data1=1"全体が値なので、data1=1を消してから書くか、data1=1をdata1=2に書き換える、という感じにしなければならず、元の値を覚えておかないと消したり置き換えたりすることができません。まあ、もともとファイルの時にも面倒なので丸ごと上書きしてましたので、キーごと削除して新たに書くようにしてお茶を濁しました。。
排他には便利に使えます。SETNXという格納コマンドを使うと、キーが存在しない場合のみ格納でき、応答で格納できたかどうかがわかります。ロックに使えると説明されています。
それと、キーに有効期限を持たせられるのも便利です。勝手に有効期限が来ると消えてくれます。
ある程度機能を限定すれば似たようなものはもちろん比較的簡単に自作できますが、性能を追求したり、安定性をきちんと確認するのはそれなりに手間がかかります。うまくマッチする用途であればとても便利に使えると感じました!