linux, 小ネタ

 

ほんとに小ネタです。すみません。

先ほどpingを打ちながら、ふと、こんなふうに使っていたなあと思ったので徒然なるままに。

pingに日付を付けたい時はこれ

$ ping localhost | perl -pe 'use POSIX;$x=POSIX::strftime("%Y/%m/%d %H:%M:%S ", localtime()); s/^/$x/;'

 

localhostへのpingはこれ

$ ping 0

 

pingの途中で統計が見たいときは[CTRL]を押しながら[¥]

$ ping  0

PING 0 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.014 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.024 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.045 ms
64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.033 ms
64 bytes from 127.0.0.1: icmp_seq=5 ttl=64 time=0.032 ms
5/5 packets, 0% loss, min/avg/ewma/max = 0.014/0.029/0.022/0.045 ms
64 bytes from 127.0.0.1: icmp_seq=6 ttl=64 time=0.029 ms
64 bytes from 127.0.0.1: icmp_seq=7 ttl=64 time=0.018 ms
64 bytes from 127.0.0.1: icmp_seq=8 ttl=64 time=0.013 ms
64 bytes from 127.0.0.1: icmp_seq=9 ttl=64 time=0.017 ms
64 bytes from 127.0.0.1: icmp_seq=10 ttl=64 time=0.017 ms
10/10 packets, 0% loss, min/avg/ewma/max = 0.013/0.024/0.020/0.045 ms
64 bytes from 127.0.0.1: icmp_seq=11 ttl=64 time=0.027 ms
64 bytes from 127.0.0.1: icmp_seq=12 ttl=64 time=0.018 ms
12/12 packets, 0% loss, min/avg/ewma/max = 0.013/0.023/0.021/0.045 ms
64 bytes from 127.0.0.1: icmp_seq=13 ttl=64 time=0.035 ms
64 bytes from 127.0.0.1: icmp_seq=14 ttl=64 time=0.019 ms
64 bytes from 127.0.0.1: icmp_seq=15 ttl=64 time=0.018 ms
64 bytes from 127.0.0.1: icmp_seq=16 ttl=64 time=0.016 ms
16/16 packets, 0% loss, min/avg/ewma/max = 0.013/0.023/0.021/0.045 ms
64 bytes from 127.0.0.1: icmp_seq=17 ttl=64 time=0.018 ms
64 bytes from 127.0.0.1: icmp_seq=18 ttl=64 time=0.016 ms
^C
— 0 ping statistics —
18 packets transmitted, 18 received, 0% packet loss, time 17429ms
rtt min/avg/max/mdev = 0.013/0.022/0.045/0.010 ms

hardware, linux

 

前回の記事でBroadcomのnicでは分散ができないのではないかとお伝えしましたが、

解決方法が見つかりましたのでご連絡します。

設定前の/proc/interruptsです。

interrupts

em1はcpu0に偏っています。

p6p1は問題なく分散されています。

早速設定してみます。

IRQごとに利用できるCPUを指定してあげると分散するようになるようです。

コマンドはこちらです。108、109、110、111は/proc/interruptsを見れば確認できます。

echo 1 > /proc/irq/108/smp_affinity
echo 2 > /proc/irq/109/smp_affinity
echo 4 > /proc/irq/110/smp_affinity
echo 8 > /proc/irq/111/smp_affinity

cpuの番号はこのように指定します。
参考ページ:https://cs.uwaterloo.ca/~brecht/servers/apic/SMP-affinity.txt

              Binary         Hex 
    CPU 0    00000001         1 
    CPU 1    00000010         2
    CPU 2    00000100         4
    CPU 3    00001000         8
    CPU 0    00010000         10 
    CPU 5    00100000         20
    CPU 6    01000000         40
    CPU 7    10000000         80

このコマンド入力後、memslapで負荷をかけてみた結果が以下です。

broadcomkaizen

分散ができるようになったようです。

これでintelでもbroadcomでもコントロール可能となりました。

あとは起動時に読み込まれるように下記で設定しておきます。
※smp_affinityは/proc/sys以外のディレクトリで管理されているのでsysctl.confでは設定はできないようです。

vi /etc/rc.d/rc.local

いずれにしても多くのコアを搭載するようになった現在、キューも多く割り当てられているほうが分散させるにはよさそうです。

linux, 小ネタ

 

PCIのクワッドポートを利用するときなんですが、

どっちがeth0なんだろうと今だに悩まされるときがあります。

そんな時の私の味方
ethtool -p eth0
指定したインターフェースポートでリンクが点灯しお知らせしてくれます。

ケーブルが差さってなくても大丈夫!(^^)v

linux

 

みんなご存知の方ばかりだと思いますので、

今回は共有するというよりは

最近、weighttpを初めて使ってみた自分に対する備忘録です。

マルチコア時代のウェブサーバの優等生「g-wan」のベンチを取るためにweighttpを知りました。

abやhttperfなどではg-wanを泣かすことができなかったのでweighttpで泣かせてみようと。

結果、泣かせることはできませんでしたが。^^;

開発者様に敬意を!

さて、実際にインストールしてコマンドを試してみます。

私もいろんなサイトで紹介されていたものを参考にしていますので、

詳細は他のサイトでご確認いただいたほうがいいかと思います。

gwanをインストールしたホスト自身にインストールしてlocalhost宛でベンチを取ります。

このベンチでは秒間のリクエスト処理数を確認してもらうのがいいかと思います。

参考までにhttperfやabの結果も載せておきます。

環境

CentOS release 6.4 (Final)
2.6.32-358.el6.x86_64
Intel Xeon E5-2640@2.50GHz * 2個
Memory 32GB
Program : G-WAN (freeware)
Platforms: Linux 32-bit and 64-bit

■weighttp

インストール

yum install -y --enablerepo=epel libev libev-devel
wget http://github.com/lighttpd/weighttp/zipball/master
unzip master
cd lighttpd-weighttp-c14ac58/
vi src/weighttp.h → ev.hのInludePathの修正
gcc -g2 -O2 src/*.c -o weighttp -lev -lpthread
cp ./weighttp /usr/local/bin

コマンド例

weighttp -n 100000 -c 300 -t 4 -k http://localhost:8080/index.html
weighttp - a lightweight and simple webserver benchmarking tool

starting benchmark...
spawning thread #1: 75 concurrent requests, 25000 total requests
spawning thread #2: 75 concurrent requests, 25000 total requests
spawning thread #3: 75 concurrent requests, 25000 total requests
spawning thread #4: 75 concurrent requests, 25000 total requests
progress: 10% done
progress: 20% done
progress: 30% done
progress: 40% done
progress: 50% done
progress: 60% done
progress: 70% done
progress: 80% done
progress: 90% done
progress: 100% done

finished in 0 sec, 305 millisec and 510 microsec, 327321 req/s, 2389702 kbyte/s
requests: 100000 total, 100000 started, 100000 done, 100000 succeeded, 0 failed, 0 errored
status codes: 100000 2xx, 0 3xx, 0 4xx, 0 5xx
traffic: 747600000 bytes total, 25600000 bytes http, 722000000 bytes data

■httperf

インストール

rpm -ivh http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm
yum --enablerepo=rpmforge install httperf

コマンド例

httperf --server=127.0.0.1 --port=8080 --num-call=200 --num-conns=50 --hog --uri=/test.html
httperf --hog --client=0/1 --server=127.0.0.1 --port=8080 --uri=/test.html --send-buffer=4096 --recv-buffer=16384 --num-conns=50 --num-calls=200
httperf: warning: open file limit > FD_SETSIZE; limiting max. # of open files to FD_SETSIZE
Maximum connect burst length: 1

Total: connections 50 requests 10000 replies 10000 test-duration 0.198 s

Connection rate: 252.7 conn/s (4.0 ms/conn, <=1 concurrent connections)
Connection time [ms]: min 3.9 avg 4.0 max 4.4 median 3.5 stddev 0.1
Connection time [ms]: connect 0.1
Connection length [replies/conn]: 200.000

Request rate: 50540.8 req/s (0.0 ms/req)
Request size [B]: 71.0

Reply rate [replies/s]: min 0.0 avg 0.0 max 0.0 stddev 0.0 (0 samples)
Reply time [ms]: response 0.0 transfer 0.0
Reply size [B]: header 255.0 content 2213.0 footer 0.0 (total 2468.0)
Reply status: 1xx=0 2xx=10000 3xx=0 4xx=0 5xx=0

CPU time [s]: user 0.04 system 0.16 (user 18.7% system 80.9% total 99.5%)
Net I/O: 125315.5 KB/s (1026.6*10^6 bps)

Errors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0
Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0

■Apache Bench

インストール

yum install -y httpd-tools

コマンド例

ab -c 300 -n 10000 -k http://localhost:8080/test.html
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests

Server Software: G-WAN
Server Hostname: localhost
Server Port: 8080

Document Path: /test.html
Document Length: 2213 bytes

Concurrency Level: 300
Time taken for tests: 0.109 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Keep-Alive requests: 10000
Total transferred: 25226516 bytes
HTML transferred: 22402199 bytes
Requests per second: 91367.59 [#/sec] (mean)
Time per request: 3.283 [ms] (mean)
Time per request: 0.011 [ms] (mean, across all concurrent requests)
Transfer rate: 225086.52 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 1.2 0 10
Processing: 2 3 0.2 3 6
Waiting: 2 3 0.2 3 6
Total: 2 3 1.2 3 13

Percentage of the requests served within a certain time (ms)
50% 3
66% 3
75% 3
80% 3
90% 3
95% 3
98% 9
99% 11
100% 13 (longest request)

このような結果となりました。

ベンチツール 処理数/秒 web server application
weighttp 327321 G-WAN
httperf 50540 G-WAN
ab 91367 G-WAN

weighttpが圧倒的ですね。

ちなみに

g-wan、nginx、httpd、mighttpdのウェブサーバでもベンチを取ったので
比較も載せておきます。configはいじっていません。

web server application 処理数 ベンチツール
gwan 334944 req/s weighttp
nginx 111842 req/s  weighttp
httpd 19395 req/s  weighttp
mighttpd 107883 req/s  weighttp

各コマンドの詳細は下記です。

■g-wan

weighttp -n 100000 -c 300 -t 4 -k http://localhost:8080/index.html
weighttp - a lightweight and simple webserver benchmarking tool

starting benchmark...
spawning thread #1: 75 concurrent requests, 25000 total requests
spawning thread #2: 75 concurrent requests, 25000 total requests
spawning thread #3: 75 concurrent requests, 25000 total requests
spawning thread #4: 75 concurrent requests, 25000 total requests
progress: 10% done
progress: 20% done
progress: 30% done
progress: 40% done
progress: 50% done
progress: 60% done
progress: 70% done
progress: 80% done
progress: 90% done
progress: 100% done

finished in 0 sec, 298 millisec and 557 microsec, 334944 req/s, 2445420 kbyte/s
requests: 100000 total, 100000 started, 100000 done, 100000 succeeded, 0 failed, 0 errored
status codes: 100000 2xx, 0 3xx, 0 4xx, 0 5xx
traffic: 747619832 bytes total, 25601273 bytes http, 722018559 bytes data

■nginx

weighttp -n 100000 -c 300 -t 4 -k http://localhost:80/index.html
weighttp - a lightweight and simple webserver benchmarking tool

starting benchmark...
spawning thread #1: 75 concurrent requests, 25000 total requests
spawning thread #2: 75 concurrent requests, 25000 total requests
spawning thread #3: 75 concurrent requests, 25000 total requests
spawning thread #4: 75 concurrent requests, 25000 total requests
progress: 10% done
progress: 20% done
progress: 30% done
progress: 40% done
progress: 50% done
progress: 60% done
progress: 70% done
progress: 80% done
progress: 90% done
progress: 100% done

finished in 0 sec, 894 millisec and 116 microsec, 111842 req/s, 427595 kbyte/s
requests: 100000 total, 100000 started, 100000 done, 100000 succeeded, 0 failed, 0 errored
status codes: 100000 2xx, 0 3xx, 0 4xx, 0 5xx
traffic: 391495650 bytes total, 21695650 bytes http, 369800000 bytes data

■httpd

weighttp -n 100000 -c 300 -t 4 -k http://localhost:80/index.html
weighttp - a lightweight and simple webserver benchmarking tool

starting benchmark...
spawning thread #1: 75 concurrent requests, 25000 total requests
spawning thread #2: 75 concurrent requests, 25000 total requests
spawning thread #3: 75 concurrent requests, 25000 total requests
spawning thread #4: 75 concurrent requests, 25000 total requests
progress: 10% done
progress: 20% done
progress: 30% done
progress: 40% done
progress: 50% done
progress: 60% done
progress: 70% done
progress: 80% done
progress: 90% done
progress: 100% done

finished in 5 sec, 155 millisec and 910 microsec, 19395 req/s, 8769 kbyte/s
requests: 100000 total, 100000 started, 100000 done, 0 succeeded, 100000 failed, 0 errored
status codes: 0 2xx, 0 3xx, 100000 4xx, 0 5xx
traffic: 46300000 bytes total, 46300000 bytes http, 0 bytes data

■mighttpd

weighttp -n 100000 -c 300 -t 4 -k http://localhost:80/index.html
weighttp - a lightweight and simple webserver benchmarking tool

starting benchmark...
spawning thread #1: 75 concurrent requests, 25000 total requests
spawning thread #2: 75 concurrent requests, 25000 total requests
spawning thread #3: 75 concurrent requests, 25000 total requests
spawning thread #4: 75 concurrent requests, 25000 total requests
progress: 10% done
progress: 20% done
progress: 30% done
progress: 40% done
progress: 50% done
progress: 60% done
progress: 70% done
progress: 80% done
progress: 90% done
progress: 100% done

finished in 0 sec, 926 millisec and 927 microsec, 107883 req/s, 410146 kbyte/s
requests: 100000 total, 100000 started, 100000 done, 100000 succeeded, 0 failed, 0 errored
status codes: 100000 2xx, 0 3xx, 0 4xx, 0 5xx
traffic: 389300000 bytes total, 19500000 bytes http, 369800000 bytes data

hardware, linux

 

最近の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でもシングルプロセスでもきれいに分散できるかもしれませんので、

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

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

PAGE TOP