App Engine Scaling Config

  • 95
    Like
  • 1
    Comment

App Engineは、Deploy時にModule Version毎にスケーリング設定を行うことができます。
結構、細かい値が設定できるのだけど、いまいちどんな作用があるのか分かりづらいものもあります。
この記事では、スケーリング設定の値にどんな作用があるのかを解説します。

Moduleって?という方は GAE ModulesをSimpleに使う を見てください。

3つのスケーリング設定概要

App Engineのスケーリング設定は3つ存在します。
それぞれ特性が違うので、Moduleでどのような処理をしたいのかによって、選択するスケーリング設定を変えます。

Automatic Scaling

Request数に合わせて自動でインスタンスの追加、削除を行う設定。
App Engineでよくオートスケールが特徴と言われるのは、主にこの設定を指している。
たくさんの小さなRequestをさばくのに適している。
End UserからのRequestは大抵短い時間で処理する小さなものが多いので、Default Moduleはこの設定にすることがほとんど。

Basic Scaling

Request数に合わせて自動でインスタンスの追加、削除を行うが、インスタンスの最大数を事前に決めておく設定。
Request処理可能時間がAutomatic Scalingより長いので、ある程度オートスケールして欲しいバッチ処理などにも適している。

Manual Scaling

Deploy時に指定した数のインスタンスが常時立ち上がるだけのシンプルな構成。
常時何かを処理したい場合や、インスタンス起動時にマスターデータを読み込みメモリ上に保持したい場合などに利用する。

Scaling Config

ざっくりと3つのスケーリング設定を見たところで、細かい設定値を見ていきます。
しかし、細かい設定値が何を指しているかを知るためには、まずApp EngineがRequestをどのように処理しているかを知っておく必要があります。

App Engine Request Processing Flow

App EngineはRequestをインスタンスに割り振る時に、Pending Request Queueと呼ばれるQueueに保持します。
App EngineはPending Request Queueを常に監視していて、インスタンスの処理が追いつかず、QueueにRequestがたまると、新しいインスタンスを追加します。
逆にQueueにRequestがまったく無い状態で、インスタンスが暇になる(Idle状態になる)と、インスタンスを削除します。
これがApp Engineのスケールの仕組みです。

appengine-pending-request-queue.png

では、これを踏まえて、スケール設定を見ていきます。

General Setting

どのスケーリング設定でも存在する設定値として、instance_classがあります。
これはCPUとメモリに関連する設定です。
FとBが存在し、それぞれFrontend, Backendの略です。
FとBにほとんど違いはありませんが、BにだけCPU Limitが大きいB8が存在します。
Automatic ScalingはFを指定し、Basic Scaling, Manual ScalingはBを指定します。
課金はFrontend Instance HourとBackend Instance Hourに分かれています。
Dialy無料枠はF1:28H, B1:8Hなので、F2やB2などの上のinstance_classを使うと、無料枠の減少が早くなります。
必要最低限のinstance_classを指定すると安くていいです。

Instance Class Memory Limit CPU Limit Cost per Hour per Instance
B1 128 MB 600 Mhz $0.05
B2 256 MB 1.2 Ghz $0.10
B4 512 MB 2.4 Ghz $0.20
B4_1G 1024 MB 2.4 Ghz $0.30
B8 1024 MB 4.8 Ghz $0.40
F1 128 MB 600 Mhz $0.05
F2 256 MB 1.2 Ghz $0.10
F4 512 MB 2.4 Ghz $0.20
F4_1G 1024 MB 2.4 Ghz $0.30

Automatic Scaling

Automatic Scalingに設定する値は5つあります。
3つのスケール設定の中で最もややこしいものです。

instance_class: F1
automatic_scaling:
  min_idle_instances: 5
  max_idle_instances: automatic  # default value
  min_pending_latency: 30ms  # default value
  max_pending_latency: automatic
  max_concurrent_requests: 50

min_idle_instances

Idle状態で常時待機しておくインスタンスの数
Requestがまったく無い状態でも立ち上がっているため、課金額が上がるが、突然のトラフィック増加に対応しやすくなる。
min_idle_instancesの設定値によって起動されるインスタンスは、インスタンスタイプがResidentとなり、Request数に応じて立ち上がるDynamic Instanceとは区別される。
Resident Instaceはあんまり積極的に処理はしない。基本Dynamicが処理をする。Dynamicが立ち上がるための時間を稼ぐための予備軍。

sinmetal 所感

個人のProjectでは課金額の節約のために大抵0にしている。
Dynamic Instanceの立ち上がりの補助のための設定なので、GoのようにSpin upが40msだと、Residentはいてもほぼ意味が無い。
Javaで重厚なフレームワークを使っていて、Spin upが遅い時などは、1~2あるとお金を犠牲にパフォーマンスを上げれるかも。

max_idle_instances

Idle状態で待機していてよいDynamic Instanceの最大数
例えば、Requestのスパイクが発生し、50台のインスタンスが立ち上がった後、max_idle_instanceの値が10だと、スパイクが落ち着いて暇になったら、なるべく早く10台までDynamic Instaceを減らす。
大きな値を設定しておくと、スパイクが小刻みに発生する時などに、ペフォーマンスが安定する。

sinmetal 所感

個人のProjectでは課金額の節約のために0 ~ 2にしている。
GoようにSpin upが40msだと、Idleで待機しているインスタンスが必要ないので、とても小さな値で問題無さそう。
Javaの場合だと、1~3ぐらいにしておくとお金を犠牲にパフォーマンスを上げれるかも。

min_pending_latency

Pending Request Queueの中で、既存のインスタンスが空くのを待つ最小時間。
大きな値を設定すると、既存のインスタンスが空くのをなるべく待つようになるので、新しいインスタンスが生成されにくくなる。

sinmetal 所感

僕はGoの場合はだいたいautomaticのまま。
Javaの場合は、3sec以上spin upにかかる場合が多いので、min_pending_latencyも3secにしておいて、既存のインスタンスが空くのを待つようにしたほうが、課金額が節約できて、パフォーマンスも良くなるかも。

max_pending_latency

Pending Request Queueの中で、待てる最大時間
RequestがPending Request Queueの中での待ち時間が、この値を超えると、新しいインスタンスの生成を要求する。
大きな値を設定すると、Pending Request Queueの中で待つ時間が長くなるので、新しいインスタンスが生成されにくくなる。

sinmetal 所感

僕はGoの場合はだいたいautomaticのまま。
Javaの場合は、3sec以上spin upにかかる場合が多いので、max_pending_latencyも5secぐらいにしておいて、既存のインスタンスが空くのを待つようにしたほうが、課金額が節約できて、パフォーマンスも良くなるかも。

max_concurrent_requests

1インスタンスで、同時に処理して良いリクエスト数。

sinmetal 所感

instance_classとの兼ね合いもあるけど、それなりに大きな値をしても良さそう。
Defaultは8だけど、ほとんどのWeb Applicationが80ぐらいの値にしても問題無さそう。

制約

Deadlines

App Engineは1つのRequestを処理できる時間に制限があり、Frontend Instanceは短め。
この時間を超えると、強制的にRequestが終了され、Errorが返される。

  • 通常のRequest 60sec
  • TaskQueue or CronからのRequest 10min

Basic Scaling

Basic Scalingで設定する値は2つです。

instance_class: B1
basic_scaling:
  max_instances: 11
  idle_timeout: 10m

max_instances

スケール時の最大インスタンス数

sinmetal 所感

コストとパフォーマンスのトレードオフで好きに決めればいいんじゃないかと思う。

idle_timeout

Idle状態になってから、シャットダウンされるまでの時間
defaultは5min

sinmetal 所感

defaultはちょっと長めになっているので、1~2min程度にしておくのが良さそう。
Javaで、Spin upが遅くて困る場合は、defaultでもいいかも。

制約

Deadlines

24h

Backend Instanceはバッチ処理などを行うことも想定されているため、Deadlineがかなり長めに設定されている。
それでも、途中でエラーになる可能性はあるため、10minぐらいで区切りながら、処理を進めていくほうが無難。

Manual Scaling

設定はinstance数の1つだけで最も分かりやすい。

instance_class: B1
manual_scaling:
  instances: 5

instances

起動するインスタンスの数

制約

Deadlines

24h

Manual Scalingは指定した数のインスタンスが常に立ちあげられている状態だけど、シャットダウンされないわけではない。
無限ループで、延々と処理をし続けるとかはできないので、注意。