Study: Huaweiのロスレスネットワーク

Huawei - Intelligent Lossless Network

  • Queueの閾値を転送能力に合わせて調整する。PFCがなるべく発動しないようにする。
  • ECNの閾値を調整する。incastのElephantとMiceの比率に注目する。
  • Fast ECN(標準でEnable)。これによりECNがデバイスから出るのはECN発動した起因となるパケットがキューから抜けるときではなく、そのキューから出るパケットにECNを立てる。これによりバッファが深くてもECNが早く転送される。
  • Fast CNP(標準でDisable)。デバイスがDest側に代わってCNP(本来はDestのホストが返すもの)をSrcに返す。(私見:これにより、先ですでにPFCロッククラスの輻輳が起こっていても早く返せる、という効果もありそう)
  • ElephantとMiceを識別できる。(これは他社でもありそう)
  • ダイナミックロードバランスをサポートする。フローレットはEligibleモードにした場合、伝送遅延よりも長いパケット間隔が来た瞬間に別のフローレットとして扱う。

以下はそれぞれのページについてざっくり要約。

PFCデッドロックは網全体がPFCを送り合いPFCが解除されない状態になること(で網全体が使えなくなること)である。リンクやノードに故障が発生するとこれは容易に発生する。

デッドロック発生のメカニズムは次の通り。RT1とRT2が存在し1: RT1からPFCが送信された。RT2はこれを受信するとRT2からRT1へのフレーム転送を停止すると同時にデッドロック用のタイマーを開始する。 2: このタイマーの終了までにPFCがXOFF状態のままである場合、PFCがデッドロック状態であると判定する。3: 回復処理を行う。この処理の期間中RT1から送られるPFCフレームはRT2で無視されRT2に事前定義されたactionにより,PFCを受け取っているにも関わらず転送あるいはトラフィックを破棄する。これを事前定義した回復期間中行う。そしてPFCデッドロック状態を解除する。つまり1の状態に戻る。 4:このデッドロックの回復プロセスが複数回行われた場合はデッドロックの制御(Deadlock control)プロセスに入る。この時にシステムはPFCを無効(手動で再度有効にするまで)にする。 以上がデッドロック検出メカニズムである。

このdetectionの設定を行える。ハードウェアベースのdetectionとソフトウェアベースのdetectionもありHuaweiの標準設定では、両方とも無効である。

デッドロック検出メカニズムを説明してきたが、ループが起きている状態など再びデッドロックになる環境ではデッドロック検出から復活しても再びデッドロックが発生し、スループットに大きな影響を与える。そこでデッドロック防止(Deadlock Prevention)という仕組みがある。

この機能はデッドロックの原因となっているフローを特定しSpine-Leaf構成を前提とする。これはフローテーブルで実装されるわけではなくPFCアップリンクを定義する必要がある。ここで大切なことはアップリンクから入ってきたフローが再びアップリンクに出ていくフローは危険であるということである。通常のSpine-Leaf構成ではLeafからSpineに対してパケットの反射は発生しない。そこでそのようなパケットは別のキューにDCSP値を書き換える。(私見:これがどのようなキューに変わるのか記載はないがおそらくdefaultのPrioに落とされるのだろう)

この防止機能が有効がリーフが受け取るキューa, 送り変えたキューがbとしよう。もし、このリーフでキューbが溢れた場合、送信元のSpineにキューaでPFCを送信する。もし、この先のSpineでキューbが溢れた場合、そのSpineはこのリーフに対してキューbでPFCを送る。(私見:これでなんで防げるんだ?)

ロスレスキューの実装を知るにはチップ全体のキューとインタフェース単位のキューを知る必要がある。以下のうちHeadroomの概念はロスレスにしかなく、Lossyなネットワークには存在しない。

チップレベルのキューは次の4つがある。1: Staticバッファ, 2: Dynamicバッファ、3:サービスプールvbuffer, 4: ヘッドルームプール(Headroom)。3,4は2の詳細な区分である。チップレベルのバッファは大きくStaticバッファとDynamicバッファに分けられる。Dynamicバッファは動的に3,4を割り当てる。Staticバッファとは固定的なサイズをもち、インタフェースの保証バッファが割り当てられるとインタフェースごとの領域がメモリに固定的に確保される(他のものはインタフェースを跨いで共用なことに注意)。3,4は全インタフェースで共有可能なバッファである。

インタフェースプールは少し異なる。1: 保証バッファ(Guaranteed buffer), 2:サービスプールvbuffer, 3: ヘッドルームプールHeadroom。チップレベルと同様に1はキューの保証バッファ分を確実に確保する。2,3も同様に全部のキューで共用されることに注意する。

キューのバッファはインタフェースのバッファと基本的に同じ。1の保証バッファはインタフェースのin/outで確定的に確保する。2のサービスプールはバースト的なトラフィックのバッファとして使う。3のヘッドルームは特殊でoutには存在しない。これはPFCのバックプレッシャーを受けている時のバッファ向けのキューでありPFCが発動している間のフレームを保持する機能。

これらのキューのサイズを適切に設定する必要がある。まず、保証バッファは魅力的なバッファだがこれが大きすぎると動的バッファは小さくなる。また、ヘッドルームバッファはPFCが発動しなければ不要ないわば臨時のバッファであるがこれを取りすぎると通常のバッファがなくなるし、少なすぎるとPFCが発動する。このバッファの調整は重要な点であるのでIntelligentなバッファ割り当てが重要となる。

基本的な動作を確認しよう。まずPFCよりも先にECNが先に発動する閾値だとする。途中のノードでキューがECN閾値を超えるとECNがdestに通達され、結果src側にECNが到達して送信レートを下げる。これでキューの輻輳は収まらずPFC閾値を超えたとする。PFCがsrcまで届いた場合srcは発出を止める。PFCが解除されるとsrcは送出を再開する。

問題点:ECNはトリガが発生してから送信元に到達するまで時間がかかる。キューを超えてから宛先に届いて送信元に帰るまで送信は制御されないからである。それまでの間にPFCが発動してしまいNWのスループットは著しく下がる可能性がある。

従来は閾値は手動で設定されてきた。固定的な手動による設定は以下のような問題を引き起こす。閾値を低く設定し過ぎた場合ECNが早く発動しすぎキューの遅延はとても低くなる、なぜなら、ECNが早く発動しキューは浅くなるからである。マウスフローには有利である。一方で閾値が遅い場合ECNの発動が遅くなりすぎる可能性もあるしキューは深くなる(私見: キューの深さはマウスフローの遅延に影響を与える)

動的ECNの閾値調整はこれらの問題を解決する。この基本的な考え方を述べる。2つの指標を考える。1つはマウスとエレファントの比率。またN:1で表されるincast valueである。

incast valueが高い場合、つまり複数のノードから1台のノードに多量のincastがある場合、ECNの閾値は低く設定して早くECNが発動するようにする。これにより(私見:多数のノードがsrcになっていると全員が一斉に発呼すると溢れやすくなるので)PFCの発生を低減することが可能である。逆に低いincastである場合は高いECN閾値とする。

マウスとエレファントの比率について、マウスが多い場合は低遅延としたいのでECN閾値は低くして良い。逆にエレファントが多い場合はECN閾値を高くする。

本題である動的な制御について考えよう。前述した通り動的なECNの閾値制御を使うとうまく最適なロスレスネットワークを実現できるかに見える。しかし、ネットワーク上を流れるトラフィックというのは多種多様なのでこれは極めて難しい。このためにこのセクションで述べるAI閾値が重要になる。

前述の機能が有効になるとデバイスは各キューのトラフィックを以下のようにAI制御(別に詳しく述べられているわけではない)する。ASICはキューの情報をデバイスのAIコンポーネントに送出する。AIコンポーネントは今のフローの状態が既知かを判定し既知ならば過去に基づいた最適な閾値に設定する。未知である場合、前述のセクションような試行錯誤を行い、最適な閾値を調整する。AIコンポーネントはこの結果をキューのECN閾値に反映する。これらを繰り返す。

以上の仕組みによってデバイスはリアルタイムにネットワーク上のトラフィックに応じた適切なECN閾値を設定し、最適なキュースケジューリングと閾値設定が可能になり、ネットワークは最適なパフォーマンスを提供する。

高速な輻輳制御を行う際にECNには課題がある。それはキューがECN閾値を超えた際にその超えたパケットに対してECNが付与されるので、そのフレームがキューから送出されないとECNがDest側に飛んでいかない。つまり、すでにキューに積まれているパケットにはECNは付与されない。そこで、FastECNはECNの閾値を超えている時に発出するパケットにECNフラグを立てる。

FastECNを使ったとしてもDestがECNフラグを検知してCNPを返すまでには(FastECNよりも)大きな時間がかかる。そこでFastCNPはスイッチデバイスがDestの代わりに先にCNPを返す。この実装はデバイスがフローテーブルを持ち、ECN状況下においてフローテーブルを探索して該当するSrcにCNPを返す。

FastCNPはいくつかの設定を持つ。まずは集約時間。これはFastCNPが発動した際、Dest側からCNPを受け取ると(フローごとの)一定時間それを破棄する(標準は50us)。これによって複数のCNPのSrcへの到達を抑制する。次にフローの生存時間。これはFastCNPに用いられる(qos fast-cnp flow-table age-time)固有のの生存時間である。

スイッチは8本のキューを持つがロスレスネットワークではエレファントフローとマウスフローを識別するのが重要である。一般的なロスレスの議論であるがマウスフローは低遅延にロスがなるべく少なく完了されるべきである。マウスフローは制御に使われるため、FCT:フロー完了時間(Flow Completion Time)に大きな影響を与える。このためのポイントとしては、フローがどちらかの識別マウスフローの優先である。

これをどのように実現しているのだろうか?デバイスはフローを識別しそのバイトカウントなどをとる。エレファントフローに識別された閾値をこえるとそれはエレファントフローであるので優先度の低いキューにラベルを張り替える

古典的なロードバランス(staticロードバランス)を考える。LAGやECMPはフロー単位での負荷分散を行う。これは5 tupleハッシュをつかってリンクを選択する。これによってあるハッシュのフローのデータ到着順序は保証される。この方法の最大の欠点はメンバリンクの負荷の偏りである。とくにとてもエレファントなフローがあるリンクに偏った場合、(本来はもっとうまく負荷分散できる場合でも)輻輳やパケロスが生じる。

そこでDynamicロードバランスを考える。これは eligible, spray, fixedの3種類が存在する。eligibleが推奨される。

Eligibleを説明する。あるスイッチの直接なPeer(Directなリンク)には伝送遅延(transmission delay)が生じる。フローとは連続したパケットの連続であるため、リンクの伝送遅延がパケットの間隔よりも短いのであれば順序関係は保証される。Eligibleはこれを活用する。フローレットとはある同一のフローにおいて(この文脈では)リンクの伝送遅延を超えた間隔で到着する最初のパケットを開始とする。リンクの伝送遅延を超えない間はフローレットを切らない(私見:と言い切っていいはず)。逆に言えば伝送遅延を超えたらぶったぎる。

sprayはフローをパケットごとに分散(spray)する。このため到着順序の保証はできず、受信側はフローの再構成をサポートしなければならない。これはあるフローの中に長いパケット長が存在するとうまくいかない。図を参照のこと。

fixedはあまり詳細が書いていない。あるフローを開始する時に完全なstaticではなくて一番空いているリンクを選び、その後同一のフローは同じリンクを使う、ということだと思う。

一般的なDCを考える。Spine-Leafが100Gでサーバは25G/100Gのネットワークでオーバーサブしているとする。ネットワークの各所ではRoCEv2が有効になっている。このような状況下でHuaweiのインテリジェントなロスレステクノロジは効果的に動く。なぜなら様々なマウスフローとエレファントフローを効果的に扱うことができるからである。さて、もっと詳細の話をする。

HPCはとにかく高速な演算が必要になる天体・化学分野などで広く使われてきた。1つのタスクが複数に分散されてサーバのコンピューティング速度の向上に従い、ネットワークのパフォーマンスも向上しなければならない。つまり、ネットワークの負荷が重くなる。サーバは一般にN:Nで通信を行い、結果を同期する際にN:1のインキャストトラフィック通信を行う。HPCの場合はCPU通信が非常に多い。

分散ストレージ1つのデータは複数のサーバに書き込まれる。これにより、冗長性を保ち、読み込みも早くなる。一方で、書き込みの一貫性は必要。書き込みの際は1:Nのインキャストトラフィック。読み込みの場合はN:1のインキャストトラフィック。

AIクラスタの場合、N:1のインキャスト通信でいてイテレーションの結果が同期される。それぞれのトラフィック量はパラメータの数に比例する。このため、LLMブームの昨今では、トラフィックの律速がそのままAI計算の律速となる。