多くのオンラインストアは、年間売上の大部分をわずか数日で稼ぎます。祝日の週末、新製品の発売、たった一度のフラッシュセールが、通常の1週間分を超えるトラフィックを1時間でもたらすこともあります。
幸いなことに、ピーク日は予測できます。日付はわかっており、前年の数値もあり、急増を引き起こすプロモーションも自社で管理しています。
推測ではなく、負荷の見積もりから始める
昨年のピークを分析ツールとサーバーログから取り出し、最も忙しかった日ではなく、最も忙しかった1分間に注目します。1日の合計値は、実際にシステムを停止させる急増を覆い隠してしまいます。急増は通常、メールキャンペーンが届いたときやカウントダウンが終わったときに訪れます。
昨年最も混雑した1時間のセッション数が60,000件で、マーケティング部門が今年はその2倍を見込んでいるとします。セッションあたり平均10ページビューで120,000セッションであれば、オリジンはその1時間に約120万ページビュー、平均で毎秒約330ページビューを処理しなければなりません。1時間の中でもトラフィックは均一ではないため、ピークの1分間については2〜3倍し、毎秒約1,000件の動的ページのリクエストに、カートと検索からのAPI呼び出しを加えた量を想定します。
次にLittleの法則で、レートを同時実行数に変換します。処理中のリクエスト数は、到着率に応答時間を掛けた値に等しくなります。毎秒1,000リクエストで1リクエストあたり300 msであれば、常時約300件のリクエストが処理されています。各アプリケーションワーカーが一度に1リクエストを処理する場合、フリート全体で最低300ワーカーが必要で、遅いリクエストやノード障害に備えた余裕を見込むとさらに多くが必要です。
- 注文。コンバージョン率3パーセントの場合、120,000セッションから1時間に約3,600件の注文が生まれます。平均すると毎秒1件ですが、ピークの1分間には毎秒5〜10件を想定してください。
- 帯域幅。1 Gbpsのポートは毎秒約125 MBを転送します。キャッシュされないHTMLページが平均100 KBであれば、毎秒1,000ページだけで、画像やスクリプトを含める前にポートの大半を消費します。
- 余裕。少なくとも見積もりの1.5倍でサイジングします。予測は通常、トラフィックが多くなる方向に外れます。また、ボットは分析ツールに計上されない負荷を加えます。
できる限り多くのトラフィックをエッジで処理する
コンテンツデリバリーネットワークは、画像、CSS、JavaScript、フォントといったすべての静的アセットを配信すべきです。CDNがそのすべてをキャッシュから配信すれば、オリジンの負荷は1桁減ります。
カテゴリーページ、商品ページ、トップページは、ログインしておらずカートが空のユーザーにとっては、多くの場合すべて同一です。これらをエッジでわずか30秒から60秒キャッシュするだけで、1分あたり数千件の同一リクエストが、エッジロケーションごと、ページごとに1件のオリジンリクエストになります。
- キャッシュキー。キャッシュする前にURLからトラッキングパラメータを取り除いてください。そうしないと、キャンペーンのクリックがすべてキャッシュミスになります。
- パージの方針。価格と在庫の変更をキャッシュ済みのページにどう反映するかを、短いTTL、対象を絞ったパージ、またはその両方によって、事前に決めておきます。
- アプリケーションキャッシュ。オリジン内では、セッション、カートのデータ、負荷の高いクエリの結果をRedisなどのインメモリストアに保持し、データベースが同じ問い合わせを何千回も受けないようにします。
- 検索。検索とフィルタリングは、商品テーブルへのSQLクエリではなく、専用の検索インデックスから提供します。
書き込み経路を基準にデータベースをサイジングする
読み取りトラフィックはキャッシュやレプリケーションが可能ですが、書き込みはそうはいきません。すべての注文は、注文テーブル、明細、在庫、決済記録、顧客データ、さらに多くの場合は監査ログに触れるため、1件の注文で20から50件の書き込みが発生することも珍しくありません。毎秒10件の注文であれば毎秒数百件の書き込みとなり、それが少数のテーブルに集中します。
まず、ワーキングセットがメモリに収まることを確認します。最近の繁忙日のスロークエリログを確認し、不足しているインデックスを今のうちに追加してください。通常のトラフィックで200 msかかるクエリは、ピーク時には数秒間テーブルをロックすることがあります。
- コネクションプーリング。データベースの前段にプーラーを配置します。何百ものアプリケーションワーカーがそれぞれ接続を開くと、CPUに余裕があるうちにデータベースの接続が枯渇します。
- リードレプリカ。カタログの読み取り、レポート、バックオフィスのクエリをレプリカに振り分け、プライマリが注文を処理できるようにします。
- ホットな行。大幅に値引きされた1つの商品が、在庫テーブルの1行をロック競合の発生箇所に変えてしまうことがあります。インメモリストアのアトミックなカウンターで在庫を確保してデータベースと突き合わせるか、在庫を複数の行に分割します。
- バックグラウンドジョブ。イベント期間中は、重いバッチ処理、フィードのエクスポート、分析ジョブを一時停止するか、別の時間帯に移します。
チェックアウトを他から分離する
ストアが負荷で劣化したときの目標は、売上を受け付け続けることです。閲覧は数分間遅くなっても構いません。チェックアウトはそうはいきません。
実際には、カートとチェックアウトのルート専用にアプリケーションサーバーのプールを分ける、少なくともワーカーを分けることで、カテゴリーページへの大量のリクエストが決済リクエストを枯渇させないようにします。決済ゲートウェイ、税額計算、不正検知スコアリング、配送料金サービスにはいずれも、短いタイムアウト、回数制限付きのリトライ、そして明確なフォールバック(たとえば注文を受け付けたうえで不正チェックを非同期で実行するなど)が必要です。
- フィーチャーフラグ。レコメンド、レビュー、パーソナライズされたウィジェット、ライブチャットを停止するスイッチを準備します。どれもデプロイなしで負荷を取り除けます。
- サードパーティのスクリプト。タグマネージャーを監査します。チェックアウトページにある分析やマーケティングのスクリプトは、どれもお客様が管理できない依存関係です。
- 待合室。決まったペースで訪問者を受け入れる仮想キューは、全員に対して落ちるサイトよりも優れています。必要になる前に設定し、テストしておきます。
- ボット対策。カートとログインのエンドポイントでIPとセッション単位のレート制限を行い、DDoS緩和を有効にしておきます。在庫を狙うボットやクレデンシャルスタッフィングは、セールと同時にやってくる傾向があります。
顧客の実際の購買行動に沿った負荷テスト
実際の買い物客は、カテゴリを閲覧し、検索し、商品ページを開き、カートに商品を追加し、そのうちの一部がチェックアウトします。テストはこうした行動の流れから組み立て、分析データに合った比率にします。例えば、閲覧70パーセント、検索15パーセント、カート操作10パーセント、チェックアウト5パーセントといった具合です。
テストは自社ネットワークの外部から、CDNを経由して、規模と構成が本番と同等の環境に対して実行します。大規模なテストは攻撃とまったく同じように見えることがあるため、開始前にCDN、ホスティング、DDoS対策の各プロバイダーに連絡してください。
- 段階的な負荷テスト。見積もりの1.5〜2倍まで負荷を段階的に増やし、レイテンシが上がり始める地点を記録します。その地点が実際のキャパシティです。
- スパイクテスト。メールキャンペーンのときと同じように、通常のトラフィックから1分足らずでピークまで跳ね上げます。キャパシティの追加に5分かかるオートスケールは、ここでは役に立ちません。
- 耐久テスト。ピーク負荷を2〜4時間維持し、メモリリーク、コネクションリーク、ディスクを埋め尽くすほどのログ量を洗い出します。
- 繰り返す。各テストで最初のボトルネックが見つかります。それを修正して再度実行し、上限が予測を十分に上回るまで続けます。
ランブックを作成し、監視を整備する
インシデントの最中、人は静かな午後に自席にいるときよりも誤った判断を下しがちです。ランブックは、判断を静かな午後に前倒しするためのものです。当日の指揮を執るのは誰か、業務部門や顧客とのやり取りを担うのは誰か、変更を承認できるのは誰か、そして最も起こりやすい問題に対して合意済みの対応は何かを明記しておくべきです。
監視には2つのレイヤーが必要です。技術レイヤーでは、すべての層のレイテンシ、エラー率、飽和度、トラフィックを対象とします。CDNのヒット率、アプリケーションの応答時間、ワーカー使用率、データベース接続数、レプリケーション遅延、キュー深度などです。ビジネスレイヤーのほうが役立つことも少なくありません。1分あたりの注文数、チェックアウト成功率、決済承認率、カート放棄率などです。
- しきい値。負荷テストに基づき、ピーク時の各メトリクスの正常な状態を書き留めておきます。そうすれば、チームは単に忙しいシステムと障害が起きつつあるシステムを見分けられます。
- 事前に合意したアクション。例えば、チェックアウトのp95レイテンシが3分間にわたり2秒を超えたらレコメンドを停止し、4秒を超えたら待合室を有効にします。
- ロールバック。直近のデプロイを元に戻す方法と所要時間を文書化します。一度は実際にテストしてください。
- 連絡先。ホスティングプロバイダー、CDN、決済ゲートウェイ、その他の重要なベンダーのエスカレーション先を、サポート窓口と対応時間とともに一覧にします。
1週間前:チェックリスト
最後の1週間には、作業の重点を構築から確認に移すべきです。この期間は、それまでに準備したものがすべて整っていることを確認し、想定外の要素を取り除くために使います。
- 変更凍結。ランブックに従って承認された修正を除き、コードとインフラストラクチャの変更を凍結します。
- 証明書とドメイン。TLS証明書とドメインの有効期限を確認します。トラフィックを素早く切り替える必要が生じた場合に備えて、DNSのTTLを短くしておきます。
- キャパシティ。追加のサーバーが計画されているだけでなく、実際にプロビジョニングまたは確保されていることを確認します。当日にゼロからスケールアップすると、プロバイダーのキャパシティの制約やウォームアップ時間の影響を受けます。
- バックアップ。最新のデータベースバックアップを実際にリストアして検証し、ポイントインタイムリカバリが機能することを確認します。
- プロモーション。すべての割引コード、セット販売のルール、価格変更を、実際のカートの組み合わせを使ってステージング環境でテストします。
- 在庫とカタログ。セール用の在庫、画像、説明文を事前に登録し、売れ筋商品のキャッシュをウォームアップしておきます。
- 人員。オンコールのスケジュール、連絡チャネル、ステータスページの運用手順を公開します。オンコールの担当者が必要なアクセス権を持っていることを確認します。
当日
グラフが上昇し始めてからではなく、イベントの数時間前にスケールアップします。主要なカテゴリーページと商品ページにリクエストを送ってキャッシュをウォームアップします。
ランブックにないことは何も変更せず、すべての判断を時刻とともに記録します。何かが壊れたら、インシデントリーダーが判断し、チームは合意済みの対応を実行し、ビジネス側の担当者はマーケティングとカスタマーサービスに状況を伝え、キャンペーンの一時停止や顧客への案内ができるようにします。1週間以内に、データが新しいうちに振り返りを行い、実際の数値を記録します。
Vonahostがお手伝いできること
Vonahostのマネージドクラウドは自社プラットフォーム、AWS、Google Cloud上で稼働し、CDN、Redis、Elasticsearch、ステージング環境、バックアップ、監視を含むため、上述のレイヤーのいくつかをカバーします。データベースなどシングルテナントのハードウェアが有利なコンポーネントには、Vonahostの専用サーバーがAMD EPYCプロセッサー、ローカルNVMeストレージ、転送量無制限の1 Gbps専用ポート、ArborによるDDoS対策を提供し、お客様が選択したリージョンに展開します。
ピークイベントに向けて計画する場合、最初に有効なステップは、トラフィックの見積もりと現在のアーキテクチャを共有いただくことです。Vonahostのすべての提案書には構成、ロケーション、責任分担、米ドル建ての月額料金が明記され、各サーバーを稼働させる国はお客様が選択できます。