ハードウェアのサイジングに関する読書メモ

随分前に買ったがピンときていなかった下記書籍が、個人的にタイムリーになってきたので読んだ&メモしておく。

WEBアプリケーション・サーバー 設計・構築ノウハウ 第2版

WEBアプリケーション・サーバー 設計・構築ノウハウ 第2版

今回は第3章「性能設計」の読書メモ。

性能設計は以下の手順で行う。

    1. 業務(=トランザクション)別の性能目標(レスポンスタイム、スループット)の定義
    2. 上記の内、全トランザクション内での割合が大きく(70%目安)、クリティカル、ボトルネックな処理を網羅し、ピーク時に実行される業務をサンプルとして採用
    3. 上記サンプルについて、サイジング(CPU数、メモリサイズ、マシン台数)
    4. 流量制御設計(各種パラメータ設定)

1. 業務別の性能目標の定義

各業務について、ピーク時間帯、全体に占めるトランザクション数の割合、レスポンスタイム、トランザクション数/秒、を要件定義する。

3. サイジング

■CPU数
「TPS」 = 「1CPUの処理件数[件/s]」×「CPU使用率」×「CPU数」
「TPS」 = 「1 / 1件に要するCPU時間[s]」×「CPU使用率」×「CPU数」
「CPU数」=「TPS」×「1件に要するCPU時間[s]」/「CPU使用率」

※TPS:Transaction Per Second。要件定義。
※一般に、CPU使用率は70%程度とする(100%ではCPUがボトルネックになってしまうため)。
※「1件に要するCPU時間」は、リファレンス・モデルからもってくるか、プロトタイプを作って測定するかで求める。もし本番用と異なるCPUについての情報しか得られない場合は、CPUベンダやベンチマークテストの公表データなどを参考に比率を入手し、積をとって算出する。

■メモリサイズ

メモリ許容量を超えた際のオーバーヘッド(GCスワップ)をどの程度の頻度許すかで決まる。
以下、Javaの場合について。
GCは他の処理とは別スレッドで実行されるが、GC実行時はGC以外のスレッドは停止されるため、GC処理時間がオーバーヘッドになる。
CopyGCとFullGCの発生タイミングは以下の通り。

  • CopyGC:Eden領域が一杯になったタイミングで発生
  • FullGC:Old領域が一杯になったタイミングで発生

よって、Eden領域およびOld領域のサイズ設定によってGCタイミングを制御できる。
(詳細な算出方法は書籍参照)
で、最終的には、算出値×安全率 のメモリサイズとする。

※一般に、安全率は20%程度とする
GC処理時間の参考値:
メモリ1GBの場合、
 CopyGC:数十〜数百ミリ秒
 FullGC:数秒〜数十秒
メモリ2Gを超えると、FullGCの処理時間は非常に長い。(10GBで30秒程度)

■マシン台数
  • 1台あたりのCPU数:4CPUまでが妥当な目安。
  • 1台あたりのメモリサイズ:32bitCPUなら4GBまで、64bitCPUなら16EBまで。ただし、上述の通り、メモリサイズが大きくなるとGCの処理時間が大きくなる

流量制御設計

リクエスト・キューのサイズと同時実行スレッド数を適切に設定することで、想定以上のリクエストが来た際にハングアップしないようにする。