«前の日記(2010-05-31) 最新 次の日記(2010-06-04)» 編集

ぱぱネット(仮)


2010-06-03 TokyoTyrantと格闘中 [長年日記]

_ [Linux][開発] TokyoCabinet(Tyrant)のパフォーマンス

仕事が忙しくてずいぶん間が空いてしまったのだが、またTT/TCをいじり始めています。 実は性能が出なくて困っていた。特に 20万件を越えたあたりからライトが激烈に遅く ちょっと使い物にならないレベルに。

で、ちょっとぐぐったらとても良い資料見つけました。 SSDとTokyoTyrantやMySQLの性能検証(by 株式会社ゆめみ)。 こんなノウハウを惜しげもなく公開してくれるなんて....大変ありがたい。

_ [Linux][開発] 読んだ限り

所詮HDDだろうがSSDだろうがディスクI/Oが混むと手のつけようがないので、 「メモリ大量に用意してxmsizデカくしてオンメモリで処理しろ」 というアプローチが 正道らしい。

TC/TT開発者mikioさんがブログ等でTTを「状態をディスクに保持してくれるmemcached」という 立ち位置で説明してるので誤解しやすい(俺だけかもしらんが俺は誤解してた)けど、 やっぱりメモリ最強 ということですか....。

具体的にはttserverを起動するdbname行にxmsiz指定をつける(パラメータは256mとか1gとか)。

cascket.tct#xmsiz=1g#opts=ld#apow=6#dfunit=4

みたいな感じ。ウチでは80万件のデータベースに対してキャッシュ1G指定したら、 だいたいライトが80倍くらいになりました(今までは何だったの....)。 データベース全体は600MBくらいなのでまるっきりメモリに入ってしまう模様。

_ [Linux][開発] さらに速くする方法もしくはmget知らなかったバカを責めて

通常、Perlにおける、TTのRDBTBL(SQLライクなテーブル状データへのアクセス)に対する検索の 贋コードは以下のとおり。概ね「ptokenカラム内をタグ検索して、ptime順にオーダーして、最大100件出力」という意味です。

my $qry = TokyoTyrant::RDBQRY->new($pm);
$qry->addcond('ptoken', $qry->QCSTRAND, $tokens);
$qry->setlimit(100);
$qry->setorder('ptime', $qry->QONUMASC);
my $rv = $qry->search();

ここで$rvに返ってくるのは キーリストのリファレンス である。なので、 以下のようにforeachで回したくなる。get関数は指定キーのデータ本体をとってくるものね。

foreach my $rkey (@$rv) {
  my $rcols = $pm->get($rkey);
  # print Dumper($rcols);
}

しかしこれは遅いのだ。 TT/TCにはmget関数というものが用意されている。 mget関数は あらかじめキーを入れたハッシュのリファレンスを渡す と、 データが存在するものは値セットしてくれ、データがないものはキーごと削除してくれる...らしい。 getだと毎回サーバに対してリクエストを出してしまうけれど、mgetだと1回で済むわけだ。

mgetを使った贋コードは以下のとおり。リストはmap関数でハッシュに直しています。

my %rtable = map { $_=>undef } @$rv;
my $count = $pm->mget(\%rtable);
foreach my $rkey (@$rv) {
  next if (!exists $rtable{$rkey});
  my $rcols = $rtable{$rkey};
  # print Dumper($rcols);
}

結果... MGET:0.006553sec GET:0.030858sec ということで mgetはgetのおよそ4.7倍 という結果でした。 ああ、俺が使い方知らなかっただけなのね。これは便利だし副作用ないしガンガン使っていこう。

_ [Linux][開発] しかし....

それでも私の環境では数万QPSにはまったく届きません。Core i3でもPhenomII X4でも。 特にライトは1000QPS出ているかでていないかで、件のレポートでいう「極端に悪い状況」です。 まあメモリ4GBしかないので、せいぜいttserverに割り当てられるキャッシュメモリは1GBということもあるけど。

なんでだろう...と思っていろいろ試しているのですが、確定的なことは言えません。

でも、ttserverを同じマシンで10コ起動するという場面は、 もしかして想定してない? と は思っています。

通常のSQLデータベースだと、1サーバ<複数データベース<複数テーブルという階層構造で、 通信用のワーカースレッドが複数個立ち上がっても、データベース自体の書き込みは比較的シリアライズされていると 考えられます。

しかしttserverの場合は1サーバ=1データベース=1テーブルという単一構造で、 どうしても実用的なアプリケーションを作成しようとすると、複数個ttserverを起動したくなる訳ですが、 どうも 全員がガムシャラにディスクをアクセスするよう なんですよね....常に全力全開マジモードで。

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.00    0.00    0.05   32.62    0.00   67.33
Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sda              27.00         0.00      1206.40          0       6032

これは...O/Rマッパーを書いて複数のテーブルを1つのttserverに押し込めるように したほうが良かったですかね。


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年
6月
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

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

訪問者数:(11777+2560143)