Google App Engineの料金体系が変わるというのは5月に発表されていたのでいまさらですが、最近になって実際に新料金体系でいくらになるのか確認できるようになりました。
私はGAEはTwitter botや簡単なスクリプトにしか使っていなかったので楽観視していたのですが、新料金体系では無料枠を超えることが分かり、慌てて対策をしました。
旧料金体系と新料金体系の違い
旧料金体系から大きく変わるのが、CPU時間ベースの課金から、インスタンス時間ベースの課金になります。
Google App Engineは、リクエストが増えると自動的にインスタンス数を増やして並列化してくれるのが最大の特長です。リクエストに対する反応が遅くなると自動的にスケールアウトし、暇になればインスタンス数を減らします。
新料金体系では、このインスタンスが動いている数×時間で金額が決まり、無料枠では24.0 28.0となっています。これは、インスタンス数が1つだけなら24 28時間、2つ動いていれば12 14時間までということです。
基本的にインスタンス数は自動制御なので、無料の範囲内だけで使いたいと思っていても、気を付けないと勝手にインスタンスを増やされて、24時間動かすことができなくなります。
また、Datastoreの制限も厳しくなり、旧料金では課金対象が容量だけだったのが、新料金ではDatastore操作回数でも制限を受けるようになり、私はこれもひっかかっていました。
今回は、この2点について対策をします。
Memcacheを使ってDatastoreのアクセスを減らす
旧料金ではDatastoreはアクセスし放題だったので、特にアクセスを減らすような努力はしていませんでしたが、新料金での制限はかなり厳しいので、回数を減らしました。
メモリキャッシュサービスのMemcacheは無料でも無制限で使えるので、できるだけMemcacheで済ましてDatastoreにアクセスしないようにします。
例えば最新の記事の日付だけを取得するような処理は、以前はDatastoreからクエリで拾っていましたが、一度日付を取得したら記事が更新されるまでMemcacheに入れて使いまわすようにしました。
また、RSSに新しい記事がないか確認する処理では、毎回全ての記事をDatastoreでチェックしていましたが、RSSのハッシュ値をMemcacheに入れておき、RSSが更新された場合のみDatastoreにアクセスするようにしました。(Last-Modifiedを返してくれないサーバが多いのでハッシュ値にした)
Memcacheはサーバのメモリが足りなくなったりサーバが再起動されるとデータが消えるので、消えることを考慮した使い方が必要です。保存が必要な値は、必ずDatastoreに入れなければいけません。
Application SettingsのPerformanceを変更する
インスタンス数の増加を抑えるために、一番簡単にできる対策がApplication SettingsのPerformanceの設定です。

Max Idle Instancesは、スムーズにインスタンスを増やすために早めに起動しておくインスタンス数の設定です。これを設定しても負荷がかかればそれ以上のインスタンスが作成されますし、暇になればインスタンス数はこの数値未満に減ります。インスタンス数を増やす気はないので、1にしておきます。
Min Pending Latencyは、リクエストに対するレスポンスがこの時間を超えるとインスタンスが増えます。Automaticだと簡単に増えてしまうので、最長の15秒に設定しました。これで、ほとんどインスタンスが増えなくなります。
Cron Jobsを減らしてTask Queueで代用する
Twitter botの場合はほとんどがCronからのアクセスですが、複数のCronの実行が重なると、インスタンスが増える可能性があります。そこで、数分単位の短周期のCronは1つにし、Task Queueで代用することにしました。
Task Queueにはmax_concurrent_requestsという設定があり、同時に実行するタスクの上限を設定できます。これを1にしておくと、タスクの実行時間が来ても先に実行しているタスクがあればその処理が終わるまで待たされます。これにより、複数のリクエストが重なるのを防ぐことができ、インスタンスの増加を抑えることができます。
max_concurrent_requestsはqueue.yamlに次のように記述します。
queue: - name: default max_concurrent_requests: 1
ここではデフォルトキューの設定を変えていますが、Cron代わりに使うためのキューは別に定義した方がいいかもしれません。
ここまでの対策で、インスタンス数を1に抑えることができました。

新料金明細も$0.00になりました。

Backendも使えば9インスタンス時間余分に使える
Frontend Instanceとは別にBackend Instanceというものもあり、こちらは9インスタンス時間まで無料で使うことができます。
Twitter botのようにCronさえ動けばいいような場合は、Backendでも問題ないので、1日のうち9時間だけBackendで動かせば、Frontendの時間を節約できます。ただし、FrontendとBackendではDashboardが分かれてしまい、ログをまとめて確認することができなくなるので、あまりオススメしません。
最悪止まっても構わない?
Google App EngineのQuotaは1日ごとに決まっていて、その切り替わりが日本時間の16時になっています。
万が一使用量をオーバーして止まってしまっても16時には復活するので、24時間動かすことができなくても夕方〜夜中はカバーできます。
一番重要な時間帯はカバーできるので、お遊びのサービスなら24時間動かなくてもいいかもしれませんね。
調整いらなかったかもw