アプリケーションサーバに設定するプロセス/スレッド数の目安を探る


アプリケーションサーバを稼動させる上でCPU処理能力に元づいた
適切なプロセス/スレッド数を設定すると良いみたいなんだけど、
実際に設定する上で簡単な目安がわかればいいなと思い測定してみた。


## 測定環境

サーバ構成は、Dockerでそれぞれ以下のコンテナ用意します。(各サーバのCPUコア数は1)
- Nginx(Webサーバ)
- uwsgi(アプリケーションサーバ)
- MySQL(DBサーバ)
測定時は、DBサーバーと連動したPythonアプリケーションをuwsgiで起動させて
フロントサーバーのNginxのProxyから経由してuwsgiへアクセスする流れです。

測定確認で利用するツール
- Locust(負荷テストツール)
- vmstatコマンド(システムの負荷状況確認)
※ Locustについてはこちらを参考
http://qiita.com/yamionp/items/17ffcc465272ad83c490


## 測定内容

今回の測定確認はアプリケーションサーバの処理能力に絞っていて
以下のパターンで、uwsgi設定のプロセス/スレッド数を変更して測定しました。
- プロセス: 1, スレッド: 1
- プロセス: 1, スレッド: 2
- プロセス: 2, スレッド: 1
- プロセス: 2, スレッド: 2
- プロセス: 3, スレッド: 1

15クライアントで合計300リクエストになるまで同時にリクエストを行い、
その時の3秒毎のリクエスト処理状況とシステム負荷状況を測定結果として考えます。
リクエスト処理状況は、Locustの結果から確認し
システム負荷状況には、uwsgi(アプリケーションサーバ)に対してvmstatコマンドで確認します。


## Locustとvmstatの項目説明

**Locust**

| 項目      | 説明                                      |
|:---------:|:------------------------------------------|
| reqs      | 現在のリクエスト数                        |
| Avg       | 1リクエストの平均処理時間(ms)             |
| Min       | 1リクエストの最小処理時間(ms)             |
| Max       | 1リクエストの最大処理時間(ms)             |
| Median    | 1リクエストの処理時間の中央値             |
| req/s     | 1秒間に何リクエストを処理を実行できてるか |

**vmstat**

[procs]

| 項目 | 説明                                          |
|:----:|:----------------------------------------------|
| r    | 実行待ち状態のプロセスの数(ロードアベレージ)  |
| b    | 割り込み不可能なスリープ状態にあるプロセスの数|

[system]

| 項目 | 説明                              |
|:----:|:----------------------------------|
| in   | 秒あたりの割り込み回数            |
| cs   | 秒あたりのコンテキストスイッチ回数|

[cpu]

| 項目 | 説明                                                  |
|:----:|:------------------------------------------------------|
| us   | 実行に使用したユーザ時間(ユーザー側)                  |
| sy   | カーネルコードの実行に使用したシステム時間(カーネル側)|
| id   | CPUアイドル率                                         |
| wa   | IO待ちCPU利用率                                       |


## 測定結果

### プロセス: 1, スレッド: 1の場合
ロードアベレージは低く、1リクエストの処理時間、req/sも全体を通して悪くないです。
実際の運用ではCPUのリソースに余裕ができそうなので
もう少し高いパフォーマンス設定をやってみて良いかもです。

#### システム負荷状況(vmstat)
```
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 481572  67852 610612    0    0    23    20  271  526  8  2 90  0  0
 0  0      0 481560  67852 610644    0    0     0     0  226  447  9  1 90  0  0
 1  0      0 480256  67860 610936    0    0     0    31 1207 2606 81 11  9  0  0
 1  0      0 478552  67884 611288    0    0     0    45 1263 2815 89  8  3  0  0
 1  0      0 477824  67908 611696    0    0     0    49 1302 2915 84 13  3  0  0
 2  0      0 477420  67924 612060    0    0     0    24 1351 2995 86 11  3  0  0
 1  0      0 477080  67932 612440    0    0     0     9 1333 2942 85 13  3  0  0
 1  0      0 476280  67964 612720    0    0     0    40 1269 2803 87 10  3  0  0
 1  0      0 476124  67996 613084    0    0     0    44 1361 2989 83 13  3  0  0
 1  0      0 475596  68012 613512    0    0     0    27 1358 2996 85 12  3  0  0
 1  0      0 473144  68020 613888    0    0     0    12 1327 2934 83 14  3  0  0
 2  0      0 472648  68044 614192    0    0     0    39 1322 2958 86 11  3  0  0
 1  0      0 471964  68068 614596    0    0     0  1263 1299 2874 86 11  3  0  0
 1  0      0 471656  68084 614956    0    0     0    24 1349 2973 83 14  4  0  0
 1  0      0 471116  68092 615280    0    0     0    79 1351 2992 85 11  3  0  0
 1  0      0 470464  68116 615716    0    0     0    61 1356 3008 88  9  3  0  0
 0  0      0 470464  68116 615804    0    0     0     0  473 1026 25  3 72  0  0
 0  0      0 470480  68124 615804    0    0     0     7  108  194  0  0 100  0  0
 0  0      0 470604  68124 615804    0    0     0     0  102  192  0  0 100  0  0
```

#### リクエスト処理状況(Locust)
```
 Name                # reqs      # fails     Avg     Min     Max  |  Median   req/s
-----------------------------------------------------------------------------------------------------------
 GET /admin/             22     0(0.00%)     982     714    1111  |    1000    6.00
-----------------------------------------------------------------------------------------------------------
 GET /admin/             69     0(0.00%)     950     714    1111  |     970    7.43
-----------------------------------------------------------------------------------------------------------
 GET /admin/            115     0(0.00%)     944     714    1111  |     930    7.80
-----------------------------------------------------------------------------------------------------------
 GET /admin/            162     0(0.00%)     937     714    1111  |     920    7.70
-----------------------------------------------------------------------------------------------------------
 GET /admin/            210     0(0.00%)     925     714    1111  |     920    7.90
-----------------------------------------------------------------------------------------------------------
 GET /admin/            256     0(0.00%)     925     714    1111  |     920    7.90
-----------------------------------------------------------------------------------------------------------
 GET /admin/            289     0(0.00%)     920     714    1111  |     910    7.90
-----------------------------------------------------------------------------------------------------------
 GET /admin/            300     0(0.00%)     918     714    1111  |     910    7.80
-----------------------------------------------------------------------------------------------------------

リクエストの完了割合に応じた1リクエスト処理時間

 Name                # reqs    50%    66%    75%    80%    90%    95%    98%    99%   100%
-----------------------------------------------------------------------------------------------------------
 GET /admin/            300    910    930    960    980   1000   1000   1100   1100   1111
-----------------------------------------------------------------------------------------------------------
```


### プロセス: 1, スレッド: 2の場合
ロードアベレージは低いのですがcsが3000台と多くオーバーヘッドが高いので
1リクエストの処理時間が後半長くなってきてパフォーマンスが落ちてきてます。

#### システム負荷状況(vmstat)
```
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 464032  68324 616496    0    0    22    19  264  512  8  2 90  0  0
 0  0      0 464196  68324 616508    0    0     0     0  117  203  0  0 100  0  0
 1  0      0 461796  68332 616712    0    0     0     8  967 2085 64  9 27  0  0
 1  0      0 461472  68356 617068    0    0     0    31 1353 3020 86 11  3  0  0
 1  0      0 461016  68364 617492    0    0     0     9 1373 3081 87  9  3  0  0
 1  0      0 460632  68388 617856    0    0     0    33 1375 3108 86 11  3  0  0
 1  0      0 459980  68412 618228    0    0     0    45 1370 3089 88  9  3  0  0
 1  0      0 459608  68436 618536    0    0     0    40 1386 3097 87 10  3  0  0
 1  0      0 459112  68436 618960    0    0     0     0 1387 3095 89  8  3  0  0
 1  0      0 458796  68460 619228    0    0     0    41 1239 2708 84 13  2  0  0
 1  0      0 458320  68476 619608    0    0     0    24 1372 3081 87 10  3  0  0
 2  0      0 457944  68484 619964    0    0     0     9 1380 3074 84 13  3  0  0
 1  0      0 457348  68508 620384    0    0     0  1301 1362 3048 85 11  3  0  0
 1  0      0 456820  68532 620696    0    0     0    41 1379 3093 87 10  3  0  0
 1  0      0 456236  68548 621056    0    0     0    24 1362 2987 87 10  3  0  0
 1  0      0 455956  68556 621484    0    0     0     9 1381 3109 86 11  4  0  0
 0  0      0 455704  68580 621668    0    0     0    33  871 1909 50  5 45  0  0
 0  0      0 455704  68580 621668    0    0     0    19  101  186  0  0 100  0  0
 0  0      0 455720  68588 621668    0    0     0     7  103  195  0  0 100  0  0
```

#### リクエスト処理状況(Locust)
```
 Name                # reqs      # fails     Avg     Min     Max  |  Median   req/s
-----------------------------------------------------------------------------------------------------------
 GET /admin/             24     0(0.00%)     928     693    1042  |     940    6.00
-----------------------------------------------------------------------------------------------------------
 GET /admin/             71     0(0.00%)     902     693    1042  |     910    7.57
-----------------------------------------------------------------------------------------------------------
 GET /admin/            119     0(0.00%)     898     693    1042  |     900    7.90
-----------------------------------------------------------------------------------------------------------
 GET /admin/            164     0(0.00%)     922     693    1210  |     900    7.70
-----------------------------------------------------------------------------------------------------------
 GET /admin/            211     0(0.00%)     921     693    1210  |     910    7.60
-----------------------------------------------------------------------------------------------------------
 GET /admin/            258     0(0.00%)     916     693    1210  |     910    7.90
-----------------------------------------------------------------------------------------------------------
 GET /admin/            290     0(0.00%)     915     693    1210  |     910    7.90
-----------------------------------------------------------------------------------------------------------
 GET /admin/            300     0(0.00%)     914     693    1210  |     910    7.80
-----------------------------------------------------------------------------------------------------------

リクエストの完了割合に応じた1リクエスト処理時間
 Name                # reqs    50%    66%    75%    80%    90%    95%    98%    99%   100%
-----------------------------------------------------------------------------------------------------------
 GET /admin/            300    910    920    930    940    980   1100   1200   1200   1210
-----------------------------------------------------------------------------------------------------------
```


### プロセス: 2, スレッド: 1の場合
ロードアベレージは常時2ぐらいあるものの上り続けず一定のとこで維持でき、
csも低くく1リクエストの処理時間も短いのでreq/sが高いです。
今回の検証では一番パフォーマンスが良いです。

#### システム負荷状況(vmstat)
```
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 457296  66832 598732    0    0    25    19  268  520  8  2 90  0  0
 0  0      0 457424  66832 598744    0    0     0    49  130  244  0  0 100  0  0
 2  0      0 449928  66840 598956    0    0     0    21 1271 2193 64 15 21  0  0
 2  0      0 448688  66872 599300    0    0     0    41 1172 2251 88 12  0  0  0
 2  0      0 447952  66888 599700    0    0     0    24 1211 2433 86 13  0  0  0
 1  0      0 447032  66896 600044    0    0     0    41 1165 2203 86 14  0  0  0
 2  0      0 446544  66920 600432    0    0     0    45 1215 2415 84 16  0  0  0
 2  0      0 446016  66944 600804    0    0     0    36 1158 2196 87 13  0  0  0
 2  0      0 445520  66960 601192    0    0     0    55 1202 2383 87 12  0  0  0
 2  0      0 444868  66968 601544    0    0     0     9 1151 2240 87 13  0  0  0
 1  0      0 444404  66992 601912    0    0     0    59 1204 2386 87 13  0  0  0
 2  0      0 443876  67016 602288    0    0     0    37 1192 2353 86 13  0  0  0
 2  0      0 443224  67032 602668    0    0     0    35 1209 2372 82 18  0  0  0
 2  0      0 441448  67040 603028    0    0     0  1348 1174 2254 84 16  0  0  0
 2  0      0 439688  67064 603404    0    0     0    40 1192 2358 81 19  0  0  0
 2  0      0 438664  67088 603792    0    0     0    35 1223 2380 86 13  0  0  0
 0  0      0 438580  67088 603900    0    0     0     0  387  740 19  4 77  0  0
 0  0      0 438612  67096 603900    0    0     0    55   97  204  0  0 100  0  0
 0  0      0 438612  67096 603900    0    0     0     0  101  211  0  0 100  0  0
```

#### リクエスト処理状況(Locust)
```
 Name                # reqs      # fails     Avg     Min     Max  |  Median   req/s
-----------------------------------------------------------------------------------------------------------
 GET /admin/             24     0(0.00%)     912     763    1067  |     880    0.00
-----------------------------------------------------------------------------------------------------------
 GET /admin/             71     0(0.00%)     888     718    1125  |     870    6.86
-----------------------------------------------------------------------------------------------------------
 GET /admin/            120     0(0.00%)     875     718    1125  |     860    8.00
-----------------------------------------------------------------------------------------------------------
 GET /admin/            168     0(0.00%)     874     718    1125  |     860    8.10
-----------------------------------------------------------------------------------------------------------
 GET /admin/            216     0(0.00%)     872     718    1125  |     860    8.00
-----------------------------------------------------------------------------------------------------------
 GET /admin/            264     0(0.00%)     871     698    1125  |     860    8.10
-----------------------------------------------------------------------------------------------------------
 GET /admin/            297     0(0.00%)     870     698    1125  |     860    8.00
-----------------------------------------------------------------------------------------------------------
 GET /admin/            300     0(0.00%)     870     698    1125  |     860    7.90
-----------------------------------------------------------------------------------------------------------

リクエストの完了割合に応じた1リクエスト処理時間(ms)
 Name                # reqs    50%    66%    75%    80%    90%    95%    98%    99%   100%
-----------------------------------------------------------------------------------------------------------
 GET /admin/            300    860    910    930    940    980    990   1000   1100   1125
-----------------------------------------------------------------------------------------------------------
```


### プロセス: 2, スレッド: 2 の場合
スペックの限界を越えた設定となってるのでオーバヘッドが大きくなり
ロードアベレージも高く1リクエストあたりの処理時間がどんどん長くなってます。
今回の検証のなかでパフォーマンスが一番悪いです。

#### システム負荷状況(vmstat)
```
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 445772  66372 580060    0    0    26    19  263  506  8  2 90  0  0
 0  0      0 445780  66372 580068    0    0     0     0  108  223  0  0 100  0  0
 3  0      0 445664  66372 580244    0    0     0    40  620 1348 41  9 50  0  0
 2  0      0 444780  66372 580592    0    0     0     0 1130 2288 87 13  0  0  0
 4  0      0 444404  66372 580948    0    0     0    32 1084 2242 89 11  0  0  0
 4  0      0 443996  66372 581320    0    0     0    33 1110 2263 84 16  0  0  0
 3  0      0 443488  66372 581692    0    0     0     9 1122 2334 84 16  0  0  0
 4  0      0 443124  66372 582036    0    0     0    28 1068 2174 87 13  0  0  0
 5  0      0 442768  66372 582404    0    0     0   113 1083 2285 85 15  0  0  0
 3  0      0 442228  66372 582776    0    0     0    40 1112 2348 89 11  0  0  0
 4  0      0 441764  66372 583140    0    0     0     0 1075 2315 88 12  0  0  0
 5  0      0 441272  66372 583512    0    0     0    33 1130 2335 84 16  0  0  0
 5  0      0 440900  66372 583852    0    0     0    33 1094 2242 85 15  0  0  0
 5  0      0 440472  66372 584152    0    0     0  1387  979 2029 91  9  0  0  0
 4  0      0 440028  66372 584512    0    0     0     0 1103 2273 85 15  0  0  0
 5  0      0 439564  66372 584828    0    0     0    47 1077 2291 85 15  0  0  0
 3  0      0 439288  66372 585188    0    0     0    37 1055 2134 87 13  0  0  0
 0  0      0 439908  66372 585208    0    0     0     0  257  478  8  1 91  0  0
 0  0      0 439948  66372 585208    0    0     0     7  101  209  0  0 100  0  0
 0  0      0 439948  66372 585208    0    0     0     0  101  209  0  0 100  0  0
```

#### リクエスト処理状況(Locust)
```
 Name                # reqs      # fails     Avg     Min     Max  |  Median   req/s
-----------------------------------------------------------------------------------------------------------
 GET /admin/             23     0(0.00%)     966     718    1225  |    1000    1.00
-----------------------------------------------------------------------------------------------------------
 GET /admin/             71     0(0.00%)     934     684    1225  |     930    6.86
-----------------------------------------------------------------------------------------------------------
 GET /admin/            117     0(0.00%)     925     623    1225  |     930    7.90
-----------------------------------------------------------------------------------------------------------
 GET /admin/            165     0(0.00%)     920     623    1225  |     930    7.90
-----------------------------------------------------------------------------------------------------------
 GET /admin/            211     0(0.00%)     918     623    1225  |     930    8.00
-----------------------------------------------------------------------------------------------------------
 GET /admin/            253     0(0.00%)     956     623    1481  |     950    7.50
-----------------------------------------------------------------------------------------------------------
 GET /admin/            298     0(0.00%)     965     623    1481  |     950    7.00
-----------------------------------------------------------------------------------------------------------
 GET /admin/            300     0(0.00%)     965     623    1481  |     950    7.10
-----------------------------------------------------------------------------------------------------------

リクエストの完了割合に応じた1リクエスト処理時間(ms)
 Name                # reqs    50%    66%    75%    80%    90%    95%    98%    99%   100%
-----------------------------------------------------------------------------------------------------------
 GET /admin/            300    960   1000   1100   1100   1200   1200   1400   1500   1481
-----------------------------------------------------------------------------------------------------------
```


### プロセス: 3, スレッド: 1 の場合
ロードアベレージが高く、1リクエストあたりの処理時間が少しずつ長くなってきてます。
1コア辺りにプロセス数をx3設定するのは厳しい印象です。

#### システム負荷状況(vmstat)
```
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 483180  67360 605444    0    0    24    20  271  524  8  2 90  0  0
 0  0      0 483480  67360 605464    0    0     0     0  158  282  0  0 100  0  0
 1  0      0 483520  67368 605520    0    0     0   204  281  571 12  2 86  0  0
 3  0      0 482308  67392 605792    0    0     0   345 1095 2047 82 11  7  0  0
 3  0      0 481108  67408 606172    0    0     0    28 1163 2176 86 14  0  0  0
 3  0      0 476772  67416 606540    0    0     0     9 1110 2053 88 12  0  0  0
 3  0      0 475340  67440 606912    0    0     0    36 1123 2116 85 15  0  0  0
 2  0      0 473732  67464 607272    0    0     0    72 1108 2105 86 14  0  0  0
 3  0      0 472524  67480 607616    0    0     0    27 1154 2202 83 17  0  0  0
 2  0      0 471256  67488 607992    0    0     0    11 1140 2188 85 15  0  0  0
 3  0      0 469984  67512 608296    0    0     0    36 1088 2055 88 12  0  0  0
 3  0      0 469584  67536 608708    0    0     0    33 1166 2223 88 12  0  0  0
 2  0      0 467008  67552 609080    0    0     0    60 1134 2201 85 15  0  0  0
 3  0      0 463308  67560 609432    0    0     0   544 1137 2044 87 13  0  0  0
 3  0      0 462624  67584 609804    0    0     0    40 1163 2146 86 14  0  0  0
 2  0      0 462136  67608 610168    0    0     0   824 1137 2158 83 17  0  0  0
 4  0      0 461604  67608 610532    0    0     0     0 1132 2195 88 12  0  0  0
 0  0      0 461728  67632 610608    0    0     0    35  459  859 22  5 73  0  0
 0  0      0 461672  67632 610608    0    0     0    37  138  253  0  0 100  0  0
 0  0      0 461672  67632 610608    0    0     0     0  122  240  0  1 99  0  0
```

#### リクエスト処理状況(Locust)
```
 Name                # reqs      # fails     Avg     Min     Max  |  Median   req/s
-----------------------------------------------------------------------------------------------------------
 GET /admin/             23     0(0.00%)    1040     736    1335  |    1100    3.00
-----------------------------------------------------------------------------------------------------------
 GET /admin/             70     0(0.00%)     961     736    1335  |     940    7.14
-----------------------------------------------------------------------------------------------------------
 GET /admin/            116     0(0.00%)     950     736    1335  |     930    7.80
-----------------------------------------------------------------------------------------------------------
 GET /admin/            162     0(0.00%)     946     736    1335  |     940    7.80
-----------------------------------------------------------------------------------------------------------
 GET /admin/            210     0(0.00%)     935     736    1335  |     920    7.80
-----------------------------------------------------------------------------------------------------------
 GET /admin/            256     0(0.00%)     939     736    1335  |     930    7.80
-----------------------------------------------------------------------------------------------------------
 GET /admin/            287     0(0.00%)     932     736    1335  |     920    7.90
-----------------------------------------------------------------------------------------------------------
 GET /admin/            300     0(0.00%)     935     736    1335  |     920    7.90
-----------------------------------------------------------------------------------------------------------

リクエストの完了割合に応じた1リクエスト処理時間(ms)
 Name                # reqs    50%    66%    75%    80%    90%    95%    98%    99%   100%
-----------------------------------------------------------------------------------------------------------
 GET /admin/            300    920    960    980    990   1100   1100   1100   1200   1335
-----------------------------------------------------------------------------------------------------------
```


## まとめ
Webアプリケーションのパフォーマンスは、Nginx(Webサーバ)側であったり、DBサーバ側のI/O負荷なども
絡むので一概にこの設定と断定はしにくいのですが、今回測定した限りではアプリケーションサーバ側では
プロセス:1、スレッド:n よりも プロセス: n、スレッド:1の方がパフォーマンスが高い印象受けました。
とりあえず、目安としてはプロセス数はコア数x2、スレッドは1で様子を見ながら
最適な設定を探るのがベターなのかなと思います。