オルタナティブ・ブログ > プログラマー社長のブログ >

プログラミングでメシが食えるか!?

ネットワークパケット処理の高速化

»

ネットワークプログラミングの仕事を長年してきましたが、ネットワークインターフェースが1Gbpsまではプログラム側の速度が追いつかないということは基本的にはあまりありませんでした。もちろん、無駄な処理をしていればプログラム側の問題で性能が追いつかないこともありますが、どちらかというとプログラムの処理速度よりネットワーク側の方が遅かった為です。ところが、最近10Gbps対応の開発をいろいろやっていると、ネットワーク側の方が速くて、プログラム側の処理が追いつかないということにぶつかりまくりました。

プログラム自体の高速化は、プロファイラを使うなどして追い込んでいけるのですが、それでも本来出るはずのスループットが達成できないことも多く、いろいろと試行錯誤をしてきました。

まずは、ネットワークインターフェースから受信したパケットをカーネルからコピーして受け取る方法から、直接カーネル内のメモリーにアクセスする方法が高速化の手段としてあります。メモリーコピーのオーバーヘッドすら問題になるほど10Gbpsは速いのです。これもそれなりに効果はありますが、これでもまだ追いつかないこともあります。

今どきのCPUはコア数が複数あるのはもちろん、並列処理を12個くらいは普通にできる時代です。ところが、普通にネットワークパケットを処理すると、順番にしか読み出しができず、そのためCPUの並列性を活かせずに、性能を上げられない、という感じになります。もっとも、パケットの取り出し自体が遅いというより、取り出したパケットの処理が遅い場合がほとんどですが。

パケットの並列処理で最も問題になるのは、パケット順の入れ替わりでしょう。UDPでも動画配信などではパケット到着順が入れ替わるのは望ましくありませんが、TCPでは入れ替わるとかなり致命的に性能を落としてしまいます。そのためネットワークインターフェースから順番に取り出したパケットを、多くのスレッドに分散させて並列処理するのは難しいのです。

そんな問題を解決するのが、RSS(Receive Side Scaling)などと呼ばれている技術です。ネットワークインターフェースが受信したパケットは実はCPUのスレッドを複数使って並列処理されているのですが、プログラムに渡す際に順番に渡すためにまた一本化しているのを、CPUのスレッドごとに直接プログラムもアクセスできるようにする技術です。さらに、パケット順入れ替わりの問題が起きないように、TCPのセッションごとにCPUスレッドをきちんと分けて分散してくれるようになっています。

これはかなり効果が高く、私が頭を悩ませていたシステムも、この技術でようやく要求性能を達成できたくらいなのですが、普通のパケット処理プログラムとは全く異なる扱い方が必要です。デバイスドライバも専用のものを使い、複数プログラムが同時にインターフェースにアクセスすることもできず、OSが提供してくれるネットワークの様々な機能は一切使えなくなります。本当に単純にパケットレベルでプログラムが直接読み書きしたいという目的でしか使えません。

実は昨日ProDHCPの相談であるお客さんを訪問し、大規模ネットワークシステムでの苦労話になった際に、同じように10Gイーサーでのスループットの苦労をされていてました。RSSの情報などは非常に少なく、しかも日本での情報はほとんどありません。でも実はネットワークインフラ関連のシステムを手がけている会社では、それぞれが苦労して取り組んでいるのです。日本の残念なところは、そのような基礎技術でどの会社にも役立つような技術でも非常にクローズドなところでしょう。それがメシの種になっているということもありますが、同じような苦労を国内各社でやっていても時間ばかりかかってしまい、なかなか海外に勝てないのではないでしょうか。さらに、日本でもネットワーク関連をアカデミックで取り組んでいる団体もありますが、実践よりは論文になるかどうかが重視され、おまけに日本特有の、すぐに批判ばかりする体質のために、だれも公表したがらない、ということになっている気がします(私が知らないだけかもしれませんが)。さらにユーザ側も、実績重視でチャレンジしませんし、エンドユーザはますます細かいことまでうるさい・・・結局、なんでも海外から実績のある製品を仕入れておしまい、という今の状態で本当に良いのだろうか、と心配なのでした。。

Comment(0)