HAProxyのパフォーマンスチューニングをやったメモ(CPS編)

by Matt J Newman



HAProxyを使う上で、どうやったらパフォーマンスが上がるのかを模索するメモ。
基本的に、万能なパフォーマンスチューニングはないので、今回はCPS(Connections per Second)のパフォーマンスを上げることに焦点を絞ります。CPS(Connections per Second)は、ロードバランサの性能指標の1つとなっている数値です。


あくまで軽くやってみた過程のメモ書きみたいなものなので、まとまりもなく、まだまだ改善の余地があるとは思いますが、何かの参考にしてください。

前提

HAProxyを動かすのに使用した環境は以下の通り。

  • Server: DELL PowerEdge R420
  • CPU: Intel Xeon E5-2430L @ 2.00GHz * 2
  • Memory: 96GB
  • Ethernet controller: Intel Corporation Ethernet 10G 2P X520 Adapter (rev 01)
    • Intel(R) 10 Gigabit PCI Express Network Driver - version 3.18.7
  • OS: CentOS 6.4 (Linux version 2.6.32-358.23.2.el6.x86_64)
  • Software: HAProxy 1.5-dev19


初期段階のHAProxyのConfig(option)は、だいたい以下のような感じ。

global
    log         127.0.0.1 local2 notice
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     131072
    user        nobody
    group       nobody
    daemon
    nbproc      1

defaults
    mode                    tcp
    log                     global
    retries                 3
    timeout queue           1m
    timeout connect         10s
    timeout client          30s
    timeout server          30s
    #timeout http-keep-alive 2s
    timeout check           10s
    maxconn                 120000

frontend hoge
    bind        *:80
    mode        tcp
    ・・・・・

backend fuga
    mode        tcp
    balance     roundrobin
    fullconn    32768
    ・・・・・

↑の前提となるデフォルト環境でまず計測

cps: 27000

haproxyの1プロセスで詰まってる感じ。

nbprocの調整

haproxy.cfgでプロセスを増やすよう以下を設定。

nbproc      2

cps: 36000

CPSが収束しない。35000〜40000付近をうろうろする感じ。

nbprocの調整 その2

haproxy.cfgで以下を設定

nbproc      4

cps: 52000

とにかくsoftirqの数が多い。TIME_WAITの数がかなり増えてきた。"tcp_max_tw_buckets"の値近く。

TIME_WAITコネクションを減らす

試しに、kernelをリビルドして、TIME_WAITコネクションの保持を短く5秒にしてみる。

cps: 47000

効果ないのでkernelを元のやつに戻す。

sysctl.confに以下のパラメータ入れて反映

根拠レスだが、以下のような感じでぶっこんでみる。

net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
net.core.netdev_max_backlog = 262144
net.core.somaxconn = 32768

net.ipv4.tcp_rmem = 4096 87380 134217728
net.ipv4.tcp_wmem = 4096 65536 134217728
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_no_metrics_save = 1
net.ipv4.tcp_moderate_rcvbuf = 1
net.ipv4.tcp_rfc1337 = 1

net.ipv4.ip_local_port_range = 1024 65535

cps: 52000

これも、あんまり効果がなさそうなので、とりあえず設定を元に戻す。

RSSまわりの調整(MQ無効)

とにかく単一のcoreでsoftirqが高いため、ここに着手。まずは、RSSまわりを調整してみる。
"/proc/interrupts"を見ていると、24core分でRSSキューが分散されているが、大きな偏りが見られるので、1つずつ切り分けてみる。
まずはNICドライバでMQを無効にする。ixgbeモジュールに以下を設定。

options ixgbe MQ=0,0

cps: 52500

2coreでsoftirqが100%はりつき。CPSは収束しない。49000〜53000あたりをウロウロ。

RPS/RFSを設定してみる

MQを無効にしたまま、以下のような感じで4CPU core分使う感じでRPS分散。

echo "f" > /sys/class/net/bond0.88/queues/rx-0/rps_cpus
echo 32768 > /sys/class/net/bond0.88/queues/rx-0/rps_flow_cnt
echo 65536 > /proc/sys/net/core/rps_sock_flow_entries

cps: 52500

あまり結果が変わらないので、設定を元に戻す。

RSSの数を制御してみる

まずは2つずつで。ixgbeモジュールに以下を設定。

options ixgbe MQ=1,1 RSS=2,2

MQ有効にして、RSSキューを2+2に。

cps: 35000

パフォーマンス落ちた。
"/proc/interrupts"をみていると、キューが1coreに偏っているので、次はこれを手動で分散させてみることにする。

RSSキューを手動で各CPUに分散

# numactl --hardware
available: 2 nodes (0-1)
node 0 cpus: 0 2 4 6 8 10 12 14 16 18 20 22
node 0 size: 49106 MB
node 0 free: 47674 MB
node 1 cpus: 1 3 5 7 9 11 13 15 17 19 21 23
node 1 size: 49152 MB
node 1 free: 47999 MB
node distances:
node   0   1
  0:  10  20
  1:  20  10

NUMAなのでチェック。↑のような感じなので、手動で1個のCPUにRSSキューを分散させる

# /etc/init.d/irqbalance stop
# echo "2" > /proc/irq/135/smp_affinity
# echo "8" > /proc/irq/136/smp_affinity
# echo "20" > /proc/irq/138/smp_affinity
# echo "80" > /proc/irq/139/smp_affinity

cps: 52500

ふむ。でも、52500で収束して安定するようになった。次はNUMAを意識しないとどうなるか。

RSSキューを手動で各CPUに分散 その2

次に、手動でキューを2個のCPUに分散させる。

# echo "2" > /proc/irq/135/smp_affinity
# echo "4" > /proc/irq/136/smp_affinity
# echo "8" > /proc/irq/138/smp_affinity
# echo "10" > /proc/irq/139/smp_affinity

cps: 47000

やはりダメ。設定を元に戻す。

nbprocの調整 その3

haproxyのプロセスも張り付いているのでhaproxyのプロセス数を8まであげてみる

nbproc      8

cps: 53000

若干改善するも伸びず。オーバーヘッドの方が大きいのだろうか。

NICのオフロード

このへんでNICをオフロードしてみる。

# ethtool -K p2p1 rx off tx off sg off tso off gso off lro off rxvlan off txvlan off rxhash off
# ethtool -K p2p2 rx off tx off sg off tso off gso off lro off rxvlan off txvlan off rxhash off
# ethtool -K bond0 rx off tx off sg off tso off gso off lro off rxvlan off txvlan off rxhash off
# ethtool -K bond0.88 tso off gso off lro off rxvlan off txvlan off rxhash off

cps: 53000

たいして変化は無く。設定を元に戻す。

RSSの数を制御してみる その2

RSSキューをさらに増殖させる。ixgbeモジュールに以下を設定。

options ixgbe MQ=1,1 RSS=4,4

さっきの結果を踏まえて、割り当たるCPUマップを手動で分散させる。

# /etc/init.d/irqbalance stop
# echo "2" > /proc/irq/135/smp_affinity
# echo "8" > /proc/irq/136/smp_affinity
# echo "20" > /proc/irq/137/smp_affinity
# echo "80" > /proc/irq/138/smp_affinity
# echo "200" > /proc/irq/140/smp_affinity
# echo "800" > /proc/irq/141/smp_affinity
# echo "2000" > /proc/irq/142/smp_affinity
# echo "8000" > /proc/irq/143/smp_affinity

cps: 50000

結果がイマイチなので、設定を元に戻す。

nbprocの調整 その4

haproxyのプロセス数を6にしてみる

nbproc      6

cps: 55000

少しパフォーマンスアップ。

tune.bufsize増やす

たぶん関係ないけど、haproxy.cfgに設定。

tune.bufsize    131072

cps: 55000

当然変わらず。設定を元に戻す。

tune.maxacceptを調整

こちらも試しに設定変えてみる。haproxy.cfgに設定。

tune.maxaccept  -1

cps: 50000

悪化。設定を元に戻す。

InterruptThrottleRateの調整

割り込み関連というところで、このパラメータもOFFってみる。

options ixgbe MQ=1,1 RSS=2,2 InterruptThrottleRate=0,0
# /etc/init.d/irqbalance stop
# echo "2" > /proc/irq/135/smp_affinity
# echo "8" > /proc/irq/136/smp_affinity
# echo "20" > /proc/irq/138/smp_affinity
# echo "80" > /proc/irq/139/smp_affinity

cps: 53000

これも悪化。設定を元に戻す。

今回の結論

軽くやってみた感じ、今回の環境を前提とした場合、CPS優先でHAProxyをチューニングする際は、、、

options ixgbe MQ=1,1 RSS=2,2

ixgbeモジュールでMQ有効、RSSを2+2で。

# /etc/init.d/irqbalance stop
# echo "2" > /proc/irq/135/smp_affinity
# echo "8" > /proc/irq/136/smp_affinity
# echo "20" > /proc/irq/138/smp_affinity
# echo "80" > /proc/irq/139/smp_affinity

RSSキュー4つを、NUMAを考慮した上で、手動で各CPUコアに分散させ。
(と書きつつ、手動で分散させる必要性はあまり感じていないし、要らないかも。)

nbproc      6

HAProxyのプロセスを6つで稼動させる。


っていうパターンが、今回利用した環境では、CPS観点でパフォーマンスが出せる結果となった。
もちろん、使用する環境によってリソースの大小や使い方/使われ方が異なるので、↑のパラメータではなく、環境によって色々と試しながら調整する必要があります。

正直、思いつきで手当たり次第やってみた感が強いので、1つずつボトルネックを見極めて、潰していけば、もうちょっと改善できると思う。この辺は冬休みの宿題かなーと思っている。


ということで、今日はこの辺まで。それでは!=͟͟͞͞(๑•̀=͟͟͞͞(๑•̀д•́=͟͟͞͞(๑•̀д•́๑)=͟͟͞͞(๑•̀д•́


Unixシステムパフォーマンスチューニング 第2版

Unixシステムパフォーマンスチューニング 第2版

  • 作者: ジャン‐パオロ・D.ムズメキ,マイクルキダス,Gian‐Paolo D. Musumeci,Mike Loukides,砂原秀樹,高橋敏明,岡島順治郎
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2003/10
  • メディア: 単行本
  • 購入: 1人 クリック: 30回
  • この商品を含むブログ (10件) を見る

[24時間365日] サーバ/インフラを支える技術 ?スケーラビリティ、ハイパフォーマンス、省力運用 (WEB+DB PRESS plusシリーズ)

[24時間365日] サーバ/インフラを支える技術 ?スケーラビリティ、ハイパフォーマンス、省力運用 (WEB+DB PRESS plusシリーズ)

  • 作者: 安井真伸,横川和哉,ひろせまさあき,伊藤直也,田中慎司,勝見祐己
  • 出版社/メーカー: 技術評論社
  • 発売日: 2008/08/07
  • メディア: 単行本(ソフトカバー)
  • 購入: 133人 クリック: 2,270回
  • この商品を含むブログ (288件) を見る