« Pathtraq 最新ランキング ガジェットを公開しました | メイン | Q4M (Queue for MySQL) 0.3 リリース »
2008年03月10日
高速なCometサーバを書いてみた件
もう昨年の2月になりますが、Comet について調査を行いました。その際の成果をまとめたスライドは既に公開していた (Comet の正しい使い方) のですが、同時に実際に作ってみた実装についても、オープンソース化することとなりました。コードは CodeRepos に置いておきますので、どうぞご覧ください。 (Revision 7754: /lang/perl/fastr)
使い方は example ディレクトリ以下を見ていただくとして、ベンチマークの結果とチューニング手法について、記録と記憶に残っている範囲からまとめておきたいと思います。
パフォーマンスについて
まず、パフォーマンスについてですが、Opteron 240EE という今となっては古い CPU でも、同時2,000クライアント程度まではハンドリングできたようです。手元のデータでは、以下の条件 (たぶん実際のチャットサービスよりも厳しいはず) で、CPU 負荷が 80%-90% でした。また、スループットは約 1.6 message/sec.room でした。
測定環境 | Opteron 240EE / CentOS 4 |
---|---|
受信並列度 | 2000クライアント (遅延: 0.1〜1.0秒 一様分布) |
送信並列度 | 50クライアント (1秒間隔で送信) |
ルーム数 | 25 (1ルームあたり40クライアント) |
一方、こちらは、より古い CPU (Celeron @ 533MHz) で測定したグラフです。こちらは、全員が単一のルームに入っているという想定でのパフォーマンス測定になります。各グラフは、受信数、送信数、レイテンシについて、送受信の並列度を変えながら測定しています。これらグラフから、送信量ではなく、接続しているクライアントの数がパフォーマンスの律速条件となっていること、また、この環境では400クライアント程度が限界である (レイテンシの目標値を1秒以下と設定した場合) ということが読み取れます。
チューニング手法について
本サーバについては、Perl で書くことを前提に、以下のようなチューニングを行いました。C で書き直せばもっと速くなるんじゃないかと思います。
- リバースプロキシとして設計
- メッセージの転送のみに特化
- 認証等はバックエンドに中継
- 可能な限り O(1)
- ハッシュではなく配列を使う
- 接続のファイルデスクリプタを添字にする
- ハッシュではなく配列を使う
- ビットアレイのリングバッファによるタイムアウト処理
- タイムアウトの設定が O(1)
- タイムアウトの処理は O(n) だがビットアレイの探索なので高速
- ビットアレイとリングバッファの大きさは起動時に計算可能
- HTTP レスポンス全体をキャッシュして使い回し
- システムコールと memcpy をできるだけ少なく
- perl は writev をサポートしていない
そんなところです。お楽しみいただければ幸いです。
投稿者 kazuho : 2008年03月10日 15:08
トラックバック
このエントリーのトラックバックURL:
http://labs.cybozu.co.jp/cgi-bin/mt-admin/mt-tbp.cgi/1802