概要
Apacheの設定を手元のVMマシンでごにょごにょしていて、
ふと性能のキャップを外すことはあるけど、意図的にキャップをかけたらApacheとOSから見た時のnetstat状態ってどんな挙動になるのだろうと思ったことをつらつらとチラシの裏レベルで書いていきます。
また、数カ月前に試したことだったのでちょっとうろ覚えのところもあります。
なので、多分一般的な人はほぼ意味がない記事になるかと思います。
また、サーバのセットアップ手順は割愛しています。
すいません、すいません、すいません。
検証概要
静的ファイルをGETするだけの単純な負荷試験を実施。
- 受け付ける秒間リクエストは50rps
- ファイルサイズは1KB,2KB,4KB,8KB,16KBの5種類
- 上記の状態でfluent-plugin-dstatで情報をElasticSearchに突っ込んでKibanaで可視化してみる
環境
- サーバ:CentOS 6.6 x86_64(VMwarePlayer上)
- Apache:apache 2.2系
- クライアント:Apache Bench, JMeter
検証1回目
設定値
<IfModule prefork.c>
StartServers 50
MinSpareServers 50
MaxSpareServers 50
MaxClients 50
MaxRequestsPerChild 1
</IfModule>
予想
多分この設定で50rpsになるはず。。。
結果
ファイルサイズ:1k 並列度:180 アクセス数:1000
cmd:ab -n 1000 -c 180 web01t.local/1k.txt
ファイルサイズ:2k 並列度:180 アクセス数:1000
cmd:ab -n 1000 -c 180 web01t.local/2k.txt
ファイルサイズ:4k 並列度:180 アクセス数:1000
cmd:ab -n 1000 -c 180 web01t.local/4k.txt
ファイルサイズ:8k 並列度:180 アクセス数:1000
cmd:ab -n 1000 -c 180 web01t.local/8k.txt
ファイルサイズ:16k 並列度:180 アクセス数:1000
cmd:ab -n 1000 -c 180 web01t.local/16k.txt
検証1回目の結果
なんかよくわからないけど32rpsになってしまう。
ではMaxRequestsPerChildを倍に増やすとどうなる?
検証2回目
設定値
<IfModule prefork.c>
StartServers 50
MinSpareServers 50
MaxSpareServers 50
MaxClients 50
MaxRequestsPerChild 2
</IfModule>
ファイルサイズ:16k 並列度:180 アクセス数:1000
cmd:ab -n 1000 -c 180 web01t.local/16k.txt
検証2回目の結果
綺麗に32の等倍である64rpsになった!
ということはコードの中でプロセス数のキャップがかかっているっぽい気がする。
forkするのはメモリやCPUコストかかるから、
普通はMaxRequestsPerChildを増やして子プロセスが死ぬまでの回数を調整しましょうということなのかな。。。?
JMeterで負荷試験してみた
Apache Benchだと並列処理が困難なので。。。
設定値
<IfModule prefork.c>
StartServers 50
MinSpareServers 50
MaxSpareServers 50
MaxClients 50
MaxRequestsPerChild 2
</IfModule>
グラフ説明
- 上段グラフの緑色:Apacheの秒間アクセス数
- 下段グラフの薄紫:netstatのtime_wait
- 下段グラフの濃い紫:netstatのsyn_recv
- 下段グラフの緑:netstatのestablish
10rps(time:60 , thread:600)
30rps(time:60 , thread:1800)
60rps(time:60 , thread:3600)
120rps(time:60 , thread:7200)
180rps(time:60 , thread:10800)
JMeterを使った検証結果
並列度が60くらいまではおおよそ問題なく捌けていそう。
倍の120にした途端タイムアウトが頻発するようになった。
グラフがガタガタなのはホスト機のCPUリソースがカツカツすぎてフリーズしかけてたからだと思います。。。
ネットワーク状態は?
並列度が60を超えた当たりからSYN_RECVが滞留し始めた。
netstat -anとかでみるとどうやら詰まり始めたらSYN_RECVの数が増加しているようだった。
並列度を上げてSYN_RECVの数がスケールしていくのは、
ESTABLISHに移ろうとしてもプロセスがリクエストを捌ききれなくて状態遷移できないためと予想。
参考
余談
JMeterで120rps負荷試験をかけたあたりからdstatで「missed 2 ticks」という表示が出て情報が欠けるようになった。
こんな表示あったんですね。。。!
MaxClientsが33以上はスルーされてしまった件
少しだけコードの中を覗いてみました。
MAX_SPAWN_RATEというのがあるようです。
時間があるときに値を修正してリコンパイルして試してみたいと思います!
115 /*
116 * idle_spawn_rate is the number of children that will be spawned on the
117 * next maintenance cycle if there aren't enough idle servers. It is
118 * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by
119 * without the need to spawn.
120 */
121 int idle_spawn_rate;
122 #ifndef MAX_SPAWN_RATE
123 #define MAX_SPAWN_RATE (32)
124 #endif