koudenpaのブログ

趣味のブログです。株式会社はてなでWebアプリケーションエンジニアをやっています。職業柄IT関連の記事が多いと思います。

オートスケールやサーバレスへの付き合い方と期待(主にAWS)

仕事の本業や副業のWebサービスホスティングにはクラウド、多くの場面ではAWS、たまにAzureなど他を使っている。

この際、時間によって変化する処理能力への要求に対応するためにオートスケールやサーバレスを活用して運用負荷やホスティングコストと付き合っている。

これらに関する所感をまとめたいと思ったのでまとめる。

オートスケールとサーバレスの違い

ここ数年で提供開始されたAWSのサーバレスなにがしはサーバレスではなくオートスケールだと思うので、その違和感の元を言語化しておく。 あくまで持論、個人の認識ではあるけれど、まぁまぁ実態に即した捉え方をしているのではないかと思う。

まずオートスケール。これは利用者の管理下にあるリソースのサイズや数を何らかの条件に則って変更するものであると捉えている。

よく使うものではECSのタスクで、例えばユーザからのリクエスト数が増減して既存のタスクの負荷が変化したら、その変化に応じてタスク数を変更、スケールアウト・スケールインする。どのように変更するかはあるECSタスクの処理能力や、ユーザからのリクエスト数の増減傾向に応じて設定しなくてはならない。

次にサーバレス。これは利用者の管理下にないリソースを、実際にそのリソースを使用する際に動的に確保するものであると捉えている。

典型的にはLambdaで、例えばユーザからのリクエストが発生したら都度実行環境を確保して処理を実行する。厳密には実行環境は再利用されるが、どのように確保、再利用されるかは意識する必要はない。確保する際にはリクエストを処理するためにかかる時間が長くなる(コールドスタート)が、それさえ許容できるなら考えることは非常に少ない。

AWSのサーバレスなにがしはサーバレスではなくオートスケールだと思う

例えばAurora Serverless v2であれば、あるインスタンス(言い換えるならサーバー)のCPU・メモリ割り当てを変化させているだけで、リクエストに応じて実行環境を確保しているわけではない。と言った具合の違和感がある。かなりサーバーを意識しなくてはならない。

オートスケールとの付き合い方

オートスケールへの期待

あるリソースの負荷の変化に自動的に対応し、リソースの効率(コスト効率)を最適化する。事前の想定より大きな要求にも自動的に対応する*1。辺りがオートスケールへの期待としてある。

これはあるWebサービスへの1日のリクエスト数≒負荷の推移。

ざっくりこのような感じの期待。

この程度、精々直前の2倍未満程度の負荷増ならやや難しくともオートスケールで対応出来なくはないが………

そのための設定をどうすればいいのかは世の中にいくらでも転がっているし、すべて理解しているわけでもないので「自分としてはこう付き合っている」になる。

ECSとの付き合い方の実際

主に付き合っているのはサービスへのリクエストを処理するECSタスクなので、簡単に設定するには

ターゲットメトリクス値を使用して Amazon ECS サービスをスケールする - Amazon Elastic Container Service

を用いればよい。

この「ターゲット追跡スケーリングポリシー」は、ボトルネックとなる要素が分かりやすい場合に、その要素のCloudWatchメトリクスの値が一定値になるようにECSのタスク数をオートスケールしてくれる。

Webサービスでは概ねCPU負荷がボトルネックとなるので主に「CPU使用率がこの位になるようにしてくれ」を設定する*2

オートスケールで特に気にしなくてはならないのは、負荷が高くなってきた際にその負荷を処理できる状態を維持するためのスケールアウト設定だ。スケールインの側は、めちゃくちゃコストを気にしなくてはならないようなことがない限りは、緩やかにスケールインするようにしておけば問題ない。

「ターゲット追跡スケーリングポリシー」で「CPU使用率」を追跡したなら、CPU使用率が一定以上になったらスケールアウト、ECSのDesired Countを変更してタスク数を増やす設定が行われる。タスクの内容次第で変わってくるが、設定変更してからタスクが立ち上がって実際にリクエストを処理できるようになるには5~10分程度は見込んでおく必要がある*3

そのため、あるタスク数でCPU使用率が落ち着いている状態から、リクエスト数が増加した際にスケールアウトが完了するまでの間は元のタスク数で処理が行えなくてはならない。

以下のようなイメージ。

サービスの負荷増減傾向やタスクで動かしているプログラムの質次第で妥当な設定は変わってくる。予測で妥当な値を決めるのは相当難しいので、悲観的なターゲット追跡値を設定、実測で負荷を見ながら少しずつ楽観的なターゲット追跡値にしていくのが無難だろう*4

ざっくり、平易に行える設定にエイヤで適当な値を指定して、後は実際の負荷の様子を見ながら調整することでオートスケールと付き合っている。と言った感じ。

オートスケールで対応できないスパイク

オートスケールでは対応できない急激な負荷増減(スパイク)に関しては、そういったスパイクは諦めるか、リソースの効率(コスト効率)を犠牲にしてターゲット追跡値を悲観的な値に設定するかになる。

負荷増減のタイミングが予測できているなら、その時刻にオートではないスケール設定(暖機、ウォームスタンバイ)を行えばよい。

スケジュールされたスケーリング - Application Auto Scaling

機能名はApplication Auto Scaringだが、オートの意味合いはちょっと異なりそう。scheduled-scalingなら指定したスケジュールで自動的にスケールするわけで、オートがかかる場所が違う感じ。

サーバレスへの期待

長々と書いた通り、オートスケールといい感じに付き合うのは結構面倒くさいので、何も考えなくてもサーバレスで発生したリクエストを処理してくれるようになって欲しい。

LambdaなどのFaaSは結構サーバレスだが「コールドスタートが許容されない」となった瞬間面倒くさいことになってくるし、そもそもFaaSで実行するプログラムにはそれなりの制約がある。

魔法はないのは分かるがが、それでも魔法になって欲しい。

というわけで、AWSのオートスケールとの付き合い方とサーバレスへの愚痴期待の記事でした。


余談・プロに頼ろう

悲観的なターゲット追跡値を設定、実測で負荷を見ながら少しずつ楽観的なターゲット追跡値にしていくのが無難

これができないような厳しめの要求があり、自分の手に負えないなら素直にプロのサポートを受けるのが良いと思う。

基本的には使っているプロバイダのサポート、大手パブリッククラウドならそれを専門としてるコンサルもあるが、玉石混淆なのでプロバイダの1次サポートが無難かと思う。

一定以上の規模の組織ならサポート契約を結ぶべきだし、小規模なら大手パブリッククラウドはスタートアップのサポートプログラムを持っていて、そのプログラム内にはアーキテクチャ面の相談も含まれていたりするのでそれらを活用するも良いかと思う。

aws.amazon.com

とか。色々ある。

*1:オートスケールしない場合、事前に想定した以上の負荷には耐えられない

*2:逆に言うと、分かりやすいボトルネックが発生するようにオートスケール対象を構成する必要がある

*3:タスクの起動処理やヘルスチェック次第で変わってくる、要実測

*4:無難にやるかは状況による………手抜きする場合はいきなり攻めた設定にする、そして痛い目――過負荷、パフォメンス劣化――を見る