2010-01-17

Quota と 10 秒ルールのはざまで

を公開してから一週間。現在、順調にユーザーが増えているところ。だけど、このままユーザーが増えても、無料の Quota 内でいけるのだろうかと少し心配に。 このアプリでは
  • Update サーブレットが cron で 5 分間隔に呼ばれ、登録されているブログ情報を確認して、TaskQueue で Check サーブレットを呼び出す。
  • Check サーブレットでは Update サーブレットから渡されたパラメータ(Key String)をもとにブログ情報を確認し、その投稿フィードへアクセス。更新があればその内容をブログ情報へ格納。
  • 登録ブログ分の Check サーブレットが全て動き終わると(MemcacheService.increment(Object, long) で確認)、Prepare サーブレットが起動。登録されているブログから更新時刻をもとに 50 個 Query を使って呼び出してリストを作成し、Memcache に格納。
  • トップページの Top サーブレットで、Memcache からリストを表示。なければ Prepare サーブレットのリスト作成メソッドから取得。
なんてことをしているんだけれど、今までは贅沢に、ブログの更新をチェックする Check サーブレットを、ブログの数だけ TaskQueue に積んで起動させていた。無料 Quota の Task Queue 呼び出しリミットは 100,000。このままの仕様だと、348 ブログ登録されただけで、一日の最後の方には「Over Quota」となってアプリが止まってしまう危険性が…。 そこで Check サーブレットの仕組みをいくらか変えて、複数ブログの更新チェックを一度にできるようにしてみた。とりあえず 10 件で。DatastoreService とか GoogleService とか、その他色んなリソースを使いまわせるので、パフォーマンス的にもいいかも。とか思って動かしてみると…

Request was aborted after waiting too long to attempt to service your request. Most likely, this indicates that you have reached your simultaneous dynamic request limit. This is almost always due to excessively high latency in your app. Please see http://code.google.com/appengine/docs/quotas.html for more details.

というログで、ションボリ。なんだこりゃと調べてみて、一番分かりやすかったのがこのページ。
 あのwarningは、リクエスト処理中に後続のリクエストが来てqueueにつまれ10秒以内に処理されなかったときに発生します。

 つまり、AppEgnineは30秒ルール以外にも、負荷が集中するときには、10秒以内に処理しないければいけないという10秒ルールも存在するのです。
ということなので、とりあえず 5 件ごとの更新チェックにしたところ、ようやく何も言われなくなった。登録ブログが次の上限 1736 件に迫ったら、また別の方法を考えないと…。

No comments:

Post a Comment