2008/06/02

これ、すごいっす。
The Memcache API - Google App Engine - Google Code

High performance scalable web applications often use a distributed in-memory data cache in front of or in place of robust persistent storage for some tasks. Google App Engine includes a memory cache service for this purpose.

http://code.google.com/appengine/docs/memcache/
何が凄いって仕様が凄い。
通常のset/getの他、dictとして格納出来るset_multi/get_multiもある。Tagtterの様にタグ毎にキャッシュしたい場合には持って来いなAPIです。
どうやらdangaをベースにしている様で、LiveJournalsourceforge、さらにはWikiPediaでも使われているライブラリらしいです。

さて、今日Tagtterにこのmemcache APIを使ってみました。
使い方としてはページをそのまま!Tagtterの場合、動的なコンテンツと言えばタグ、Vote、ユーザですが、これらが変更されない限りトップページタグページは変る事は無いのです。他の情報はjavascript(jQuery)で動的に取得しており、サーバには格納されていません。
どんなに大胆な使い方かと言うと
class TopPage(webapp.RequestHandler):
  def get(self):
    cache = memcache.get('tagtter_top_page')
    if cache:
      # キャッシュがあるならそのまま出力
      self.response.out.write(cache)
      return

    ・・・ 巨大なデータ処理 ・・・

    path = os.path.join(os.path.dirname(__file__), get_template(self))
    cache = template.render(path, template_values)
    # キャッシュに溜め込む
    memcache.set('tagtter_top_page', cache, cache_time)
    self.response.out.write(cache)

class AddTagsAPI(webapp.RequestHandler):
  def get(self, username):

    ・・・ タグの追加処理 ・・・

    # 結果を出力
    dump_json(self, { 'status': 'ok', 'message': 'done' })
    # キャッシュをクリアしてやる
    memcache.flush_all()
上記の様に、キャッシュがあればそのまま出力し、タグが追加されればキャッシュをクリアするという方法。
おかげでトップページタグページの表示速度が激変しました。
但し、ユーザ一覧ページ等は、pageというパラメータにより出力する内容が異なる為、このままでは対応出来ません。やっちゃうとどんどん同じページが表示されてしまいます。
今のところ、トップページとタグページにしか取り入れていませんが今後少しずつ取り入れて行きたいと思います。

ところで、公開されたAPIのもう一つImages APIも使ってみました。
使い方は簡単。
from google.appengine.api import images

...

image = images.Image(data) # input data
image.resize(100, 100)
image.rotate(90)
data = image.execute_transforms(output_encoding=images.JPEG)
現状、合成したり90度単位でない回転等は出来ませんが、コレ使えばなんでもありちゃんかいっと思った。いずれやる。

動いている物は以下
Image API Test
Posted at 18:00 | WriteBacks () | Edit
Edit this entry...

wikieditish message: Ready to edit this entry.






















A quick preview will be rendered here when you click "Preview" button.