限界への挑戦:Netflixがいかにして800Gb/sのビデオトラフィックを配信するか

限界への挑戦:Netflixがいかにして800Gb/sのビデオトラフィックを配信するか

数百万人の同時ユーザーに高画質ビデオを配信するには、単なる高速なディスクや大容量の回線だけでは不十分です。ストレージからネットワークへビットを移動させることに寄与しない、あらゆるCPUサイクルとメモリコピーを徹底的に排除する必要があります。NAB Showでの詳細な技術プレゼンテーションにおいて、Netflixのエンジニアは、単一サーバーのスループットを800Gb/sへと押し上げるために必要となったアーキテクチャの進化を明らかにしました。

この規模では、主な敵は生の計算能力ではなく、メモリ帯域幅とオペレーティングシステムカーネルのオーバーヘッドです。これらの速度を達成するために、Netflixは特定のワークロードに焦点を当てました。それは、FreeBSD-currentとNGINXに基づいたスタックを使用して、事前にエンコードされた静的メディアファイルを配信することです。

データパスの進化

Netflixがいかにして800Gb/sに到達したかを理解するには、CPUとメモリバスへの「税金」を削減するために実施された最適化のタイムラインを見るのが役立ちます。

1. 非同期sendfile (2014)

従来、ファイルの配信は、ディスクからカーネルへ、次にユーザースペースへ、そして最後にネットワーク経由で送信するために再びカーネルへとデータをコピーするプロセスを含みます。Netflixは、sendfile(2)を利用しました。これにより、カーネルはユーザースペースを完全にバイパスして、ファイル記述子からTCPソケットへ直接データを送信することが可能になります。

しかし、標準的なsendfileは、ディスク読み取りが遅い場合にNGINXのワーカーをブロックしてしまう可能性があります。Netflixは非同期sendfileを実装し、この操作を「投げっぱなし(fire and forget)」のメカニズムへと変えました。ディスク読み取りが完了すると、割り込みハンドラがTCPスタックにデータの準備ができたことを通知し、ワーカーのスレッドが停止するのを防ぐことで、古いハードウェアでのスループットを23Gb/sから36Gb/sへと向上させました。

2. Kernel TLS (kTLS) (2016)

現代のトラフィックにおいて暗号化は必須ですが、TLSは通常、sendfileのパイプラインを破壊してしまいます。標準的なTLSセットアップでは、データをカーネルからユーザースペースへコピーし、CPUで暗号化してから、再びカーネルへ送り返す必要があります。

Netflixはこの問題を、TLSの共通鍵暗号をカーネル内に移動させることで解決しました。初期のハンドシェイクはユーザースペースに残りますが、バルク暗号化はsendfileパイプラインの一部として処理されます。これにより、ゼロコピーのデータフローが回復し、カーネルとユーザースペース間の繰り返されるコピーによる膨大なメモリ帯域幅のスパイクを排除しました。

3. NUMAの習得 (2019)

ネットワーク速度が上昇するにつれ、NetflixはNon-Uniform Memory Architecture (NUMA)の限界に直面しました。マルチソケットシステムでは、メモリとI/Oデバイスは特定のCPUコアに「近い」状態にあります。もしNode 0上のCPUが、Node 1に接続されたメモリ内のデータを暗号化し、Node 0に接続されたNICによって送信する必要がある場合、データはNUMAファブリック(ソケット間の相互接続)を何度も横断しなければなりません。

最悪のシナリオでは、単一のパケットがNUMAバスを4回横断することになります:

  1. ディスクからメモリへ
  2. メモリからCPUへ(暗号化のため)
  3. CPUからメモリへ(暗号化済み)
  4. メモリからNICへ

この混雑はCPUのストールを引き起こします。NetflixはDisk Centric Siloingを実装し、読み取り、暗号化、および送信のプロセスが、データが存在するNUMAノード上で完結するようにしました。さらに「Strict Disk Centric Siloing」へと移行することで、NUMAバスのバルクデータの横断を完全に排除し、ファブリックの飽和を大幅に削減しました。

最終的な飛躍:インライン・ハードウェアkTLS (2022)

NUMAの最適化を行っても、ソフトウェアベースのkTLSは利用可能なCPUサイクルのほぼ半分を消費します。400Gb/sの壁を突破するために、NetflixはNVIDIA (Mellanox) と協力し、ConnectX-6 Dx NICを使用してInline Hardware kTLSを実装しました。

ハードウェアオフロードを利用することで、カーネルは暗号化キーをNICに直接渡します。データはディスクからメモリへ、そしてそのまま平文でNICへ流れます。NICがワイヤーに到達する際に、データをオンザフライで暗号化します。

その影響は二重です:

  • CPUの負荷軽減: ホストCPUはもはやバルク暗号化のプロセスに関与しません。
  • メモリ帯域幅の削減: CPUが暗号化のためにデータを読み書きする必要がなくなるため、メモリ帯域幅の要件が半分に削減されます(800Gb/sのストリームにおいて、約400GB/secから約200GB/secへ)。

800Gb/sにおける実験結果

AMD EPYC 7713 CPUを2基搭載し、Mellanox ConnectX-6 Dx NICを4枚搭載したDell R7525サーバーを使用して、Netflixは本アーキテクチャの限界をテストしました。720Gb/sへの道のりは、いくつかの反復を経て達成されました:

  • 初期結果 (420Gb/s): ソケット間のxGMIリンクにおけるAMDの動的リンク幅管理 (DLWM) によって制限されていました。
  • 強制リンク幅 (500Gb/s): xGMIをx16および18GT/sに強制設定した後、NVMeクアドラント間の不均等なI/O分布により、プラトーに達しました。
  • Disk Centric Siloing (670Gb/s): DMAの処理方法を変更することでxGMIハッシングを改善しましたが、これはページデーモンへの負荷を増大させました。
  • Strict Disk Centric Siloing (720Gb/s): 送出NICがディスクのあるNUMAノードにローカルであるように設定することで、720Gb/sに到達しました。この時点で、ボトルネックはCPUから、コンテンツの人気の度合いによるNIC出力ドロップ(一部のNICは94Gb/s、他のNICは84Gb/s)へと移行しました。

技術的統合とコミュニティの視点

このアーキテクチャは、ハイパフォーマンス・ネットワーキングにおける根本的な転換、すなわち「すべてをオフロードする」という動きを強調しています。データプレーンをカーネルへ、そしてハードウェアへ押し出すことで、NetflixはCPUの役割を役割をこなすコーディネーターへと最小化し、データプロセッサとしての役割をから脱却させました。

コミュニティの視点からは、一部のオブザーバーは、静的で既に暗号化されたDRMコンテンツに対してTLSの必要性に疑問を投じています。しかし、「TLS everywhere」という業界のトレンドは、セキュリティとプライバシーのメリット、そして標準化されたハードウェアオフロードを利用できる能力が、オーバーヘッドを上回ることを示唆しています。さらに、このスタックにおけるFreeBSDの使用は、ネットワークスタックに対するきめ細かな制御が不可欠な、特殊で高スループットなネットワーキング・タスクにおいて、BSDカーネルが引き続き極めて重要であることを裏付けています。

Sources