Tokyo TyrantをDBと比較してみる
あらかじめ書いておくと、最終的にごく当たり前の結論しか出てきませんΣ(・ω・ノ)ノ
ただ、その「当たり前の結論」を、自分で身をもって体感しておくのは、
意味があるとは思います
例によって前置きから入るわけですが、
昨年末あたりから新しいシステム開発の話が立ち上がりまして、
先月あたりからアーキテクチャの設計をしておりました
ちょいと特殊なWebシステムなのもあり、
分散システム的な凝ったのを考えていたのですが、
いくつかピースが欠けていたのです
そんなとき、本屋で見たのがこれです
Software Design (ソフトウェア デザイン) 2010年 02月号 [雑誌]
- 出版社/メーカー: 技術評論社
- 発売日: 2010/01/18
- メディア: 雑誌
- 購入: 4人 クリック: 75回
- この商品を含むブログ (9件) を見る
この本で「Key-Value Store (KVS)」の特集をやっておりまして、
まさに「これだ!」と
欲しいのは「分散KVS」なのですが、まずはそれらの基盤となっている、
「Tokyo Cabinet」*1が、DBと比較してどんなもんなのか試してみました(`・ω・´)
なお、「Tokyo Cabinet」がファイルコンテナで、
「Tokyo Tyrant」がそのネットワークインターフェースです
また、ほとんどの国産KVS*2が「Tokyo Cabinet」を利用しています
環境
ハードウェア
ソフトウェア
- MySQL5.0.67
- Ruby1.8.7-p249
- Tokyo Cabinet(TC) 1.4.42-ruby1.29
- Tokyo Tyrant(TT) 1.1.40-ruby1.13
テストデータ
- アプリレベルでパーティショニングされた中の1テーブル
- 実際にこの単位で使っている
- レコード件数:約115万
- カラム数は7
- 格納データは文字列と数値のみで、マルチバイトなし
書き込みテスト
- DBから全件読み込み
- (コードレベルでは)fetchで1件ずつ取得
- 取得データを{カラム => 値}でハッシュ化した後、テストごとに処理
- TTのkey書式は「固定文字列_数値9桁」
WTest1(DB)
- 取得したデータをDBの別スキーマにそのまま書き込み
- コミットは最後に一回
WTest1'(DB)
- WTest1と同じだが、コミットをレコード毎に行う
- 20分待っても終わらなかったため、停止(´・ω・`)
WTest2(TT-RDB)
- TTをハッシュデータベースで起動
- 取得データを無視し、固定長の数値文字列をset
- 取得自体は行うため、読み込みのコストは同じ
WTest4(TT-TBL)
- TTをテーブルデータベースで起動
- 取得データのHashについて、Valueを文字列変換してから格納
読み込みテスト
- TTはあらかじめ分かっているキーで順に全データを取得
- DBは単純に全件取得し、WTestと同じロジックでHash化
- 10000件ごとに取得結果を書き出し、中身が正常であることを確認
- RTest[A]はWTest[A]の結果の全件取得テスト
- RTest3のみ、取得後にYAML.loadでHashに復元
検索テスト
- ある1カラムを指定して検索
- DBはIndexあり
- TTはIndexあり/なしで測定
- そのカラムは二種類の値[1, 2]のみ存在
- 一致検索ではなく、範囲検索(>=2)
- 検索結果は読み込みテストと同じ処理
- TTの場合、検索結果はkeyで返されるため、そのkeyで値を取得
検索テスト | 内容 |
---|---|
STest1 | WTest1のDBから検索 |
STest2 | WTest4の内容を検索/Indexなし |
STest3 | WTest4の内容を検索/Indexあり |
結果
- 測定は数回行い、最速の結果を採用
- ただし、全てのテストで回ごとのぶれは最大でも2秒
- 時間は分:秒で表記
テスト | 対象 | 時間 | 備考 |
---|---|---|---|
WTest1 | DB | 5:18 | |
WTest2 | TT-RDB | 3:47 | 単純KV |
WTest3 | TT-RDB | 9:52 | YAML |
WTest4 | TT-TBL | 5:49 | |
RTest1 | DB | 2:13 | |
RTest2 | TT-RDB | 1:01 | 単純KV |
RTest3 | TT-RDB | 1:49 | YAML |
RTest4 | TT-TBL | 4:11 | |
STest1 | DB | 0:39 | |
STest2 | TT-TBL | 1:28 | Index× |
STest3 | TT-TBL | 1:25 | Index○ |
考察
- 単純な比較だとDBの方が速い
- もちろん、チューニングの有無もある
- DBの代替として使うには厳しい
- DBの負荷を下げるキャッシュとしてならいけそう
- TT-TBLは便利そうだけど、コストがでかい
- Indexが効きづらいのは、データのせいかもしれない
- もっと長い文字列ならあるいは・・・
- 単純なKey-Valueの場合、DBよりもTTが上
- 特に、細かなトランザクションが発生する場合、TTの圧勝
つまり、TTがDBに対してアドバンテージを持つのは、
小さなデータを大量に更新する場合であり、
まさにSNSのログイン情報とか、ECサイトの閲覧履歴のような処理です
既存のDBが十分に性能を発揮できる範囲では、
やはりKVSよりDBの方が高速であり、
この意味でKVSを導入する必要性は薄いと思われます
しかし、ご存じのように、DBはスケールコストが半端ではありません
この点では「分散KVS」に圧倒的なアドバンテージがあります
(性能/容量がリニアにスケールする)
・・・と、ここまで書いておきながら、
実はTC/TT自体は「分散KVS」ではありませんΣ(・ω・ノ)ノ
TTはMySQLと同じレプリケーション機構を持つものの、
完全なノードクラスタ構成にはなってません
なので、自立的に処理を分散することはできないのです
だからこそ、ROMAのような分散KVSとしてのフロントエンドが必要なわけですが、
データ格納にTCを使う(ことが多いらしい)ため、
本質的には今回のような性質を引き継ぐと思われます
結論
- 単体で使うならTCよりはDBの方がいい
- 分散KVSを導入する状況は以下の場合
- 大量のサーバで分散処理したい
- 大量のデータを分散して格納する必要がある
- 小さなデータによるトランザクションが大量に発生する
ほら、当たり前の結論だ(´・ω・`)
*1:あの「Hyper Estraier」を作った方がmixiで開発
*2:kumofs / ROMA / Flare 詳細は雑誌参照