年越しのその瞬間、KARTEのリクエスト急増とスケールアップの裏側

あけましておめでとうございます。エンジニアの Yui です。

はじめに

KARTE では毎年、年越し(1/1 0:00)のタイミングで KARTE を導入している一部のウェブサイトにおける新年のキャンペーンやセール開始によるリクエスト急増が見込まれます。このリクエスト急増に対応する事前のスケールアップやリアルタイムでの対応を一部のエンジニアで行なっています。

通常時はクラウド上のほぼ全てのリソースのスケーリングを自動化しているのですが、コストやコールドスタートに対する対策の観点からこのタイミングのみ一部を手動で対応しています。

この記事では今年どんな対応を行なったのかを記録として残しておきたいと思います。

今回スケールさせた部分について

KARTE ではインフラの大部分に Google Cloud を利用しています。今回スケールさせるのは主に Google Cloud のサービス群(Cloud Bigtable(以下 BigTable), Google Kubernetes Engine(以下 GKE), Compute Engine(以下 GCE) など)になります。

今回の対応部分である、KARTEのリアルタイム解析基盤についてざっくり説明します。
スクリーンショット2024-01-1513.13.57.png
リアルタイムユーザー解析

KARTE の JavaScript タグが入っているウェブサイトにユーザーが訪れると、そのユーザーの閲覧やクリックなどのウェブサイト上での行動( = イベントデータ)が KARTE のサーバーに送られます。KARTE のサーバーは受け取ったイベントデータをリアルタイムに解析します。また、事前に設定している施策配信を行うかどうか(このページを閲覧した人にはこのポップアップを出す、など)の判定を行い、結果をウェブサイト側に返します。

この解析や配信判定処理を担当しているのがリアルタイム解析基盤と呼んでいる部分で、レイテンシやサーバー負荷状況がサイト上のユーザー体験にクリティカルに影響します。
(リアルタイム解析基盤のアーキテクチャについて詳しく知りたい方はこちらの記事をご参照ください。 Blitz(後編):リアルタイムユーザー解析エンジンを実現する技術 - 強整合な解析 -

事前準備

リアルタイム解析基盤はざっくり分けてユーザーの解析や配信判定などリアルタイムに処理する必要がある部分と、イベントデータの永続化など非リアルタイムの処理でよい部分があります。
アーキテクチャや過去の対応実績をもとに特に前者に重点を置き、何をどの程度スケールさせるのかを事前に検討しました。

準備として実際に当日までに行った内容は以下です。

  • 当日の対応内容の読み合わせ(今回は4名で対応しました)

  • 誰がどの部分を担当するのかを決める

  • 各自担当部分についてスケールさせる値を決める

    • 昨年の年明けタイミングや直近1ヶ月の定常時のリクエスト数・インスタンス数の平均・最大値などを確認して判断しました
  • Terraform や GKE の manifest など IaC で対応する部分は当日までに PR を作成し、レビューを済ませておく

    • 当日はこの PR をマージすることで CI/CD パイプラインが走り、変更が適用されます
  • BigTable のスケールアウト検証

    • BigTable は最小ノード数を増やしたからといって必要なリソースが確保できるかを確約していません。そこで、実際の環境で少なくとも数日前の時点で想定量までスケールできるかという点や、当日の作業手順確認の目的で事前検証を行いました。(数日前時点でスケールできたからといって当日に同じリソース量までスケールできることが確約されていない点は注意が必要です)

    ノード割り当てとは、各プロジェクトで 1 つのゾーンにプロビジョニングできるノードの最大数です。この割り当て数にまだ達していなくても、クラスタにノードを追加できるとは限りません。ゾーンでこれ以上ノードを利用できない場合、プロジェクトで割り当てが残っていても、そのゾーンのクラスタにノードを追加できないことがあります

    割り当てと上限 | Cloud Bigtable ドキュメント | Google Cloud

    ゾーンでノードがなくなると、構成した最小ノード数を満たすように追加ノードがプロビジョニングされません。

    自動スケーリング | Cloud Bigtable ドキュメント | Google Cloud

作業内容や担当、進捗についてはこんな感じで Notion で管理しました。
tasks.jpg

当日やったこと

作業当日(2023/12/31)は事前に決定した通りに以下の手順で作業を行いました。

  • 20:30 に Slack に集合

  • 通常時に利用している自動スケール設定のモニタリングを OFF にする

  • Datadog のログ量を調整する

    • 普段から Datadog への書き込みが多いかつ重要度の低いログを一時的に停止させることで、不要なコストがかかることを防止する目的で行いました。
  • BigTable クラスタのノードサイズの最小値を手動で徐々に上げていく

    • BigTable はノードを増やすと一時的にレイテンシが増加し負荷がかかった状態が続く可能性があり、ユーザー体験に影響を与える可能性があります。一気に上げてレイテンシが高い状態が続くのを避けるため、都度レイテンシを確認しながら手動で徐々に上げるようにしました。

      クラスタ内のノード数が増加した後、クラスタのパフォーマンスが大幅に向上するまでに、負荷のかかった状態が最大 20 分間続く可能性があります。Bigtable は、その負荷に基づいてクラスタ内のノードをスケーリングします。

      パフォーマンスについて | Cloud Bigtable ドキュメント | Google Cloud

  • IaC 対応部分のPRをマージし、変更後の値までスケールすることを確認

  • Datadog のダッシュボードでスケール台数やエラーレート、レイテンシを監視し異常がないかを確認
    datadog.jpg
    ▲こんな感じで作業と並行してダッシュボードを継続して確認していました

以下は 2023/12/31 23:00 〜 2024/1/1 1:00 までのイベント数や接客数・スループットを Datadog のダッシュボードに描画したグラフです。0:00 のタイミングでリクエストが急増しているのがわかります。
イベント数.jpg

当日は事前準備した内容の実施に加え、想定よりもリクエスト数が増えそうな兆候があったため追加でインスタンス数を増やすなどの対応を行いました。

後片付け

0:00〜0:30ごろをピークにリクエスト数が徐々に落ち着いていくのを確認しました。その後1:00頃からPRのリバートや手動でスケールさせた部分のスケールインを行いました。

スケールイン時も急激に台数を減らすとサーバーの負荷増加や BigTable のレイテンシ増加などでパフォーマンスが低下するおそれがあるため、対応方法に注意する必要があります。

今回対応した部分(BigTable, GKE, GCE)に関してはスケールインを自動で徐々に行う設定が入ってることを確認し、スケールインを実行しました。

クラスタ内のノード数を減らしてスケールダウンする場合、10 分間に 10% を超えるクラスタサイズの縮小は行わないようにしてください。スケールダウンが速すぎると、クラスタ内の残りのノードが一時的に過負荷になる場合にレイテンシが増加するなど、パフォーマンス上の問題が発生する可能性があります。

スケーリング | Cloud Bigtable ドキュメント | Google Cloud

Kubernetes offers features to help you run highly available applications even when you introduce frequent voluntary disruptions.
As an application owner, you can create a PodDisruptionBudget (PDB) for each application. A PDB limits the number of Pods of a replicated application that are down simultaneously from voluntary disruptions.

Disruptions | Kubernetes

スケールインの速度を制御するには、追跡時間枠内でのオートスケーラーの最大許容削減数を構成します。

  • 最大許容削減数maxScaledInReplicas: VM インスタンスの数または割合)。指定された追跡時間枠内においてワークロードで(グループのピークサイズから)削除できるインスタンスの数。このパラメータを使用して、グループをどれだけスケールインできるかを制限します。これにより、より多くのインスタンスがサービスを開始するまで、発生しうる負荷スパイクに引き続き対応できます。最大許容削減数が小さいほど、スケールインの速度は遅くなります。
  • 追跡時間枠timeWindowSec: 秒)一時的な負荷減少の後に負荷スパイクが発生する可能性が高く、最大許容削減数を超えてグループサイズをスケールインしたくない時間。このパラメータで、オートスケーラーが過去の負荷を処理するのに十分なピークサイズを決定する際の時間枠を定義します。オートスケーラーは、追跡時間枠で観測されたピークサイズから最大許容削減数を差し引いた値よりも小さいサイズには変更されません。追跡時間枠が長いほど、オートスケーラーは過去のピーク負荷を重視します。これにより、より慎重な安定したスケールインが可能になります。

オートスケーラーによる判断の理解 | Compute Engine ドキュメント | Google Cloud

おわりに

年越しの瞬間はこんな感じで緊張感がありながらもわいわい対応していました。
Group1.jpg
普段はなかなかやらないような大幅なスケールアップやリアルタイムでの対応を行い、個人的にもとてもいい経験になりました。

CX(顧客体験)プラットフォーム「KARTE」を運営するPLAIDでは、データを活用しプロダクトを改善していくエンジニアを募集しています。
詳しくは、弊社採用ページをご覧ください。