2010-11-16

CPU 使い過ぎ? - GAE 管理コンソール上の警告 (Blogger Glass)

管理コンソールに赤文字が!

前回(→「内部リンクを置き換える #2」)の実装を配備した後、管理コンソールを見に行くと、Dasshboard の Current Load のところに以下のスクショのように赤文字が出ていた。

GAE Admin Console
Dashboard の Current Load
「Avg. CUP (API)」が赤文字で表示されている。 黄色三角上にマウスカーソルを持っていくと「This URI uses a high amount of CPU and may soon exceed its quota.」という警告が出てくる。
Logs
Current Load で赤字になった URI をクリックすると Logs が開く。 cpu_ms と api_cpu_ms を使い過ぎているということらしい。

「/」というリクエスト URI の処理に時間がかかりすぎているようだ。この「/」は、「一覧」画面を表示するためのもので、つまりは「内部リンクを置き換える」機能の実装で変更を加えた部分でもある。「一覧」を作るために取得したフィードから、permalink と Post ID を取り出し、そのひもづけ情報をデータストアに書き出すという処理が付け加えられている。この処理に時間がかかっているようだ。

Quota Details で確認すると……

管理コンソールの「Quota Details」を開きリソースごとの「Daily Quota」を確認すると、どの項目も 0% のまま。「Rate」もすべて Okay となっている。リソースの割り当てを使い切りそうということではない。

困ったときはググってみる

何度かググってみて、Google グループの Google-App-Engine-Japan で関連しそうな情報を見つけた(→「ダッシュボードの「Current Load」の「Avg CPU (API)」が赤文字になる」)。これによれば、この赤文字はさほど気にする必要はないようだ。ただ、平均リクエスト処理に 1 秒以上かかるアプリには同時リクエスト数が 30 までという上限が科せられる、という点は覚えておいた方が良いかも。

GAE ではアプリへのリクエストがしばらく途絶えるとアプリのインスタンスが消される。その後にリクエストが届くと、アプリインスタンスを再生成することになり、このときは(インスタンスが存在するときにくらべると)処理時間がかかる。ログを見ていると、このアプリインスタンス再生成をともなったリクエスト処理のときにも警告が出ている。気付いていなかっただけで、単発の警告はこれまでも出ていたってことだ。これだけでどうにかなるなら、とっくになっている。

設計変更が必要か?

Current Load で赤文字が出るのは、「一覧」画面のリクエストで permalink と Post ID のひもづけ情報をデータストアに保存したときだけだ。一度保存してしまえば 2 回目以降のリクエストでは出なくなる。つまり、赤文字の警告が出るような状況は頻繁には起こらない。

仮に、「設定」画面等に「ひもづけ情報の保存」のためのボタンを設け、ユーザが明示的に指示するようにしたとしても、そのリクエストの処理ではやはり赤文字が出ることになるだろう。

データストアの呼び出しを減らすのは効果があるだろうか? 今の設計/実装では、「一覧」画面のリクエストでは一回につき最大 25 回のデータストアの書き込みが起きる(ページごとの記事数が 25 なので)。データモデルが以下のようになっているから(src/model.py より)、記事の数だけデータストアに書き込むことになる。

class PairOfLinks(db.Model):
    """
    PairOfLinks binds a permalink to a post_id of a blog specified
    with a blog_id.
    Each entity of PairOfLinks must be created specifying a permalink
    as its key.
    """
    blog_id = db.StringProperty()
    post_id = db.StringProperty()

これを例えば一ヶ月単位でまとめて書き込むことにすれば、1 度のリクエストでせいぜい 2 回の書き込みで済む。書き込むデータの総量は変わらないものの、API 呼び出しの回数が 25 回から 2 回に減れば効果はあるかもしれない。その分、前処理やら後処理が複雑になるけれど。

保存先をデータストアから memcache に変えるのは有効だろうか? 処理時間は確実に短くなるはず。その代わりに「ひもづけ情報」が揮発性になってしまう。

そこで登場するのが Task Queue だ。

Programming Google App Engine」、13. Task Queues and Scheduled Tasks より
Enqueueing a task is fast, about three times faster than writing to the datestore. [...snip...] For example, an app can write a value to the memcache, then enqueue a task to persist that value to the datastore. This saves time during the user request, [...snip...]

ここに挙げられている例がぴったり当てはまる。ユーザが「一覧」と「記事」画面を行ったり来たりしている間は memcache が有効だし、セッションが終了または長く中断する間に Task で「ひもづけ情報」がデータストアに書き出されるなら、次回のセッションにはデータストアから情報が取り出せるはず。

memcache、Task、データストア、という三段構えで対応するように実装してみようか。そのためには、Task と Queue について調べないと。

追記@2010-11-30

GAE の Task と Queue の使い方および、それを使った Blogger Glass の変更については以下の記事を参照のこと。

参考文献

Programming Google App Engine
Dan Sanderson
Oreilly & Associates Inc ( 2009-11-15 )
ISBN: 9780596522728

関連リンク

関連記事

0 件のコメント:

コメントを投稿