*

Google App Engine Modules のScalingを試す

公開日: : 最終更新日:2015/11/05 投稿者: GAE ,

みなさんこんにちは。

前回の記事では、GAE Modulesの簡単なサンプルを配備し、動作を確認しました。
今回は、それぞれのModulesごとにScalingの設定を行い、動作を確認してみたいと思います。

GAEでScalingといえば、リクエスト量や処理量に応じて自動でやってくれるというイメージですが、Modulesのリリースにより、設定でそのスケーリングのルールを設定できるようになりました。
新登場したのは、Manual-ScalingBasic-Scalingです。
それぞれのaumatic-scalingとの違いは次の通りです。(公式のドキュメントをなんとなく訳しただけです)

Feature Automatic Scaling Manual Scaling Basic Scaling
Deadlines HTTPリクエストは60秒。タスクは10分間。 すべてのリクエストは無期限に動作します。
manual-scaling設定のインスタンスは、インスタンスの開始に/_ah/startを選択することができます。
HTTPレスポンスコードを返すことなく、数時間に及ぶプログラムやスクリプトを実行することができます。
manual-scalingに同じ
CPU/Memory F1, F2 , F4 instance classから選択して設定が可能。 B1, B2, B4, B4_1G, B8 instance classから選択して設定が可能。 B1, B2, B4, B4_1G, B8 instance classから選択して設定が可能。
Residence インスタンスはメモリーをベースとした使用状況により解放されます。 インスタンスはメモリーに残り、状態はリクエスト間で保存されます。
インスタンスが再起動したとき、/_ah/stopリクエストがログに出現します。もしstop callback methodが登録されていた場合、インスタンスが実際に停止する前にそれを完了するための30秒間の猶予を持ちます。
インスタンスはidle_timeoutパラメータをもとに解放されます。もしインスタンスがアイドル状態で、idle_timeoutより長い時間リクエストを受け取っていなければ、インスタンスが解放されます。
Startup and Shutdown インスタンスはリクエストによってオンデマンドで生成され、アイドル状態の間は自動で停止します。 インスタンスの/_ah/start宛の空のGETリクエストがAppEngineによって自動で送られます。
appcfg stop(またはAdmin ConsoleUIからての停止)によって停止されたインスタンスは強制的に停止するまえに実行中のリクエストを終わらせるための30秒の猶予を持ちます。
インスタンスはリクエストによってオンデマンドで生成され、idle_timeout設定を基にしたアイドル状態になると自動で停止します。manual-scalingと同様に、appcfg stop(またはAdmin ConsoleUIからての停止)によって停止されたインスタンスは強制的に停止するまえに実行中のリクエストを終わらせるための30秒の猶予を持ちます。
Instance Addressability インスタンスは無名。 インスタンスは次のようにURLで割り当てることができる。
http://instance.version.module.app_id.appspot.com.
もしカスタムドメイン用にwildcard subdomaing mappingを行いたい場合にも、モジュールやそのインスタンスにURLを割り当てられる。
http://module.domain.com
http://instance.module.domain.com
それぞれのインスタンスの状態は高い信頼性をもってキャッシュされ、subsequent requestにより取得できる。
manual-scalingに同じ。
Scaling App Engineは処理量に応じてインスタンスの数を自動的にスケールする。このスケーリングの根拠はモジュールバージョンに対応する形でアップロードされた設定ファイルのautomatic-scalingです。 モジュール内の設定ファイルを使って、それぞれのモジュールバージョンごとにインスタンスの数を設定できる。
インスタンスの数は一般的にメモリに展開されているデータセットの数や要求されるオフライン作業のためのスループットに合わせる。
basic scalingなモジュールバージョンは最大のインスタンス数をbasic_scalingのmax_instancesパラメータを使うことで設定できる。
動作するインスタンスの数は処理量に応じてスケールする。
Free Daily Usage Quota 28 instance-hours 8 instance-hours 8 instance-hours

GAEにデプロイしたアプリケーションのScalingの設定は、デフォルトではautomatic-scalingになっています。
automatic-scalingは、リクエスト量や処理量に応じて自動でリソース割り当てを変えてくれて便利なのですが、リクエストに対する限界時間が60秒であったり、タスクの有効期限が10分であったりと時間的制限が厳しいのが悩みの種でした。

Deadlineを確認してみる

Automatic Scaling

まずはautomatic-scaling設定(スケーリングの記述をしない)モジュールをデプロイして、deadlineを確認します。

サンプルプログラムは65秒待ってからログにもやしが生えるだけの簡単なものです。
automatic-scalingでは、リクエスト応答まで60秒間の猶予しかないので、失敗するはずです。

appengine-web.xml

<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
 <application></application>
 <version>1</version>
 <threadsafe>true</threadsafe>
 <system-properties>
 <property name="java.util.logging.config.file" value="WEB-INF/logging.properties" />
 </system-properties>
 <module>module1</module>
</appengine-web-app>

Module1Servlet.java

package com.example.myproject;

import java.io.IOException;

import javax.servlet.http.*;

@SuppressWarnings("serial")
public class Module1Servlet extends HttpServlet {
 public void doGet(HttpServletRequest req, HttpServletResponse resp)
 throws IOException {
 Logger log = Logger.getLogger(Module1Servlet.class.getName());
 try {
 Thread.sleep(65 * 1000);// 65秒待つ
 } catch (InterruptedException e) {
 e.printStackTrace();
 }
 log.info("もやし");
 }
}

実行結果


当然こうなります。ログにもやしも生えていません。
予想通り失敗しました。automatic-scalingは便利ですが、タイムアウト設定を変えられないのが難点です。

Manual Scaling

では次に、manual-scaling設定のmoduleを配備してみましょう。
manual-scalingならば、リクエストに対する制限時間はないはずなので、ログにもやしが生えるはずです。
appengine-web.xml

<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
 <application></application>
 <version>1</version>
 <threadsafe>true</threadsafe>
 <system-properties>
 <property name="java.util.logging.config.file" value="WEB-INF/logging.properties" />
 </system-properties>
 <module>module2</module>
 
 <manual-scaling>
 <instances>1</instances>
 </manual-scaling>
</appengine-web-app>

appengine-web.xmlにタグを追加しました。
タグの値は、このモジュールが動作するために、いくつのインスタンスを生成するかを意味しています。
上の表にもある通り、manual-scalingでは、GAEによる自動でのスケーリングが行われないため、自分でコンソール上から停止をするか、Modules APIを使って停止をするまで、この値の数のインスタンスが常にメモリ上に存在することになります。

次に、サンプルプログラムです。これは先ほどと同じです。
Module2Servlet.java

package com.example.myproject;

import java.io.IOException;

import javax.servlet.http.*;

@SuppressWarnings("serial")
public class Module2Servlet extends HttpServlet {
 public void doGet(HttpServletRequest req, HttpServletResponse resp)
 throws IOException {
 Logger log = Logger.getLogger(Module2Servlet.class.getName());
 try {
 Thread.sleep(65 * 1000);// 65秒待つ
 } catch (InterruptedException e) {
 e.printStackTrace();
 }
 log.info("もやし");
 }
}

実行結果

はい。ちゃんともやしがLogsに生えました。
manual-scaling設定にすれば、60秒を超えるような処理のリクエストにも対応できます。

25時間耐久レース

次に、これまで重い処理を任せていたBackendsと、新登場Manual-Scaling Moduleとで耐久レースです。
内容は単純、一時間ごとにLogsにもやしを生やして、25本(25時間)のもやしが育てられたほうが勝ちです。
BackendsへはTaskQueuesを使って処理を委譲します。
ModuleへはHTTP GETでサーブレットを呼び出します。
動作させるプログラムはこちらです。

        log.info("もやしは一時間に一本生えます。");
        log.info("-------------------------------------");
        for (int i = 1; i <= 25; i++) {
            log.info("もやしが" + i + "本....");
            try {
                Thread.sleep(60 * 60 * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

backends.xml

<?xml version="1.0" encoding="utf-8"?>
<backends>
 <backend name="worker">
 <class>B1</class>
 <options>
 <dynamic>true</dynamic>
 <public>true</public>
 </options>
 </backend>
</backends>

Manual-Scalingモジュールの設定はこちら。
appengine-web.xml

<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
 <application></application>
 <version>1</version>
 <threadsafe>true</threadsafe>
 <system-properties>
 <property name="java.util.logging.config.file" value="WEB-INF/logging.properties" />
 </system-properties>
 <manual-scaling>
 <instances>1</instances>
 </manual-scaling>
 <module>moyashi</module>
</appengine-web-app>

実行結果 – backends


うーん、こちらは処理の途中で何度かインスタンスが再起動してしまっています。
2日ほど待ちましたが、結局、正常終了は一件もありませんでした。
実行結果 – Manual-Scaling Module


うんうん、うまくいっている…と思ったら例外が出ていました。
どうやら、manual-scalingのモジュールにも時間制限があるようで、24時間までとなっている模様です。
公式ドキュメントを見ると無制限と読めますが、さすがにそこまでは無理ということなんでしょうか。
ともあれ、一度も途中停止はしていないし、Backendsより安定しているととってもよさそうです。

※追記

Google サポートに問い合わせたところ、現時点ではDeadlineは24時間が仕様と回答されました。
ただし、Modulesの機能自体の仕様がまだ最終化されていないので、これからも変わるかも~とのことです。

この記事を書いた人

kimura
kimura
Webデザイナー。本サイトの管理・デザイン担当をしております。
 

関連記事

GAE負荷テスト その1「Hello World!」

2011年11月にGAEのプレビューが終わり、早数ヶ月経ちました。 これからGAEでの開発に乗り出

記事を読む

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

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

記事を読む

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

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

記事を読む

1つのエンティティにプロパティをいくつまで作れるか

1つのエンティティにプロパティをいくつまで作れるか 1つのエンティティにプロパティをいくつまで

記事を読む

GAEでよくあるエラーの発生原因と対策1

GAE上で動くWebアプリケーションに特有の例外について、弊社での運用の事例からいくつか特徴的なもの

記事を読む

東京リージョン内でのGAE・GCS・GCE間の通信はこのくらいだった

11月8日に Google Cloud Platform にて待ちに待った日本リージョンがリ

記事を読む

AppEngineでTwilioを試してみた(応用編)

AppEngineでTwilioを試してみた(基本編) AppEngineでTwilioを試し

記事を読む

Cloud Loggingの利用方法

はじめに 本記事はGoogle Cloud Platformの公式ページで公開されている「Goog

記事を読む

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

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

記事を読む

AppEngineでTwilioを試してみた(基本編)

AppEngineでTwilioを試してみた(基本編) AppEngineでTwilioを試し

記事を読む

PAGE TOP ↑