Intel I350の受信バッファが最大値の4096でも溢れた

夏休みもいよいよ最終日となり、一息ついたところでI350の受信側のリングバッファが溢れた事象についてまとめます。

以前より3560Xのアップリンクポートでわずかながらパケット破棄が発生していました。
おそらくマイクロバーストによるものですが、最近新しいArista Networksのスイッチを導入したため、この症状自体は改善しました。

しかし上記の症状が安全装置になっていたのか、DMZ側でトラフィックを受けているLVSのパケット破棄が大量に発生するという現象が発生しました。
以下はその時のグラフです。

lv1

気づいた時にはドキっとしましたが、以前よりnet_devやigbのソースを一通り読んでいたため、カーネル側のキューか、NIC側のリングバッファ溢れだということはすぐ予想できました。
すぐにどちら側の問題か切り分けにはいりました。

まずキュー側です。
/proc/sys/net/core/netdev_max_backlog を超える値はキューイングされず、破棄されます。
影響範囲も少ないのでまずは何も考えずにふわっと増やしてみましたが、効果はありませんでした。

次にバッファ側を調べてみました。

このようにifconfigのoverrunsというなかなか上がらないカウンターが昇竜拳していました。

RX packets:1215382409979 errors:0 dropped:9836789 overruns:9836789 frame:0

値の元になっている/proc/net/devをみてみます。

$ cat /proc/net/dev
Inter-|   Receive                                                |  Transmit
 face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed
 bond1: 301302257145320 1242460031644    0 50134427 19769362     0          0  94522289 59829397999 1104977661    0    0    0     0       0          0
 bond0: 266789966151393 978716441978    0 95911204    0     0          0 142912972 564647908448725 2213999050962    0    0    0     0       0          0
  eth0: 266784042597227 978620538142    0 7402    0     0          0 142780453 564647908459099 2213999050966    0    0    0     0       0          0
  eth1: 5923561185 95903847    0 95903801    0     0          0    132519     1302      31    0    0    0     0       0          0
  eth2: 301300435242358 1242429666624    0 19769362 19769362     0          0  94522274 59829396211 1104977621    0    0    0     0       0          0
  eth3: 1821914034 30365078    0 30365065    0     0          0        15     1788      40    0    0    0     0       0          0
    lo: 6027064668 68489292    0    0    0     0          0         0 6027064668 68489292    0    0    0     0       0          0
bond0.11: 208950786744728 614004718922    0    0    0     0          0  88018817 487194387836941 1723708710469    0    0    0     0       0          0
bond0.12: 41205097680103 308328470394    0    0    0     0          0  50947732 72909647177800 412801455153    0    0    0     0       0          0

対応するカラムはfifoのところです。

fifoって意味はわかるけど、なんぞいやと調べたところFIFOバッファエラーということらしいです。
ethtool -Sでもエラーカウンターとして確認できます。

rx_no_buffer_count: 220474

参考サイト
https://nuclearcat.com/mediawiki/index.php/Intel_Gigabit_Performance#FIFO_buffer

つまり受信バッファが溢れているので、開けてやればいいということですね。
どうやるかというとNAPIはドライバが定期的にポーリングしてバッファの中身をとりにいくため、ポーリング頻度を上げるか、一度で処理する量を増やしてあげればバッファに空きができるはずです。
ただしCPUの負荷は上がります。
自社の場合NW I/O周りはひたすらCPUバウンドという経験がすでにあるため、LVSを新しく作る段階でCPUはXeon E5-1650v2というクロックの高いCPUを採用していたので余裕はまだまだあります。

以下の2がNAPIのバッファポーリングに関するパラメータです。

net.core.netdev_budget
net.core.dev_weight

テスト環境がない一発勝負なので、安全そうなnetdev_buger(処理数の上限アップ)を試してみたところ、見事にパケット破棄が消えてなくなりました。
また何故かわかりませんが、LAN側からのping監視に結構ジッターがあったのがなくなりました。
症状が改善した上に余計調子よくなってしまいました。
CPU負荷も目立って上昇はしていませんでした。

lv2

lv3

まあIntelのNICとはいえ、L3スイッチから全力で投げつけられたパケットを処理するのは箱出しパラメータだときつそうですね。
むしろよく動いてたと思います。

この勢いで10GネットワークでもLVSがまだまだ活躍することでしょう。

安価(?)でプチキャリアグレードNATルータを作ってみた

寒い日が続きますが、皆さん体調など崩していないでしょうか?
自分はサバゲで叫びすぎて喉を痛めてその後いっきに冷え込んだため、そのまま喉をやられてしまいました。
内部ネットワークを10Gでリプレースというでかい作業に着手した直後に同僚が不摂生という不可抗力で倒れ、一人で糞暑い中連日DCに通って朝から晩まで作業して、やっとこさ落ち着いたらこのざまです。

さて、自社でも大変重宝しているCore i7 870のVyattaですが、そのトラフィックもとうとうピーク時で大量のショートパケットをさばきつつ out/400Mbps inout/280Kpps 前後をNATで処理するようなところまできてしまいました。
今となっては貧弱なハードウェアでここまでできてしまったのは、正直想定外です。
CPUはチューニングのためにハイパースレッドをオフにして、各コア綺麗に分散している状態でピーク時で45%くらいなのでそろそろキャパシティに不安がでてきました。

natter1 natter3 natter2

そこで内部ネットワークの10G化にあわせて、新しいNATルータを設置することにしました。
自分の中での要件は以下のとおりでした。

・通常だと一個しか置けないデフォゲーNATルータを複数置いてスケールさせたい
・安定性と冗長性は絶対ゆずらない
・アクティブスタンバイ構成をやめてアクティブアクティブにして効率化したい
・Vyattaの負荷を考慮してデフォゲーと内部ルーティング用を分離して、全サーバにスタティックルートを書いている運用を捨てたい
・フェイルオーバーは2,3秒くらいでしてほしい

という夢の様な要件から、以下の方法を導き出しました。

・NAT/IP Masquaredeは従来通りVyattaでがんばる、ここはCPUパワーでコスパを出すしかない
・デフォゲーは信頼性向上と直近でセグメント間の通信をワイヤレートでする必要があるため、思い切ってディストリビューションスイッチとしてL3スイッチを導入する
・デフォゲーを受けたL3スイッチからは、OSPFのECMPでNATルータの負荷分散をする、冗長性はルーティングプロトコルで担保する

このように、L3スイッチが得意とする超高速ルーティングと、CPUバウンドでなんとかなるIP Masuquaredeの処理をVyOSでするという分担構造になりました。

説明用に軽く図をかいてみました。

natter4

これならば高信頼かつワイヤレートでVLAN間が通信できるし、NATルータはL3スイッチのECMP上限数まで増やせるし、内部と外部用でゲートウェイわけなくてもいいし、一石億鳥やー!ってことでプロジェクトは動き始めました。

L3スイッチとVyattaでのOSPF ECMP NAT串刺しルーティング構成の検証はVirtual Box上で、Arista NetworksのvEOSを対向として行いました。
vEOSは多少の機能制限があるものの、ほぼ完璧にL3スイッチの動作をするのでこちらで検証を行いました。

もちろん外部と正常に通信できるのは当たり前ですが、ルーティング的に問題ないことはわかっていたので、ECMPの分散に偏りがでないかを重点的に調べました。
一昔前のL3スイッチではECMPの負荷分散がIPを元にハッシュ化していたため、しばしば偏りECMPの意味がないといった状況が多発していたようです(?)
現在ではパケット単位が標準のようです。

ディストリビューションスイッチはアライドテレシスのx8100を導入しました。
要件に対して事前の検証やアドバイス、導入支援まで迅速に数多くしていただきました。

今回はこの程度の概要しか気合が足りなくて書きませんが、リクエストがあればもうちょっと深く掘り下げて書いて見ようと思います。

このドサクサにまぎれてVyattaからVyOSに移行しました。
詳細は過去のエントリーにあります。

あとサーバルームの連続稼働は一日6時間くらいまでが健全だと思いました。