Inside はてなブックマーク全文検索: TokyoCabinet と TokyoTyrant で高速化・並列化

遅ればせながら kzk くんの はてなブックマーク全文検索機能の裏側をメモ。

すごくいいコラボレーションだなと思いつつ、ふむふむと思ったのは以下の部分。

当初はそのままSedueをインストールすれば終わるんじゃねぐらいに思っていたのですが、そう甘くも行きませんでした。

一番問題となったのは登録時のパフォーマンス。Sedueでは今まで適当に本文を1文章1ファイルで格納していたのですが、バッチで全文章を登録するとなるとこれでは遅すぎたので、TokyoCabinetを使用して本文を保存する事にしました。

  • APIが簡単
  • 4G以上のデータも扱える
  • スレッドセーフ
  • mixiでの高負荷運用実績が有る

な辺りが決め手でした。これで劇的に速度が改善し、色々と作業が進め安くなりました。

(中略)

開発方法については、Sedueではランキング関数の部分はプラグイン(動的ライブラリ)の形になっていて、サーバーを走らせながらランキング関数を色々と変えることができます(C++で記述可能)。これのお陰で試行回数が増え、だいぶ楽が出来たと思います。

あとこだわった所としては、エントリの持っているメタデータを、リアルタイムに使用する部分です。これにはTokyoTyrantを使用しました。

ブックマーク数を例に取ると、ユーザーがブックマークをした際に、更新用のTokyoTyrantにブックマーク数を記録しておきます(eid -> bookmark_count)。TokyoTyrantレプリケーション機能を使って、参照用のSlaveを並べておきます(/dev/shm/にハッシュDBを置いています)。

これらのTokyoTyrant Slaveを、ランキングプラグインからアクセスする事で、検索されたまさにその時点でのブックマーク数を利用してスコアリングを行います。1つの検索クエリにつき、TokyoTyrantに1万キーぐらいの取得要求が行くこともあって、結構激しいことになってます。でも普通に裁けているので、TokyoTyrant凄い。これぐらいのQPSが出てくれるとKey-Value Storageの応用範囲がぐっと広がって楽しいです。mikio先生++。

先ほどの登録の件もそうですが、mikio先生には足を向けて寝れません。今度飯でもおごらせて下さい。

最近 DBM 使うときは(たとえば ChaIME でも) TokyoCabinet 使っているのだが、確かにこれコンパクトだし(インデックスサイズの小ささに定評ある Tx と比べても2倍も行かない)、検索速いし、大体の用途にお勧めなのである。TokyoTyrant の用例も参考になった。 (memcached 並みの速度で動くようだし) 自分が使うケースとしてはかな漢字変換で SocialIME 的な変換機構導入するときかなぁ。単一サーバで動かしているからあまり必要ないと思うが……

で、ふと最近 Googler になった ohkura さんの MapReduce for Machine Learning on Multicoreを思い出す。このスライドの中では単一マシンで MapReduce 使ってどれくらい効果があるか(ないか)といったことを検討しているが、単一マシンで使っても問題によってはそんな悪くない(statistical query model というモデルに属する学習アルゴリズムであればよい)とのことなので、サーバ構成の問題と言うよりは、問題次第なのかもしれない。