TokyoCabinet のデータサイズは 64GB 付近で性能劣化
当ブログでサービスを提供している AmazonSearch ですが、子ども部屋の確保が最大の理由で、自宅サーバから sakura VPS 2G へ一ヶ月ほど前に移行を行いました。移行手順は以前もご紹介した、ブログをさくら VPS へ移行手順に準じて行いました。
AmazonSearch は内部計算が複雑なため、さくら VPS では QPS(queries per second)が 5-6 程度しかでません。したがって、高速化を図るためレスポンス結果を TokyoTyrant(TokyoCabinet)にキャッシュする仕様で実装を行っています。先日まで安定運用できていたのですが、RDB(casket-a.tch) のデータサイズが 64GB 付近に近づいた時点で性能が急激に劣化して高負荷でレスポンスが返せない事象が発生しました。ちょうど 2012/6/2 15:30 付近からです。
[tts@localhost tts_cache]$ ll 合計 64439492 -rw-r--r-- 1 tts tts 64001497584 6月 2 15:57 casket-a.tch -rw-r--r-- 1 tts tts 1920080351 6月 2 15:57 log -rw-r--r-- 1 tts tts 5 6月 2 15:56 pid drwxr-xr-x 2 tts tts 4096 6月 2 15:26 ulog
ちなみに、自宅サーバ時代は SSD で高速であったため定期的に RDB を完全に破棄&再構築(つまり casket-a.tch を削除して ttserver を再起動)していたので問題は発生しませんでしたが、さくら VPS では HDD 性能が問題で RDB を破棄すると diskio が高騰してロードアベレージが 30-50 と停止しているにも等しい状態になるため、事実上キャッシュ破棄ができずにいました。
しかし 2G タイプはディスク容量が 200GB しかないため、ディスク容量の問題からプログラムの改修を行っていた矢先にこの問題が発生し、昨日は対応に追われていたところでした。
まず Tokyo Cabinet の 64GB 問題ですが、「TokyoCabinet 64GBの壁|CyberX:エンジニアブログ」で同じ話題を取り扱っていました。同様の問題はぐぐっても検索結果に出てこないので、知名度が低い問題のようです。
HDBTLARGEオプションを指定する必要があるようです。
改めて Tokyo Cabinet の仕様書を読んでみると、こんな感じで記述されています。
Fundamental Specifications of Tokyo Cabinet Version 1 (Japanese)
bool tchdbsetxmsiz(TCHDB *hdb, int64_t xmsiz);
`hdb' specifies the hash database object which is not opened.
`xmsiz' specifies the size of the extra mapped memory. If it is not more than 0, the extra mapped memory is disabled. The default size is 67108864.
If successful, the return value is true, else, it is false.
Note that the mapping parameters should be set before the database is opened.
64GB と書かれてなくて、67108864 KB と書かれていますが、確かにデフォルトではハッシュDBは 64GB の制限があると書かれています。単位が KB だったのと、英語だったので、気がつかない&全然読んでませんでした。すいません!
対応策の #opts オプションについてもちゃんと書かれていました。
Fundamental Specifications of Tokyo Cabinet Version 1 (Japanese)
この問題は Tokyo Cabinet 作者 mikio 氏のブログでも Kyoto Cabinet の設計思想の説明で断片的に取り扱われています。
今回僕がとった対応方法は、さくら VPS 2G プランがそもそも disk 容量 200GB だったので全く別の方法ですが、それはまた別のエントリで解説します。とりあえず、いまから Key-Value やるなら Tokyo Cabinet じゃなく kyoto Cabinet を使っておいた方が良いのでしょうね。
コメントやシェアをお願いします!