ggated/ggatec の遅延の原因2009年03月30日 06時11分15秒

以前から何度も遭遇していた ggate で見られる問題の原因が判明した。

問題は二つ。ggate の TCP の使い方。これを修正すると問題なく動作するのは確認した。もう一つは、TCP の実装。パケットの転送が何故だか遅くなることがある。片方がパケットを送り続けもう片方が受け取るだけなのだが、ほぼ直結に近い形の二台間であっても、その転送に数秒単位の遅れが見られる。コードを探ってはいないし、TCP も転送速度を保証しているわけでもない。しかし、何のトラフィックも無い二台間で、数秒に一パケットしか遅れなくなるのは、明らかに何かがおかしい。

TCP 通信に大きな遅延が出てくるのは、サーバがクライアントに比べて大きく遅く、その遅いサーバに書き込みをする場合。現在、サーバは十年前の物を使っている。読み出しだけだと問題は無い。また、同等レベルのサーバとクライアントを組み合わせた時もこのような症状は出ない。機材の関係などで、遅いクライアントは試していない。遅いクライアントで無ければ行なえない作業が無いのと、余分なデバイスが無い。

ggate はサーバクライアント間で、二つの TCP を接続する。二つとも、一方通行の通信にのみに使われる。何らかの形でこの実装が、この異常なネットワークの遅延を引き起こしている。

元々この実装の仕方がおかしい。TCP は本来双方向通信のプロトコルだ。それをわざわざ二つ作り、単方向通信として使っている。言わば、往復切符を二枚買い、片道分だけ別々に使うやり方だ。なぜ、手間を掛けて余計なことをやるのかがわからない。

これを、わざわざ二つの TCP コネクションを作らずに、一つで処理するように書き換えると、今まで悩まされていた遅延は無くなった。しかし、今度は互換の無い実験的な実装だったので、接続に失敗する場合が出てきて、頭を悩ませている。

この問題のある実装も同じような性能の二台で使うと問題は表面化しない。また、送信側が送ったと高らかに宣言したパケットが届くのに、数秒かかっているのを見ると、TCP の潜在的なバグも存在するのかも知れない。ggate はスレッドを生成し、ソケットをブロッキング I/O で扱っている。送信の専属と受信の専属がいる。FTP のデータポートなども同じような形になる。FTP では問題ないので、TCP の方は杞憂かもしれない。

他にも似たようなものに、iSCSI がある。こちらは RFC で規定されている為、異なったプラットフォーム間でも使える。最近、少しずつ調べている。

次回