2004-07-24

_ZODB

休みになっても、やっぱりZopeいじっている自分が哀しくなりますが、 これは技術的興味だけでやっていることです。

はっきり言って、ZODB(正確にはFileStorageと言うべき)は遅い。 書き込みは確かに速いけど、 ZMySQLStorageより速いわけじゃありません。 実際的にはZMySQLStorageはバグだらけで使えたものではありませんが。

何が遅いって、 オブジェクトの数が膨大なときに、 ルート・オブジェクトから全探索すると、よく分かります。 FileStorageが使うData.fsでは、 関連するオブジェクトが近接して置かれたりはしないので、 ディスクをシークしまくることになってしまい、 ほとんどスラッシングみたいな状態になります。

仕事の上では、まだ耐えられる程度なので、すごく困ってはいませんが、 速くなったらすごく嬉しいし、 技術的に面白いことなので、ちょこちょこ考えたり、 試したりしてるわけです。

忘れてしまわないように、いくらかアイデアを書き留めておきます。

差分?
仮にデータベースの大部分がシリアライズされたオブジェクトのデータで埋め尽くされているとすると、 バージョニングのやり方を改良できるかもしれない。 例えば、現状のように全てをimmutableにはせずに、 過去のバージョンは差分だけを保存するということが考えられる。 もし多くのオブジェクトがそう大きく急激に変化することがないなら、 かなりデータを減らすことができる。
圧縮?
単純にzlib使うということも考えられる。 しかし全体を圧縮すると、 シーク時のオーバーヘッドが洒落にならないかもしれない。 オブジェクト単位で圧縮すると、 オブジェクトのデータは一つだけでは小さ過ぎて、 圧縮率が非常に悪いかしれない。
再配置?
オブジェクト間の関連度に応じて、 準最適な配置を計算し、Data.fsを再配置する。 すごく重そうだし、 そもそもどうやったら出来るのか。 アプリケーションの高いレベルで関連性が定義されると、 Data.fsを探査するだけでは情報が得られない。 ということは、実際に使用している時に、 統計を集めないといけないということか。 リアルタイムでやるのはファイルの一次元性を考えると、 多分無理だという気がする。
分割?
Data.fsがでかいのが良くないのだから、 いっそのことあまり見ないオブジェクトは別のファイルに追い出してしまう。 あるいは、よく使うものを別ファイルにする。 これをやると、FileStorageの「ただひらすらファイルの最後に追加する」 というルールが破られてしまうので、 逆にパフォーマンスが落ちるかもしれない。
徹底分割?
もっと分割しまくることもできる。 極端なのはDirectoryStorageだが、非常にパフォーマンスが悪いと聞いた。 以前の私のテストでも、 ファイルシステムをデータベース代わりにするのは駄目なようだったので、 インデックスをファイルシステムに任せるのは悪いアイデアだと思う。 だから、この方法は多分駄目だろう。

仮定が多いので、実際のデータを解析して、 統計をちゃんと取らないといけません。 気が向いたら、休みの間にやるつもりです。

[]