ファイルシステム on ファイルシステム と ファイルシステム on DBM

ユーザーランドでP2P分散ファイルシステムを実装してFUSEでマウントするとき、バックエンドはファイルシステムの方が速いのか、DBMの方が速いのか。


ファイルシステムファイルシステムとして使うのに適したデータ構造になっているはずなので、ファイルシステムの方が速そうな気がする。
だけどもファイルシステムカーネルスペースで動くので、sendfile()とかでがんばらないとread/writeでカーネルスペース→ユーザースペースのコピーが発生するし、open()とかstat()とかでいちいちコンテキストスイッチが発生する。
open()したファイルディスクリプタをキャッシュするとか、余分にがんばらないといけない。分散ファイルシステム的に操作は全部ステートレスでないと困るので、「さっきopen()したファイルの〜」といった操作をプロトコルに加えることはできない。


一方DBMはユーザーランドで動くので、コンテキストスイッチは発生しない。ファイルシステムと言っても結局はパスをキーとしたマップで表せるわけで。値は [付加情報, データ]。マルチフォークとかExtended Attributesとかは気にしない方向で。


ハードリンクやらinodeやらと言った概念は、そもそも分散ファイルシステムの段階で有り得ない概念なので、別にバックエンドでサポートされていたところでどうしようもない。(どうやって全ノードでユニークな番号を割り当てろと)



と言うわけで最近見つけたTokyo Cabinet。これはピッタリな感あり。
データベース本体だけではなくて、実はユーティリティAPI群も便利なんじゃないか。


read()を非同期にできない。どうしたってディスクからのread()は非同期にできないのだけど。マルチスレッドにしない限り。…逆にwriteは普通非同期だけど。

読み込みたいデータがキャッシュに載っていることが期待できるか否かで、戦略が変わる気がする。

載っていることが期待できるなら、ブロック覚悟でread()する。

どうせ載ってないだろー&読み込むデータが十分大きいなら、別スレッド(カーネルスレッド)でread()してmutex+conditionで同期する。あるいはlightyみたいに、tmpfsにLinux AIOでコピーしてシグナルで同期する。非同期はどっちも実装がうげげになるのでヤな感じ。