はじめに
今回は、永続性key-valueストアの代表としてTokyoTyrantを取り上げます。TokyoTyrantというのはTokyoCabinetのネットワークインタフェースです。名前が似ていてわかりにくいですが、TokyoCabinetがkey-valueストアの機能(データの保存や読み出し)を持ったデータストレージであり、TokyoTyrantはTokyoCabinetをネットワーク越しに操作できるようにしたラッパーです。キャビネット(内閣)を傀儡にするタイラント(僭主)ということで、このような名前が付けられたそうです。
今回も利用したコードやプログラムはgithubに置いてあるので適宜参照してください。
TokyoTyrantの特徴
key-valueストアという点ではmemcachedと同じですが、TokyoTyrantサーバを停止してもデータが消えない(データの永続性がある)ことが最大の特徴です。 expiresを設定することはできませんが、それ以外はほぼmemcachedと同じように扱えます。
また、TCHDB(ハッシュデータベース、※1)、TCTDB(テーブルデータベース、※2)などといった様々なデータ型があり、それらを用途に応じて使い分けることができることも特徴です[3]。
表1 それぞれのデータ型に対応するクラス名とファイル名
データ型 | TokyoTyrant | TokyoCabinet | ファイル名 |
ハッシュデータベース | RDB | HDB | *.tch |
テーブルデータベース | RDBTBL | TDB | *.tct |
B+treeデータベース | RDB | BDB | *.tcb |
オンメモリデータベース | RDB | ADB | * |
どんなところに使える?
もっとも簡単な利用方法は、前回紹介したmemcachedの代替として利用するというものです。memcached互換プロトコルが実装されているため、memcachedを利用している場合ポート番号を変えるだけでTokyoTyrantに差し替えることが可能です。これだけで簡単にデータの永続性が得られます。
また、テーブルデータベースを利用すれば一つのkeyに対して複数のvalueを持たせることが可能であり、keyだけでなく任意のvalueを条件としてデータの検索を行うこともできます。JOINやGROUP BYといった処理は行えませんが、それ以外のほとんどの検索条件を扱えます。レスポンスはRDBMSに比べて高速なので、アクセス数が多いテーブルをTokyoTyrantのテーブルデータベースに載せ換える、といった利用方法も効果的かもしれません。
- 具体的な利用シーン
- memcachedの代替としての利用
- 複雑な検索条件を用いつつも高速なレスポンスが要求される
TokyoCabinetを試す
さて、まずはTokyoCabinetを試してみます。TokyoCabinetはvalueとして文字列しか扱えません。配列やハッシュなどをvalueとして保存したい場合には、明示的にシリアライズ(取り出すときにはデシリアライズ)してあげる必要があります。
TokyoTyrantを試す
TokyoCabinetでデータの保存や読み出しが出来ることが確認できました。しかし、TokyoCabinetではネットワーク越しのアクセス(例えば別サーバにアクセスするなど)ができません。これを実現するものがTokyoTyrantです。
では、TokyoTyrantを利用してみましょう。前回と同じように、localhostに3台のTokyoTyrantサーバを別々のポートで起動してみます。
memcached互換プロトコル
もちろんTokyoTyrant独自プロトコルを使って利用することも可能ですが、ハッシュデータベースであればmemcached互換プロトコルが利用できます。前回、memcachedを利用したときのコードの一部を以下のように変えるだけです。
memcached互換プロトコルを利用する場合、Consistent Hashingによって処理を分散させるのも非常に簡単です。実際試してみると、別々のポートで立てたTokyoTyrantサーバに分散してデータの保存/読み出しが行われていることが確認できます。
テーブルデータベース
次に、もう一つの用途として考えられるテーブルデータベースを扱ってみましょう。テーブルデータベースではmemcached互換プロトコルは使えないため、TokyoTyrantの独自プロトコルを利用します。
まず、テーブルデータベース用のTokyoTyrantサーバを立ち上げます。先ほどとは保存先の拡張子が違うことに注意してください。
TokyoTyrantはmemcachedと同じようにクライアント側の実装によって処理を分散させる必要があります。ただし、Consistent Hashingのような仕組みはなく、レプリケーションで処理(主に読み込み部分)を分散させるようです。-mhost, -mportでマスターのホストとポートを指定し、-rtsでレプリケーションタイムスタンプの記録を、-ulogでレプリケーション用のログを出力しています[4]。
テーブルデータベースを利用した具体的なコードは以下のようになります。簡単な実装ですが、set_connectionメソッドでマスター、スレーブを設定し、do_initメソッドで書き込みはマスターに、読み込みはスレーブに処理を振り分けています。
例では、名前が“山田”で始まるデータを誕生日の降順で検索してみました。このようにテーブルデータベースではRDBMSのように検索条件を利用することができます。ただ、実際に使うとなると独自の定数がたくさん出てくるため、扱いにくいなぁというのが正直なところです(強調部分)。紙面の都合上、詳しくは扱いませんが、MiyazakiResistanceやActiveTokyoCabinetを使うとテーブルデータベースをActiveRecordのように扱えます。
まとめ
今回はTokyoTyrantについて見てみました。memcachedは何といっても手軽なのですが、どうしてもデータ消失のリスクがあります。TokyoTyrantをmemcached互換プロトコルで利用すれば手軽にデータの永続性が保証できるため、非常に便利ではないでしょうか。また、テーブルデータベースは導入の敷居は高いですが、RDBMSのように扱えて高速に処理できるというのは魅力的です。