要約
以下の重要な領域を最適化します:
- NICオフロード技術
- TCP_QUICKACKで遅延を削減
- net.core.rmem_maxの調整
- SO_BUSY_POLLでCPU効率を向上
- 遅延スパイクを最小限に抑える戦略
スピードの必要性: なぜ100Gbpsなのか?
詳細に入る前に、なぜ100Gbpsが必要なのかを考えてみましょう。高頻度取引の世界では、毎マイクロ秒が重要です。これは単なる自慢話ではなく、数百万ドルを稼ぐか、すべてを失うかの違いです。
しかし、100Gbpsのスループットを達成し維持することは、単にハードウェアを増やすだけではありません。既存のインフラから最大限のパフォーマンスを引き出すためにシステムを微調整することが重要です。ここでカーネルの調整が役立ちます。
NICオフロード: ハードウェアに重労働を任せる
まず最初に、NICオフロードを活用していない場合、パフォーマンスを無駄にしています。現代のNICは、CPUを圧迫する多くのネットワーク関連のタスクを処理できます。現在のオフロード設定を確認する方法は次のとおりです:
ethtool -k eth0
以下の主要なオフロードを確認してください:
- tcp-segmentation-offload (TSO)
- generic-receive-offload (GRO)
- receive-side-scaling (RSS)
これらのオフロードを有効にするには、次を使用します:
ethtool -K eth0 tso on gro on
さらに、100Gbpsネットワークでは、以下の高度なオフロードを有効にすることを検討してください:
- ntupleフィルタリング
- 受信パケットステアリング (RPS)
- 受信フローステアリング (RFS)
これらはCPU使用率を大幅に削減し、コア間のパケット分配を改善します。
TCP_QUICKACK: 高頻度取引では忍耐は美徳ではない
高頻度取引では、ACKを待つことはペンキが乾くのを待つようなものです。TCP_QUICKACKを使いましょう。この便利なオプションは、カーネルにACKを即座に送信するよう指示します。
システム全体でTCP_QUICKACKを有効にするには:
echo 1 > /proc/sys/net/ipv4/tcp_quick_ack
アプリケーション内の特定のソケットに対しては:
int quickack = 1;
setsockopt(socket_fd, IPPROTO_TCP, TCP_QUICKACK, &quickack, sizeof(quickack));
これにより遅延が大幅に削減される可能性がありますが、ネットワークトラフィックが増加する可能性もあります。すべての最適化と同様に、特定のユースケースに対して効果があるかどうかを測定してください。
net.core.rmem_maxの調整: サイズが重要
受信バッファに関しては、大きいほど良いことが多いです。net.core.rmem_maxパラメータは、最大受信ソケットバッファサイズをバイト単位で設定します。100Gbpsネットワークでは、これを増やす必要があります:
sysctl -w net.core.rmem_max=16777216
これにより、最大受信バッファが16MBに設定されます。しかし、これだけではありません!関連するパラメータも調整してください:
sysctl -w net.core.wmem_max=16777216
sysctl -w net.ipv4.tcp_rmem="4096 87380 16777216"
sysctl -w net.ipv4.tcp_wmem="4096 65536 16777216"
これらの変更は一時的です。永続化するには、/etc/sysctl.confに追加してください。
SO_BUSY_POLL: ビジーウェイトが良いこともある
低遅延ネットワーキングの世界では、待たないことが最良の待ち方であることがあります。SO_BUSY_POLLがその役割を果たします。このソケットオプションは、カーネルが割り込みに頼らずに受信パケットをビジーポールすることを可能にします。
アプリケーションでSO_BUSY_POLLを有効にするには:
int busy_poll = 50; // マイクロ秒単位の時間
setsockopt(socket_fd, SOL_SOCKET, SO_BUSY_POLL, &busy_poll, sizeof(busy_poll));
システム全体でビジーポーリングを有効にすることもできます:
echo 50 > /proc/sys/net/core/busy_poll
echo 50 > /proc/sys/net/core/busy_read
この設定には注意が必要です。CPU使用率が増加する可能性があります。専用のネットワーキングコアで使用するのが最適です。
遅延の獣を飼いならす: スパイクを減らす戦略
これらの最適化を行っても、遅延スパイクが発生することがあります。以下の追加戦略でそれらを抑えましょう:
1. IRQアフィニティ
ネットワーク割り込みが専用のCPUコアで処理されるようにします:
echo 2-3 > /proc/irq/YOUR_ETH_IRQ/smp_affinity_list
2. CPUアイソレーション
重要なネットワーキングタスクのためにCPUを分離します:
isolcpus=2-3 nohz_full=2-3 rcu_nocbs=2-3
これらをカーネルのブートパラメータに追加します。
3. NAPI (New API)
ネットワークインターフェースでNAPIが有効になっていることを確認します:
ethtool -k eth0 | grep "napi-tx-"
4. スケジューラの調整
遅延に敏感なタスクには、SCHED_FIFOスケジューラを使用することを検討してください:
struct sched_param param;
param.sched_priority = 99;
pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m);
すべてをまとめる: 全体的なアプローチ
100Gbpsマイクロサービスの最適化は、個々の設定を調整するだけではありません。システム全体に対する全体的なアプローチが必要です。以下は、すべてをまとめるための最終的なヒントです:
- アプリケーションをプロファイルしてボトルネックを特定する
- perf、フレームグラフ、eBPFなどのツールを使用して深い洞察を得る
- 極限のパフォーマンスのためにDPDKやカーネルバイパス技術を検討する
- ストレージI/Oを忘れないでください。隠れたボトルネックになることがあります
- 定期的にベンチマークとモニタリングを行い、早期にリグレッションをキャッチする
結論: 終わりなきスピードの追求
100GbpsマイクロサービスのためのLinuxのチューニングは、簡単なことではありません。ハードウェアの能力、カーネルパラメータ、アプリケーションレベルの最適化の複雑なダンスです。しかし、NICオフロードからTCP_QUICKACK、バッファ調整からビジーポーリングまで、私たちがカバーした技術を使えば、高頻度取引環境を次のレベルに引き上げるための知識を得ることができます。
低遅延と高スループットの追求は決して終わりません。実験を続け、測定を続け、そして何よりも可能性の限界を押し広げ続けてください。次回は400Gbpsのチューニングについて話すかもしれません!
"高頻度取引の世界では、ためらう者は失われる。しかし、カーネルをチューニングする者は市場を支配する。" - 匿名のLinuxカーネルの達人
さあ、パケットを征服しに行きましょう!そして、あなた自身の素晴らしいチューニングのヒントがあれば、コメントで教えてください。HFTの厳しい世界では、私たちは皆一緒にいます... そうでない限り。