Google App Engine Modules のScalingを試す

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

ご注意

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

みなさんこんにちは。

前回の記事では、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]
<?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>
[/xml]

Module1Servlet.java
[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("もやし");
}
}
[/java]

実行結果


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

Manual Scaling

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

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

次に、サンプルプログラムです。これは先ほどと同じです。
Module2Servlet.java
[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("もやし");
}
}
[/java]

実行結果

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

25時間耐久レース

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

[java]
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();
}
}
[/java]

backends.xml
[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>
[/xml]

Manual-Scalingモジュールの設定はこちら。
appengine-web.xml
[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>
[/xml]

実行結果 – backends


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


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

※追記

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

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

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

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