マルチキュー ネットワークインターフェース(修正)

 

最近のNICは複数の送信用受信用のキューが用意されており、

そのキューはそれぞれハードウェアのIRQに関連付けられているので複数のCPUに処理を分散させることができます。

ただ、

複数のキューはあっても受信用のキューだけしか用意されていないNICではIRQでの分散が出来ていないように見えます。

有名どころのNICでは

BroadComの[bnx2][tg3]系のドライバのnicは受信用だけ複数のキューが用意されています。

一方でIntelの[igb][ixgbe]系のドライバのnicは送受信用に複数のキューが用意されています。

/proc/interruptsを見ると確認できます。

私の環境での例です。

em1-0
em1-1
em1-2
em1-3
em1-4

となっていまして、このbroadcomのnicは受信用のキューしかないように見えます。

p6p1-TxRx-0
p6p1-TxRx-1
p6p1-TxRx-2
p6p1-TxRx-3
p6p1-TxRx-4
p6p1-TxRx-5
p6p1-TxRx-6
p6p1-TxRx-7
p6p1-TxRx-8
p6p1-TxRx-9
p6p1-TxRx-10
p6p1-TxRx-11

一方でintelのnicのほうはこのようになっていて送受信用のキューがあり、それが12個見えています。

TxRxとなっているものが送受信対応と考えればいいのかなと思います。

これが原因かはわからないないのですがCPUの使い方に違いがありましたので紹介します。

/proc/interruptsで確認できます。

interrupts

p6p1のnicは均等に複数のcpuに処理が分散されていますがem1のnicはcpu0に偏っています。

次に実際に負荷をかけてCPUの状態を確認します。

まずはintelのnic経由で負荷をかけます。

top – 18:15:53 up 6:09, 2 users, load average: 1.99, 1.97, 1.91
Tasks: 318 total, 1 running, 317 sleeping, 0 stopped, 0 zombie
Cpu0 : 20.8%us, 29.5%sy, 0.0%ni, 42.4%id, 0.0%wa, 0.0%hi, 7.2%si, 0.0%st
Cpu1 : 16.2%us, 23.7%sy, 0.0%ni, 53.8%id, 0.0%wa, 0.0%hi, 6.4%si, 0.0%st
Cpu2 : 11.5%us, 18.3%sy, 0.0%ni, 65.6%id, 0.0%wa, 0.0%hi, 4.7%si, 0.0%st
Cpu3 : 17.6%us, 24.8%sy, 0.0%ni, 49.6%id, 0.0%wa, 0.4%hi, 7.6%si, 0.0%st
Cpu4 : 11.2%us, 14.1%sy, 0.0%ni, 70.4%id, 0.0%wa, 0.4%hi, 4.0%si, 0.0%st
Cpu5 : 3.7%us, 5.8%sy, 0.0%ni, 89.1%id, 0.0%wa, 0.0%hi, 1.4%si, 0.0%st
Cpu6 : 8.7%us, 12.6%sy, 0.0%ni, 75.2%id, 0.0%wa, 0.0%hi, 3.5%si, 0.0%st
Cpu7 : 3.7%us, 5.4%sy, 0.0%ni, 89.8%id, 0.0%wa, 0.0%hi, 1.0%si, 0.0%st
Cpu8 : 0.7%us, 0.3%sy, 0.0%ni, 99.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Cpu9 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Cpu10 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Cpu11 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 32829724k total, 2468428k used, 30361296k free, 131044k buffers
Swap: 524280k total, 0k used, 524280k free, 1373528k cached

黄色文字部分のシステムのCPU利用率をみていただくとわかるのですが均等に分散しているように見えます。

次はbroadcomです。

top – 18:17:43 up 6:11, 2 users, load average: 1.99, 1.97, 1.91
Tasks: 318 total, 1 running, 317 sleeping, 0 stopped, 0 zombie
Cpu0 : 21.6%us, 34.0%sy, 0.0%ni, 1.0%id, 0.0%wa, 0.0%hi, 43.3%si, 0.0%st
Cpu1 : 2.0%us, 4.0%sy, 0.0%ni, 94.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Cpu2 : 1.0%us, 2.0%sy, 0.0%ni, 97.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Cpu3 : 2.0%us, 3.0%sy, 0.0%ni, 95.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Cpu4 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Cpu5 : 1.0%us, 0.0%sy, 0.0%ni, 99.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Cpu6 : 34.0%us, 46.8%sy, 0.0%ni, 19.1%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Cpu7 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Cpu8 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Cpu9 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Cpu10 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Cpu11 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st

一目瞭然ですね。赤と黄色を見るとCPU0へ負荷が偏っているのがわかると思います。

これはmemcachedに対してmemslapでおもいっきり負荷をかけた結果なのですが、
サーバのパフォーマンスを引き出せぬまま限界を迎えてしまった例です。

複数のmemcachedを立ち上げてサーバ内でスケールアウトは可能なのですが、
できれば、サーバ内でスケールアップのほうが運用しやすいのではないでしょうか。

そもそも、最近のNICは複数のキューがあるのでそのキューで分散できると思いこんでいたんですが、

よくよくみてみると使えてないんだなと。

とりあえずはmemcachedなどのシングルプロセスで動作するアプリケーションでサーバ内でスケールアップさせるためにはintelのnicを利用する形で対応するのが手間がかからず良いように思います。

OS:CentOS 6.4
カーネル:2.6.32-358.el6.x86_64

オンボードNIC:Broadcom BCM5720 Gigabit Ethernet PCIe
driver: tg3
version: 3.129d broadcom社から2013-08-30時点で最新をインストールしています。
firmware-version: FFV7.4.8 bc 5720-v1.30

PCINIC:Intel 10-Gigabit X540-AT2
driver: ixgbe
version: 3.9.15-k
firmware-version: 0x800002ee
今回調査していたサーバは上記構成です。

irqbalanceを起動時にonにしておけばintelのnicであれば綺麗に分散してます。

起動時にirqbalanceをonにしてしまえば、後でirqbalanceを止めてもきれいに分散したままになります。

ただ、起動時にirqbalanceをoffで起動するとintelのnicでも分散しないので注意です。

broadcomはirqbalanceを使っても分散しませんので、

とりあえずはintelのnicを使うことで対応するのが簡単で良いかもしれません。

あと、補足として

RPSを設定することで複数のCPUに分散出来ない場合であっても

複数のキューを有効活用することによってCPU負荷を改善させることができるようです。

echo "f" > /sys/class/net/eth0/queues/rx-0/rps_cpus

標準ではdisabledだそうです。

RFSを設定することでも改善はできるようなのですが私の環境では変化がなかったので採用していません。

この設定により1%のidleが15%のidleへと変化しました。

これにより改善はするのですが劇的な改善というほどのものではないかなという印象です。

完璧に裏が取れているというわけではありませんので、

間違いを指摘していただける方、補足いただける方はコメントいただけると助かります。

もしかしたらBroadcomのNICでもシングルプロセスでもきれいに分散できるかもしれませんので、

情報をお持ちの方宜しくお願い致します。

こちらの記事も参照ください

hardware, linux

Posted by Akira


PAGE TOP