平常時は同時接続およそ500人、ピーク時には数分で8,000〜10,000人に跳ね上がるシステム。ピークに合わせて機材を購入すれば一年の大半が無駄になり、平常時の構成のままなら最も重要な瞬間に落ちます。
これは参考アーキテクチャであり、導入事例ではありません。このページに顧客名や特定案件の数値は含まれていません。
課題
平常時は同時接続およそ500人のシステム。ピーク時 — セール、受付開始、申告期限 — には数分で8,000〜10,000人に跳ね上がり、数時間続いた後、平常に戻ります。
ピークに合わせてハードウェアを購入すると、一年の95%を遊休設備とともに過ごすことになります。平常時の構成のままにすると、最も重要な瞬間、つまり売上が集中する瞬間に落ちます。
提案する構成
階層を分離し、それぞれ独立して増減させる
静的コンテンツ配信、アプリケーションロジック、データベースの三層に分けます。それぞれ受ける負荷の性質が異なるため、それぞれ独立して拡張できるようにします。
できる限りエッジに寄せる
画像、CSS、JavaScript、そして内容がほとんど変わらないページまで、CDNから配信します。これによりピーク時のトラフィックの大半はアプリケーションサーバーに到達しません。労力に対する効果が最も大きい施策です。
アプリケーション層をステートレスにする
アプリケーションサーバーがセッション状態を持たないようにし、インスタンスを自由に増減できるようにします。増減の判定はCPU使用率ではなく応答時間を基準にしてください。利用者が実際に感じるのは応答時間だからです。
データベースの読み書きを分離する
最も難しい制約です。データベースはアプリケーションサーバーほど簡単に複製できません。方針としては、書き込みを受ける主系を1台、参照負荷を分担する読み取り用の複製を複数台、加えて繰り返される問い合わせ用のキャッシュ層を置きます。
待てる処理はキューに回す
確認メール、帳票生成、他システムへの同期などはキューに積みます。ピーク時、利用者にはすぐ応答を返し、重い処理は裏で走らせます。
弱点と対処
| 弱点 | 対処 |
|---|---|
| 立ち上がりに増設が間に合わない | ピーク時刻が分かっている場合は時刻指定で事前増設し、暖機済みの予備を確保 |
| 再起動後のキャッシュが空 | ピーク前に頻出データを事前に読み込む |
| データベース接続数の枯渇 | コネクションプールをサービス単位の上限付きで運用 |
| 1つの遅いサービスが全体を巻き込む | タイムアウトとサーキットブレーカー |
| クラウド費用が予算を超える | 上限設定と日次の予算アラート |
進め方
- まず計測する。 ボトルネックの場所を知る前に最適化しないでください。結果はしばしば予想を裏切ります。多くの場合、原因はサーバーのCPUではなく1本のデータベース問い合わせです。
- 安く直せるものから。 遅い問い合わせにインデックスを追加し、圧縮を有効にし、静的ファイルをCDNに移す。この段階までで十分なシステムも多くあります。
- アプリケーション層から状態を取り除く。 台数を増やすための前提条件です。
- 自動増減を構築し、負荷試験を行う。 想定ピークの1.5倍で試験してください。
- 本番ピークの前に予行演習する。 障害ケースを含めて、シナリオを通しで実施します。
見落とされがちな点
負荷試験は、一つのエンドポイントを叩き続けるのではなく、実際の利用行動を再現する必要があります。実際の利用者はログインし、検索し、詳細を見て、カートに入れ、購入します。各段階で負荷のかかる箇所が異なります。設計の悪い負荷試験は安心できる数字を出し、それでも当日にシステムは落ちます。
ご用意いただきたいもの
- 可能であれば、直近6か月以上の実トラフィックデータ
- 想定するピークの規模と発生時期
- 御社の基準 — どこまで遅くなったら「壊れている」とみなすか
- ピーク時のインフラ費用の上限