memstored は memcached のバイナリプロトコルをサポートしたハッシュストレージサーバーです。IO戦略ライブラリmpio の信頼性と性能をテストするために開発しました。

IOに mp::iothreads を使用し、バックエンドには Tokyo Cabinet の抽象データベースAPIを利用しているため、高速でスケーラビリティが高く、かつ柔軟性の高いアーキテクチャになっています。プログラムの大部分はライブラリによって実現されているため、プログラム全体の見通しが良く、行数で見ても非常に小さく収まっています。





IOアーキテクチャ

マルチコア時代の高速サーバーの実装で紹介したサンプルプログラムと同様に mp::iothreads を使っています。memstored はスレッド間で共有するリソース（=排他処理が必要）が少ないので、すべてマルチスレッドで記述しています。

新しいクライアントを accept(2) するためのスレッドが走っており、コネクションが確立されるとWorkerスレッド*1にソケットが受け渡されます。

Workerスレッドはクライアントからデータを受け取り、memcached プロトコルのパースとデータベースの操作を行います。そのスレッドでそのまま返信を返します。ここで返信のサイズが非常に大きかったときに書き込みがブロックしてしまうのを防ぐため、一度に書き込みきれなかった場合は Output 用のスレッドに受け渡します。

返信は writev(2) を使って送信しています。アドレスが連続していなくてもカーネル内で効率よく処理してくれるので、ヘッダ + データ という形式のプロトコルを効率よく送信できます。memstored はデータベースからデータを取り出してから返信が完了するまでの間に一度もデータをコピーしません*2。

この最適化はデータのサイズが大きいときに効果を発揮しそうです。



