ウェブ広告のインフラについて(第3回) vyattaのチューニング

梅雨入り前の微妙な天気が続きますね。

今回は前回の基本構成で紹介した、vyattaに実際どういったチューニングを施しているのかと愚痴を書いていきます。

自社でのサービス系のトラフィックのほとんどはLVSから入りvyattaから出て行きます。
vyattaはLVSを通った戻りのトラフィックだけでなく、多数あるDSPへのビッドリクエストも処理しています。
また、グローバルIP節約のためにIPマスカレードをしています。

実は自社のネットワークではここがコアスイッチに次いで重いのですが、CPUが i7 870 メモリ16G NIC 82574L 2口のサーバでピーク時に上り 500Mbps 200K/pps 程度を処理しています。
ただbufferbloatやマイクロバーストの影響と思われる送信キューの再キューが発生してしまっています。これは今度の課題です。

現状使っているハードウェアがかなりショボイので、箱を変えるだけで10GクラスのIPマスカレードもvyattaでいけると確信しています。
そもそもIntelに言わせると、82574LなんてNICじゃなくてPHYだ!だそうで…。

では具体的なチューニングを紹介していきます。

リングバッファを増やす

82574Lに限らずIntelのNICはTx/Rx共に最大値が4096ですが、デフォルトだと256固定になっています。
これにより、受信の場合だとTCPスタックのキューに入る前にリングバッファが溢れてパケットが破棄されてしまいます。

ただバッファも多ければいいというわけではなく、bufferbloatやバッファが増えることによりレイテンシーが低下します。
パフォーマンスを求めるなら、NAPIのチューニングも必要になります。
難しいことはいつもの次回以降に。

デフォルトの状態です。

ethtool -g eth0
Ring parameters for eth0:
Pre-set maximums:
RX:		4096
RX Mini:	0
RX Jumbo:	0
TX:		4096
Current hardware settings:
RX:		256
RX Mini:	0
RX Jumbo:	0
TX:		256

増やしてみます。
この際リンクダウンが発生するので注意が必要です。

ethtool -G eth0 rx 4096 tx 4096

なお現状に適正なリングバッファの値を調べることはかなり面倒です。
闇雲に増やしてもマイクロバーストの原因となってしまいます。
リングバッファが常に溢れていないか、またはフルになった形跡を確認する必要があります。
これについては確証は得ていないのですが、それっぽい方法は調べてあるので次回以降です。

RFS/RPS

82574LはとてもいいNICなのですが、NICのインタラプトが以下のようになっています。

 50:   81480180          0          0          0   PCI-MSI-edge      eth0-rx-0
 51:    7064255          0          0          0   PCI-MSI-edge      eth0-tx-0
 52:       4786          0          0          0   PCI-MSI-edge      eth0
 53:          2   77843270          0          0   PCI-MSI-edge      eth1-rx-0
 54:          1    1888030          0          0   PCI-MSI-edge      eth1-tx-0
 55:          8          0          0          0   PCI-MSI-edge      eth1

一応マルチキューになってはいますが、Rx/Txが単体で分散していないため、どうして特定のコアに負荷が集中します。
これを分散する為にRFS/RPSを利用しています。

なお評価中のi350ではRx/Txをモジュールに与える値で変更できます。
以下は一例です。

  65:          7          0          0          0          0          0  IR-PCI-MSI-edge      eth2
  66:   47472804          0          0          0         21         27  IR-PCI-MSI-edge      eth2-rx-0
  67:   49140306          0          0          0          0          0  IR-PCI-MSI-edge      eth2-rx-1
  68:         31          0         29   68618984          0          0  IR-PCI-MSI-edge      eth2-rx-2
  69:    9835040          0          0          0          0          0  IR-PCI-MSI-edge      eth2-tx-0
  70:         26          0          0          0    9837578          0  IR-PCI-MSI-edge      eth2-tx-1
  71:         24          0          0   10782440          0          0  IR-PCI-MSI-edge      eth2-tx-2
  72:   17034513          0          0          0          0          0  IR-PCI-MSI-edge      ahci
  73:          1          0          0          0          0          0  IR-PCI-MSI-edge      isci-msix
  74:          0          0          0          0          0          0  IR-PCI-MSI-edge      isci-msix
  75:          7          0          0          0          0          0  IR-PCI-MSI-edge      eth3
  76:         25          0          0         11         35   27880083  IR-PCI-MSI-edge      eth3-rx-0
  77:    9845213          0          0          0          0          0  IR-PCI-MSI-edge      eth3-rx-1
  78:         22    9845071          0          0          0          0  IR-PCI-MSI-edge      eth3-rx-2
  79:    9825399          0          0          0          0          0  IR-PCI-MSI-edge      eth3-tx-0
  80:         23          0    9825377          0          0          0  IR-PCI-MSI-edge      eth3-tx-1
  81:    9825424          0          0          0          0          0  IR-PCI-MSI-edge      eth3-tx-2
  82:          3          0          0          0          0          0  IR-PCI-MSI-edge      eth0
  83: 1383727826          0          0          0          0          0  IR-PCI-MSI-edge      eth0-rx-0
  84:         55          0         71        155 1302104857          0  IR-PCI-MSI-edge      eth0-rx-1
  85: 1324395997          0          0          0          0          0  IR-PCI-MSI-edge      eth0-rx-2
  86: 1830013044        164          0          0          0          0  IR-PCI-MSI-edge      eth0-tx-0
  87:        262         75          0          0          0 1928280549  IR-PCI-MSI-edge      eth0-tx-1
  88: 1883840698          0          0          0          0          0  IR-PCI-MSI-edge      eth0-tx-2
  89:          3          0          0          0          0          0  IR-PCI-MSI-edge      eth1
  90:         44          0   62434654          0          0          0  IR-PCI-MSI-edge      eth1-rx-0
  91:    9853611          0          0          0          0          0  IR-PCI-MSI-edge      eth1-rx-1
  92:    9840908          0          0          0          0          0  IR-PCI-MSI-edge      eth1-rx-2
  93:         21    9825401          0          0          0          0  IR-PCI-MSI-edge      eth1-tx-0
  94:    9825431          0          0          0          0          0  IR-PCI-MSI-edge      eth1-tx-1
  95:    9825440          0          0          0          0          0  IR-PCI-MSI-edge      eth1-tx-2

上記の場合パラメータはこんな感じです。CPUはXeon E5-1650v2なので6コアを意識しています。

options igb IntMode=2,2,2,2 RSS=3,3,3,3 QueuePairs=0,0,0,0

さて脱線しましたが、ついでにeth0とeth1でflow entryを使い切るように設定します。
国内で有名なコピペ設定でもいいと思いますが、ここは海外含めて事例を調べてこう設定してみました。
この部分に関してはまだカーネルの実装までは追っていませんので確証がもてません。

echo "f" > /sys/class/net/eth0/queues/rx-0/rps_cpus
echo 16384 > /sys/class/net/eth0/queues/rx-0/rps_flow_cnt
echo "f" > /sys/class/net/eth1/queues/rx-0/rps_cpus
echo 16384 > /sys/class/net/eth1/queues/rx-0/rps_flow_cnt
echo 32768 > /proc/sys/net/core/rps_sock_flow_entries

カーネルをアップグレード

公式のコミュニティ版だとカーネルが古いためVyatta4People.Org版(?)にアップグレードして使っています。
設定はそのままでコマンド一発でアップグレードすることができます

vyatta@rt4:~$ add system image http://ftp.het.net/iso/vyatta/vc6.7/images/vyatta-livecd-redding-20130712-amd64.iso

 CoDel等、最近になって野心的に実装されたおいしい機能を試すためです。

conntrack tableを正確に設定する

ここがIPマスカレードの一番の肝です。
まとめエントリーはこちらになります。

メモリ16Gで以下の設定で運用しています。

 expect-table-size 196608
 hash-size 23576
 table-size 196608

実メモリから逆算することにより限界値が明確になります。
expect-table-sizeは自社の使い方だとほぼ使われることがありませんが、メモリも余裕があるので保険で同じ値をいれてあります。

conntrackタイムアウトを短くする

conntrack tableは実メモリの制限を受けるため、不要なものはさっさとconntrack tableから削除してしまします。

 timeout {
     icmp 3
     other 600
     tcp {
         close 10
         close-wait 1
         established 10
         fin-wait 10
         last-ack 30
         syn-recv 60
         syn-sent 5
         time-wait 3
     }
     udp {
         other 30
         stream 10
     }
 }

vyattaに限らずconntrack tableは特定の環境でかなりの頻度で溢れます。
少ないデフォルト値を増やして対処できればいいですが、消えないのにタイムアウトが長めになっている場合もあります。
どう対処したかは結構前にかいたこの辺のテキストにまとまっています。

愚痴

分裂したようなんですがどうなんでしょうか…。

次回はたぶんLVSのチューニングです。

 

コメントを残す

メールアドレスが公開されることはありません。


*