memcached binary protocol

先日memcached Night in Tokyo #1に参加してきました。レプリケーションがアツイ。バイナリプロトコルがアツイ。

というわけでバイナリプロトコルのマイクロベンチマークをしてみました。


テストしたのは本家memcachedではなく、私が勝手に作ったストリームパーサです(すべてのプロトコルには対応していません)。get("key$i")set("key$i", "value$i") を5,000,000回ずつリクエストしたときのプロトコルをファイルに保存しておき、mmap(2)してパースしました。
パーサとベンチマークに使ったプログラム一式はmemcached-protocol-bench.tar.gzからダウンロードできます。

リクエスト数 サイズ 時間 1リクエストにかかるパース時間 1秒間にパースできるリクエスト数
text 1,000,000 23.5 MB 0.49 sec 0.49 μsec/request 2,000,000 requests/sec
binary 1,000,000 40.2 MB 0.033 sec 0.033 μsec/request 30,000,000 requests/sec

keyもvalueも非常に小さいため、バイナリプロトコルのヘッダの大きさが目立ちます。バイナリプロトコルの方がずっと高速ですが、1リクエスト当たりの遅延の差は0.45μ秒と非常に小さく、ほぼゼロと考えてもいいのかもしれません。パーサの実装がマズイという可能性もなきにしもあらず ^_^;)

バイナリプロトコルの利点:

  • キーに任意の文字を使える(テキストプロトコルは空白や\r\nが混入すると危険だし、そもそも制御文字は許可されていないので、base64する or エラーにする などの対処が必要)
  • getは1度に1つのキーしかリクエストできないので、サーバーの実装がシンプルになる(get_multiはクライアント側でパイプライン処理して実装する)
  • 何かに使える拡張用フィールド?がある
  • 非同期プロトコルになり得る(クライアントから送られた値をそのまま返すopaqueフィールドがある)

※追記:tmaesakaさんの講演資料が公開されました:memcached Night #1 in Tokyo