バーストリクエストとの戦い


はじめに

外向けにサービスを展開していると、サービスにもよりますがバースト的なトラフィックが発生して、食いきれなくなることがあるかと思います。
自分の担当していたサービスでは、ピーク時には平常時の10倍以上のリクエストがきて、ELBで食いきれなくなることが多々ありました。
試行錯誤を繰り返して、ある程度は解消したので、その時行った対策や検討などを書きたいと思います。

バーストリクエスト

バーストリクエストとは?

何らかしらの原因で急激にリクエストが増える事です。
下のメトリックスではLBへのアクセスが10倍程度になっています。

なぜ起きるか?

今回の場合は、アプリからAPIを叩かれるサービスを行っていたため、地震が発生した場合などニュースアプリ等から大量にリクエストが来て、この様な現象が発生していました。
他にも広告システムなど、キャッシュを効かせられないサービスではこのようなバーストが起きたりします。

発生して困る事

書くまでもない事ですが、一時的にサービスが使えなくなったり重要なデータが取れなかったりします。(例えば広告が出ない)
もちろん、どこまで対応するかはサービスのSLA次第ですが、できるだけ無くしたいですよね・・・・。

対策案検討時(ボトルネックを特定する)

基本的には、ロードバランサやインスタンスのメトリックスを見ればある程度はわかります。
* ELB 5XXs(カウント)が増えている場合 => LBのキャパシティが足りない可能性が高い
* バックエンド接続エラー(カウント) or ターゲット接続エラー(カウント)が増えている場合 => 配下のインスタンスのキャパシティが足りていない可能性が高いです。(サーバ台数を増やしましょう)

今回対応したパターンでは、どちらも起きてそうでした・・・・・。

環境

構成図

対策前の環境

  • ELB(CLB)
  • APIサーバはapacheでpre-forkモデル
  • サーバはautoscaleで必要に応じで増減させる

対策後の環境

  • ALB
  • APIサーバはgolangでrewrite
  • サーバは台数固定
  • クライアント側から再送を頑張ってもらう(対策前からもある程度はやっていたと思われる)

各対策の説明

  • ELB->ALB(パフォーマンス向上を狙って変えてみたが劇的には変わらず。)
  • apache->golang(そもそもpre-forkモデルがイケてなかったせいもあり、パフォーマンス的には劇的に改善。必要な台数は半分以下に)
  • autoscale->台数固定 (バーストリクエストが来た場合に、そもそもautoscaleが間に合っていない様な状況だったので、ある程度食える台数を見積もって固定台数に変更。)
  • クライアント側から再送(再送である程度は救えるが、リアルタイム性を要求するものには厳しい)

ELBのオートスケールが間に合っていない場合の対策方法

  • 常に負荷(ダミーリクエスト等)をかけておくと、ある程度台数いる状態になります。
  • 明らかにリクエストが増えそうな場合はAWSに連絡すると一時的には、増やしてくれます。ELB暖気運転(Pre-Warming)申請というのを出して下さい。

最後に

基本的に、突発的なバーストトラフィックに対しては、autoscaleでは間に合わないことが多いです。
そういう意味では、最大キャパに合わせてサーバを設置できるオンプレの方が合っているかもしれないです。
AWS側でのこの辺の問題は気にしているようなので、今後改善されて行くことに期待してます。