«前の日記(2010-03-14) 最新 次の日記(2010-03-16)» 編集

ぱぱネット(仮)


2010-03-15 Tokyo Cabinetで遊ぶ [長年日記]

_ [開発][Linux] 噂のTokyo Cabinet

mixiのアーキテクトである 平林幹雄さんの一連のソフト群は mikio ware と呼ばれ、筋(どの筋?)では有名です。 いろいろなものを作られているのですが、最近、富に注目を浴びているのは、 Tokyo Cabinet / Tokyo Tyrant と呼ばれる軽量データベース。

Tokyo Cabinet

個人的にはSQLite3という、 組み込みリレーショナルデータベースを良く使っていたのだが、 いくつか問題にぶち当たっていて、これを解決する手段を探していたというわけ。

  • 原則DBロックで2,3プロセスから書き込むと良く更新失敗する
  • RDBMSなので割と真面目にテーブル設計しないといけない
  • 登録が遅い!トランザクション使えば速いがそのロック期間は(1)の問題が生じる
  • サーバ実装のデファクトがない
  • レプリケーションがない
  • パフォーマンスチューニングの余地が少ない

特に1番めの欠点を直そうとSQLite3を改造しようとして挫折した経験あり(笑) これができないとウチのような小規模Webページでも大変困ったことになるのです。

一方Tokyo Cabinetは、RDBMSではないのでテーブル同士のJOINなどはできないものの、

  • mixiの更新時刻処理に使われていて毎秒数万アクセスをさばいている(らしい)
  • ハッシュ、B+木、固定長、テーブルDBを選択でき、テーブルDBは非常に理解しやすい
  • Tokyo Tyrantというサーバ実装がある
  • レプリケーションがある
  • ハッシュ表やリーフ(ノード)サイズが細かく制御でき、かつzlib/bzip2による圧縮もサポート

という素晴らしい特徴があります。なかなかいい感じではないですか。

_ [開発][Linux] テーブルデータベースの基本

TCの真骨頂は、カリカリにチューニングしたハッシュデータベース(PerlやRubyの連想配列のようなKey-Value-Storage)にあるらしいのですが、私はテーブルデータベースにしか興味がないのでこれを使ってみます。

テーブルデータベースは、名前の通り「表」です。

Table Database

が、SQLのテーブルとはだいぶ異なります。なんとカラムは自由に増やせます。特定の行だけに カラム'type'があって、他の行にはない、なんて事も可能です。SQLだとALTERで増やして、 デフォルト値で埋めるなんて作業をしなければなりませんが....

どうもTTは基本的にハッシュデータベースであり、 primary keyだけは特別 扱い しているものの、残りのカラムはすべてセルデータに結合して記憶されているようですね。 セルに「7」という数値だけではなく「type:7」という形で記憶されるようです。 事前にテーブル設計をしなくても良いのはメリットである半面、「typ o 」みたいな 間違いをしてもTT側でチェックしてくれる訳ではないのでハマりそうですな(笑)

あと、これは面喰らったのですが、サーバ版のTokyoTyrantでは基本的に 1つの初期化スクリプト=1データベース=1テーブルのようです。1データベースに 複数のテーブルを格納することはできないようです。つまりTCPポートが別々に分かれた 複数のサーバを起動しておくという使い方になるようです(少なくとも標準では)。

起動にはttserverというサンプルファイルを/etc/init.dにpostepgみたいな テーブル名と同じファイル名にしてコピーして所定の変数を書き換えます。 以下の例はポート1993にpostepg.tctという名前のテーブルを作成する例です。

# configuration variables
prog="ttservctl"
cmd="ttserver"
basedir="/mnt/windex/postepg"
port="1993"
pidfile="$basedir/pid"
#logfile="$basedir/log"
#ulogdir="$basedir/ulog"
ulimsiz="256m"
#sid=2
#mhost=""
#mport="1993"
#rtsfile="$basedir/rts"
dbname="$basedir/postepg.tct#opts=l#apow=8#dfunit=2"
maxcon="1024"

chmod a+x postepgして/etc/init.d/postepgで起動します。

_ [開発][Linux] TokyoTyrantへのアクセス

Perl,Rubyなどのバインディングが存在しますが、私はPerlを使いました。

use TokyoTyrant;
my $pe = TokyoTyrant::RDBTBL->new();
die "ERROR: unable to connect" if (!$pe->open('localhost', 1993));
if ($pe->rnum == 0) {
    $pe->setindex($pec->{'eventid'}, $pe->ITDECIMAL);
    $pe->setindex($pec->{'nibble'}, $pe->ITTOKEN);
    $pe->setindex($pec->{'provider'}, $pe->ITLEXICAL);
    $pe->setindex($pec->{'title'}, $pe->ITQGRAM);
}
$pe->close();

ちょっとハマったのは データベースのタイプを合わせること ですか。hogehoge .tct をデプロイしている サーバにアクセスするためには、必ずTokyoTyrant::RDBTBLを使わねばなりません。 まあ少し考えればわかることですが...

登録数が0のときにインデックスを張っています。数値はITDECIMAL、文字列辞書式順はITLEXICAL、 「ニュース,報道」みたいなカンマや空白で区切られた複数の意味を持つ文字列はITTOKEN、 自由な単語で検索したい文字列にはITQGRAMを付与します。これで検索などが高速化されます。

データの登録はprimary keyを取得して、それに対してPerlのハッシュリファレンスをputします。

 my $cols = {
     'eventid'=>23435,
     'nibble'=>'2f 情報・ワイドショー その他',
     'provider'=>'NHK総合',
     'title'=>'おはよう日本'
 };
 my $rkey = $pe->genuid();
 $pe->put($rkey, $cols);

検索結果はprimary keyのリストで返ってくるので、それを使ってgetします。 Q-GRAMのインデックスを張っておくと、SQLite3のlikeなんて目じゃない柔軟な検索が可能になります。 ちなみにQCFTSANDは空白で区切られた単語単位のAND検索。Googleとまではいかないけど、 こんなお手軽に柔軟な検索ができるようになるのはTTのメリットでしょう。

my $qry = TokyoTyrant::RDBQRY->new($pe);
$qry->addcond('title', $qry->QCFTSAND, 'よう 本');
my @rlist = $qry->search();
foreach my $rkey (@rlist) {
    my $rcols = $pe->get($rkey);
    print $rcols->{'title'} . "\n";
}

基本はこれだけ。

_ [開発][Linux] ベンチマーク

ベンチマーク用にtcttestというコマンドが用意されているので、どのくらい速いか調べてみた。 インデックスは張りまくりの条件です。

tcttest write -tl -ip -is -in -it -if -ix ./test/test.tct
ベンチマーク

Q-GRAM転置インデックス生成を含む6種類のインデックスを張りながらでも、 250万レコード平均で4800レコード/秒というすさまじい速度です。 100万レコードから250万まで測定しましたが、微妙に時間が延びるもののほぼ線形。 ディスクの延びもほぼ線形でした。

最近はスケールアウトが流行りですが、これだけ速ければTC一つで事足りる事例も 多いのではないでしょうか。特に個人では.....

次は検索時間を調べてみたいと思います。


2001|04|
2006|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|03|04|05|06|07|08|09|10|11|12|
2014|01|03|04|05|10|

[BANNER]
このサーバーをもう12年も維持しているかと思うとめまいがしますよ。
ツッコミ機能は、ハンドル名が完全日本語じゃないと登録できません。
また、本文にURLが含まれていても登録できません。
いずれもSPAM対策です。
[Panda Papanda]
2010年
3月
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31

[Papanda]  [Kuma]  [Tomorin]  [Iron]  [Eiza]  [Dokkin]  [Honya]  [Zyou]  [Tsuyo]  [Bike]  [KoeBBS]  [Chukei]  [portal]  [tvmatome]  [KaoPaku] 

訪問者数:(11777+2560143)