*

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

公開日: : 最終更新日:2015/04/17 投稿者: GAE

この記事では、こちらの公式ドキュメントをもとに、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のスケーリングの仕組みについて
後編 スケーリングの最適化の実践

この記事を書いた人

kajimaru3
How toよりWhyが気になるエンジニア

関連記事

15分でできる!!GAE/GOで高速REST APIを構築するための簡単手順 〜前編〜

iOSやAndroid等のクライアントアプリを開発する場合、サーバ側の開発も必要となるケースは多

記事を読む

GCEにPuttyから簡単接続する

年末ではありますが、先日ちょっとGCE(Google Compute Engine)を触る機会がまた

記事を読む

App Engine for PHP ベータ版から正式版へ

GCPBlogの記事によると App Engine for PHP(PHPアプリをGoogle Ap

記事を読む

たった1つのCloud SQLインスタンスで複数のWordPressを動かす

皆様こんにちは。 前回はCloudSQLやCloud Storageを用いてWordpress

記事を読む

Prediction API入門(後編)

今回はPrediction API on GAE/J みなさん、こんにちは。Prediction

記事を読む

Datastoreモデル変更の影響調査

GoogleAppEngine(以下GAEと呼称)に限らず、開発を行なっていると『テーブルの構造を変

記事を読む

GAE/GOでTwitter Botを作ってみる~前編~

TwitterやFacebookのような有名サービスと連携したアプリを開発する場合、開発者は

記事を読む

東京リージョンによってGAEの速度は早くなったのか!?

ついにGAEに東京リージョンが新設されました!!サービス開始からGAEを触れていたユーザにと

記事を読む

Search API詳細解説 Part4「Search API 詳細 検索性能編」

Search API詳細解説シリーズ タイトル Part1Search API 概要説明

記事を読む

Search APIの「Faceted Search」を使ってみた

Search API詳細解説シリーズは完結しましたが、2015年2月19日のAppEngine SD

記事を読む

PAGE TOP ↑