« リモートからXenのDomUとかLVMやファイルを差分バックアップするスクリプトを書いた | Main | 高度に進化した分散データストアは RDBMS と見分けがつかない? (shibuya.pm #12 スライド) »

December 01, 2009

TCP通信ではデータの送信をまとめて行うべき、もうひとつの理由(& サーバのベンチマーク手法の話)

 TCP通信をするプログラムを書く際に「データの送信はまとめて1回で」行うべき、というのは鉄則と言っていい、と思います。その理由としては、パケット数を最小限に抑えることでオーバーヘッドを少なくするためだと一般に説明されますが、自分はもうひとつポイントがあると考えています。次のグラフを見てください。

Write_size_and_speed

 グラフは、一定量のデータを転送するのにかかる時間と使用するブロックサイズ(1回のwrite(2)で書き込むサイズ)の関係を表したものです注1

 ホスト間のTCP通信を行っている場合は、TCPのバッファが有効に機能するので、ブロックサイズ(=パケット数の逆数)による速度の変化は、ほぼありません。一方、同一ホスト上で通信を行うと、ブロックサイズと反比例して所要時間が反比例の関係にあることがわかります。

 原因は、同一ホスト上の通信では、送信プロセスがwrite(2)を呼ぶたびにコンテクストスイッチが発生し、受信プロセスが起き上がってread(2)でデータを受信するところにあります。そのオーバーヘッドが大きいため、ブロックサイズを小さくするのに反比例して速度が遅くなるのです。この傾向は、送受信プロセスが交互に起動するユニプロセッサのシステムだけでなく、別個のCPUで実行されるマルチコアの環境でも同様です。

 以上が、TCP通信をするプログラムではデータの送信はまとめて1回で行うべき、もうひとつの理由です。アプリケーションプログラマの視点から見ると、ホスト間のTCP通信はスループット重視だが、同一ホスト間の通信はレイテンシ重視だ、と理解しておけばいいのかもしれません。少なくとも、高速なサーバプログラムを開発する際には、ローカルとリモート両方でのベンチマークをとった上でチューニングを行うべきなのは確かだと思います。

 自分が昨日の Shibuya.pm #12 で「サーバプログラムはリモートホストからベンチマークすべき注2」と主張したのは、以上に基づき、不要なコンテクストスイッチを避けるべき、という考えからです。今、手元にいいデータがないのですが、サーバとベンチマークプログラムの両者を同一ホスト上で動かした場合のみ、コンテクストスイッチが頻発しパフォーマンスが低下するケースがあったと記憶しています注3

 サーバの作りは製品によって異なりますから、最大スループットを比較するようなベンチマークテストを行う場合は、リモートホストから測定するのが公平なのではないでしょうか注4

注1: 確か linux 2.6.18 で測定。TCP_NODELAY はセットしています
注2: 「実際の利用形態がリモートホストからのアクセスになるのであれば」とすべきかも
注3: 例えばマルチスレッドなサーバとマルチスレッドなクライアントだと速度が落ちると思います
注4: 最大スループットを必要とするような大規模の運用では、通常リモートホストからサーバを利用すると考えられるため

TrackBack

TrackBack URL for this entry:
http://bb.lekumo.jp/t/trackback/404050/22470027

Listed below are links to weblogs that reference TCP通信ではデータの送信をまとめて行うべき、もうひとつの理由(& サーバのベンチマーク手法の話):

Comments

Post a comment