GAEのスケーリング 後編 <最適化の実践>

  • このエントリーをはてなブックマークに追加

ご注意

この記事は 2015年1月30日 に書かれたものです。内容が古い可能性がありますのでご注意ください。

この記事では、こちらの公式ドキュメントをもとに、GAEのスケーリングの仕組みと最適化のやり方について紹介しております。記事は前後編の2段構成でお送りします。

前編 GAEのスケーリングの仕組みについて
後編 スケーリングの最適化の実践

今回は実践編として、App Engineのスケーリングを最適に動作させるには実際どうすればいいのか、ご説明します。

スケーリングの最適化について

App Engineにおけるスケーリングを最適化する際、以下2つの要素の兼ね合いが重要となります。

  1. ユーザへの平均応答時間の短縮
  2. インスタンスの稼働時間にかかる費用の削減

App Engineは従量課金制のため、スケーリングしインスタンス数が増えると、インスタンス総稼働時間が長くなりコストが増えます。その一方インスタンス数が増えることで、ユーザリクエストが分散され待機時間が減り、ユーザへの平均応答時間が減ります。

この兼ね合いのもと、今回は実践的な3つの最適化の方法を説明していきたいと思います。

  1. QPSを向上させレイテンシーを低くする
  2. インスタンス数を調整する
  3. インスタンスの起動にかかる時間を減らす

説明に進む前に、前提として、この記事では「自動スケールするフロントエンドインスタンス」を対象とした最適化の手法を説明します。スケーリングの種類やインスタンスの種類については、元ドキュメントまたは公式のこちらを参照下さい。

1.QPSを向上させレイテンシーを低くする

QPS(Query Per Second)とは、1つのインスタンスが1秒間で処理するHTTPリクエストの数です。図1のように、GAEではAdmin ConsoleからQPSを確認できます。

image04

図1.Admin Consoleで確認できるQPS

QPSを上げる一番良い方法は、1つのリクエストの処理に掛かる時間を短くすることです。1リクエストにかかった時間は、図2のようにAdmin Consoleのログから確認できます。

image02

図2.リクエストごとにかかった時間

リクエストの処理時間を減らすには、コードを最適化し処理時間を短くするという方法もありますが、ここでは別の方法を紹介します。
Appstatsや最近リリースされたCloud Traceを使う方法です。図3のように、ひとつの処理にかかった全体の時間と、RPC(Remote Procedure Call)に使われた時間が見えるため、処理中でのボトルネックを見つけることができます。

image06

図3.Appstatsで見る処理のタイムラインの一例

表1に、ボトルネックに応じた最適化の方法を示します。

ケース 最適化の方法
RPCがボトルネックの場合 1度にまとめてRPCを行うようにします。例えば、Datastoreからデータを取得する際、いちいちKeyを送ってデータを取得するのではなく、取得したいKeyをまとめて一度に送ることで、送受信にかかる時間を減らすことができます。
他、RPCを非同期にすることで、結果を待つ間、他の処理をさせることができます。ですが、予期せぬバグが発生しうるため、この選択をする場合は開発スキルや経験が必要となるのでご注意下さい。
RPC以外の部分がボトルネックの場合 インスタンスのCPUの性能を上げます(インスタンスの性能についてはこちら)。
費用は高くなりますが、基本的な処理速度が向上しQPSが上がります。さらに、少ないインスタンスで十分リクエストを捌けるようになり、かつ、インスタンスの初期化の頻度も減るため、全体としてQPSが向上します。
そのうえ、1リクエストにかかる処理時間が減り、ユーザの待ち時間も減ります。

表1.ボトルネックに応じたQPSを向上させる方法

また、QPSを上げる別の方法として、1インスタンスで同時に複数リクエストを処理させるという手法もあります。
デフォルトでは、並列処理をすることで予期せぬ不具合が発生しないよう、1インスタンス1リクエストとなっていますが、スレッドセーフな処理であるならば、こちらのページを参考に、1インスタンスに複数リクエストを並列処理させることもおすすめします。

2.インスタンス数を調整する

QPSはアプリケーション全体のスループットを示す指標であり、先ほどはQPSを向上させる手法について説明しました。
ここではスケーリングの柔軟性を表すIdle InstancePending Latencyを調整することで最適化する手法を紹介します。どちらも図4のようにAdmin Consoleから設定できます。
(公式での日本語表記が無いため、以降もIdle Instance、Pending Latencyをそのまま表記します)

image00

図4.Admin ConsoleでのIdle InstanceとPending Latencyの設定

Idle Instanceとは

すでに初期化が完了し、リクエストを受け付ける準備が整っているインスタンスを指します。デフォルトでは、リクエストがなければidle instanceは0個になりますが、Admin Consoleで最小値と最大値を設定できます。
Idle Instanceは、アクセスがバーストしたときの安定性を示す指標です。最小値を高く設定すれば、バースト時もインスタンスの初期化に極端に時間をかけずリクエストを処理することができます。また、最大値を高く設定すれば、バースト後もゆるやかにIdle Instance数が減っていきます。ですが、Idle Instanceが増えればそれだけコストがかかるため、設定する際は注意が必要です。

Pending Latencyとは

全てのインスタンスが処理中のためリクエストが待機しはじめた時点から、新しいインスタンスが生成されはじめるまでの時間を指します。図5にPending Latencyの概要図を示します。こちらもAdmin Consoleで最小値と最大値を設定できます。

image01

図5.Pending Latencyの概要図

Pending Latencyの設定により、インスタンスの生成頻度を調整することができます。
最小値は、待ち状態になったリクエストが必ず待機する時間を指しており、小さくすれば頻繁に、大きくすれば緩やかにインスタンスが生成されるようになります。また、最大値は、その値を超えたら必ずインスタンスが生成されはじめる時間を指すため、最小値と同様に、小さくすれば頻繁に、大きくすれば緩やかにインスタンスが生成されるようになります。
インスタンスが頻繁に生成されれば、ユーザの待ち時間も軽減しますが、インスタンス数が増えてコストがかかるため、Idle Instanceと同様に設定には注意が必要です。

ベストプラクティスとアンチプラクティス

表2に、Idle InstanceとPending Latencyの最小値・最大値の設定についてまとめました。

Idle Instance Pending Latency
最小値の設定 最大値の設定 最小値の設定 最大値の設定
小さくした場合 -バーストの直前に待機しているインスタンスが少ない
-低コスト
-バースト後のインスタンス数が少ない
-低コスト
-インスタンス生成が高頻度
-高コスト
-インスタンス生成が高頻度
-高コスト
大きくした場合 -バーストの直前に
待機しているインスタンスが多い
-高コスト
-バースト後のインスタンス数が多い
-高コスト
-レスポンスが遅くなる
-低コスト
-レスポンスが遅くなる
-低コスト

表2 Idle InstanceとPending Latencyの最小値と最大値の設定

まず、設定のアンチプラクティスを説明すると、下記の2つです。

  1. Idle Instanceの最小値と最大値を同じにする。
  2. Pending Latencyの最小値と最大値のギャップを減らす。

どちらにせよ、スケーリングがうまく動作しなくなるおそれがあります。

次に、Googleがすすめるベストプラクティスを説明します。
 

パフォーマンス重視の場合

  Idle Instanceの最小値を大きくし、Pending Latencyの最大値を小さくする。
  他の値はautomaticにする。

 

低コスト重視の場合

  idle Instanceの最大値を小さくし、Pending Latencyの最小値を大きくする。
  他の値はautomaticにする。

重視する要素によってどちらかを選ぶか、どちらも同等に重要ならば中間をとるように設定すると良いです。

3.インスタンスの起動にかかる時間を減らす

以下の手法によって、インスタンスの起動(ロード)時間を減らせます。

  • 起動時に実行するコードを最小限にする
    • 起動時の初回認証の場合には不要なライブラリをロードしない
    • Javaの場合、アノテーションを処理する際、Pluggable Annotation Processingを活用する
    • slim3などの軽量なフレームワークを利用する
  • ディスクへのアクセスを最小限にする
    • コードをzipやjarファイルでまとめてロードするようにする
  • 起動時間のオーバヘッドの小さい言語(Goなど)を利用する

他の2つの最適化手法(QPSの向上とインスタンス数の調整)に比べるとシンプルな対策ですが、インスタンスの起動が頻繁に実施される場合には、どれも非常に効果を発揮するものです。

まとめ

今回はApp Engineのスケーリングを最適化する3つの方法を紹介しました。

  1. QPSを向上させレイテンシーを低くする
  2. インスタンス数を調整する
  3. インスタンスの起動にかかる時間を減らす

どれも驚くほど簡単です。前編のはじめで皆様に紹介した公式の文章が過言ではなかったことが、少しでもお伝えできたならば幸いに思います。
まだまだApp Engineは多くの方に受け入れられていないように思えます。DatastoreがMySQLなどのRDBと勝手が違うなど、確かにApp Engineを選択する上でハードルが高いところもあります。ですが、逆に素晴らしいメリットもあるのです。
この記事を読んでApp Engineに興味が湧いた方がいらっしゃったら、ぜひ試してみて下さい。

GAE Getting Started
https://cloud.google.com/appengine/?hl=ja

※記事に利用している図はこちらのドキュメントから引用しております

前編 GAEのスケーリングの仕組みについて
後編 スケーリングの最適化の実践
  • このエントリーをはてなブックマークに追加

Google のクラウドサービスについてもっと詳しく知りたい、直接話が聞いてみたいという方のために、クラウドエースでは無料相談会を実施しております。お申し込みは下記ボタンより承っておりますので、この機会にぜひ弊社をご利用いただければと思います。

無料相談会のお申込みはこちら