インメモリKVSのRedisについて

* wiki(Tech Note)のページ追加
このエントリーの内容を整理してwikiにもRedis関連のページを追加しました。
Redis – Tech Note


Redis is an open source, advanced key-value store. It is often referred to as a data structure server since keys can contain strings, hashes, lists, sets and sorted sets.

インメモリKVSのRedisを少し触ってみました。

さくらVPS(CentOS 5.6)にインストールしようと思ったのですが、yumのレポジトリだと今は古いバージョンしか入れられないようなのでソースからビルドしました。手順は公式の通りに。(参照: Download – Redis)
また、/etc/init.d で動作させるスクリプトは同梱されていなかったので以下からお借りしました。
A CentOS initscript for Redis — Gist

Redisの利用実績

Who’s using Redis?
公式のアナウンスによると、githubやdigg、stackoverflowなど多くの有名サイトで利用実績があるようなので、導入検討時の良い説得材料になりそうです^^

Redis data types (型について)

Redisは基本の文字列型の他にリストやセット、ハッシュなどの様々な型がありますが、それぞれの型に対するコマンドがatomicに動作するという特徴を持ちます (参照: Command reference – Redis)。つまり、ユーザー側でCAS操作をぺたぺた書いてその戻り値をいちいち気にする必要はありません。

String (文字列)

まずは基本の文字列型から試してみます。整数文字列をセットしてインクリメント/デクリメント操作をすると内部で整数値(符号付き64bit値)として扱われます。また、バイナリセーフなのでどんな種類のデータでも保存できます。JPEGイメージとかでもOK。

v2.2以降ではLRU (Least Recently Used)をサポートしているのでmemcachedのような使い方もできます。

List (リスト)

次はリスト型。公式のチュートリアルでTwitterクローンを制作してますが、そこで使われているようにユースケースとしては時系列データを扱うのに良さそうです。

複数のプロセスから1つのリストにどんどん値をpushしていっても安心で、rpush/lpushなどのList型のコマンドはatomicな操作になっています。

* RPOPLPUSH(srckey, dstkey)
個人的に面白いなと思ったList型のコマンドを別途紹介。このコマンドは srckey に対応するリストの末尾要素を削除して、その要素を dstkey に対応するリストの先頭にpushします。ひとつのリストをバックアップとして使ってメッセージキューを安全に実装するときなどに使えます。また、srckey と dstkey が同じ場合はローテーションすることになります。

Set/Sorted Set (集合/ソート済み集合)

Setは順不同の集合型。和集合や積集合などの各種集合演算が利用可能で、メンバの重複を許可しません。ソーシャル系のサービスだとユーザー(コミュニティ)のつながりを調べたりするのに使えそうです。また、Sorted Setでは任意のスコアで値がソートされるのでいろいろな用途が考えられると思います。

Hash (ハッシュ)

最後はHash型。ハッシュ形式のデータを保存できます。

Hash型では効率的にメモリを使用するために設定ファイルでパラメータを指定できるようになっていましたが、いまいちよくわかりません。zipmap ってなんだろう。。

以上で、それぞれのデータタイプ毎に提供されたコマンドの使い方を簡単におさらいしました。Redisには他にもたくさんのコマンドが提供されているのでいろいろ調べておきたいと思います。

Persistence (永続性)

Redisはインメモリで動作しますが、非同期でディスクにも書き出すため永続性を備えています。ディスクに書き出すタイミングは設定ファイル(redis.conf)で指定できます。デフォルトでは以下のように設定されていて、この辺りは運用しながら調整する必要がありそうです。

このようにRedisの永続化機能はスナップショットを書き出す方式なので、もしRedisサーバが落ちたときは最新のデータが失われる可能性があります。これを防ぐために append only file と呼ばれるファイルに更新コマンドを書き出すこともできます。

append only file

デフォルトでは無効になっているので利用するために設定ファイルを編集します。

これだけ。デフォルトのファイル名は appendonly.aof になっています。ここで、set mykey foo を実行したときのappend only fileの内容は以下のようになりました。このようにプロトコルがシンプルなので簡単に読めます($の後ろの数字はバイト数)。

同期には fsync() を使っているようですが、どのタイミングで同期するのかも指定できます。

Virtual memory (仮想メモリ)

RedisではLinuxカーネルを参考にして独自に仮想メモリ機構を取り入れているみたいです。つまりRAMからあふれたデータをswap outしてディスクに書き出してくれます。実装初期のバージョンでは不安定でよく壊れていたようですが、現在は良くなっていると思われます(※ 厳密な検証はしてません)。この仮想メモリに関連するパラメータもいくつかあるので、内部動作も含めて調べておきたいと思います。ただ、弊社のサービスで使うDBサーバは(お金の力を使って)数十GBのメモリを載せてたりするので、仮想メモリはあんまり使わないかもしれません。

Replication (レプリケーション)

RedisにはTokyo Tyrantなどと同様にマスター/スレーブのレプリケーションをサポートしています。利用するのは簡単で、スレーブとして利用したいRedisの設定ファイルに項目を追加するだけです。

レプリケーションが動作しているか確認してみます。

大丈夫そうです。ログでは以下のように書き出されていました。

Hashing (データ分散)

イマドキのNoSQLデータベースクライアントにおいては珍しいことではないのですが、Redisクライアントでも Consistent Hashing によって複数サーバにデータを振り分けています(対応していないクライアントライブラリもある)。近々Rubyコミュニティの小さな集まりに参加する予定なので、ここではリハビリも兼ねてRubyクライアントを使って確認してみます。公式のレコメンドに従って redis-rb を使いました (MRI 1.9.2p0 (2010-08-18 revision 29036))。

* 出力結果

キーが偏ってますね。HashRingクラスの実装を見てみると仮想ノードのデフォルト数は160になっていました。これを倍の320に設定して試してみます。

たいして変わらなかった。。でもとりあえずキーが分散することは確認できました。

Pipelining (パイプライニング)

Redisではパイプライニングにも対応しているらしいので確認してみました。複数のコマンドをサーバーの応答を待たずに一括で送信します。

さくらVPS(いちばん安いやつ)上のRedis Server v2.2.9で公式のサンプルコードを使ってベンチマークを取ってみます。パイプライニングの有無で処理時間を計測しています (MRI 1.9.2p0 (2010-08-18 revision 29036))。

* 結果

公式のベンチマーク結果と似たような差が出ました。パイプラインを使用したほうが5倍ほど速かったです。

Pub/Sub

RedisではPublish-Subscribeモデルのメッセージング機能をサポートしています。
* subscriber.rb

* 動作確認

使うだけなら簡単ですね。

——————–
以上、Redisについてちょっと調べてみました。クライアントライブラリは多くの言語から提供されていますが、作りの質が言語によってかなり差があるように見えるので検証時は注意した方が良さそうです。また、データセンターをまたいで利用したときの検証も行っていきたいです。リアルタイム性が必要なサービスで十分使えるなら、例えば映像配信インフラにおいて視聴ステータスの管理やプレイヤーからのハートビートをさばく部分などに使えるでしょうか。ちょっと試してみようと思います。

これ以上さくらVPSでがんばるのは大変なので会社のデータセンター使わせてもらおう。今夏の節電対策で西日本にがばっと移設したところもあるので好都合かもしれない。

あわせて読む:

4 Thoughts

  1. Thanks for finally writing about >インメモリKVSのRedisについて
    ? Rest Term <Loved it!

  2. One or two of regarding me: co-workers call myself NICK as well as in online
    you will find me underneath redhat01 login name.

    I do certainly not name me personally a hacker, however I love to review program code and discover vulnerabilites on game titles and different applications.

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です