2011年09月06日

GAE/Pでmemcacheを利用してデータアクセスを高速化。

GAE for Python で memcache を利用する方法を紹介する。memcacheとは早い話がキャッシュのことで、datastoreよりも高速に動作する。

以下はそのサンプルである。

お馴染みのゲストブックアプリだが、今回は未入力状態で投稿ボタンが押された場合は表示の更新と見なし、キャッシュから書き込み一覧を取得・表示する。もしキャッシュに書き込み一覧が無ければ、その時はデータストアから取得し、キャッシュに再登録するという流れである。言わずもがな、書き込みがあった場合はデータストアへ登録すると同時にキャッシュもクリアしておく。

<html>
<body>
{% for greeting in greetings %}
<p>{{ greeting.date }}<br/>
{{ greeting.content|escape }}</p>
{% endfor %}
<form action="/sign" method="post">
<div><textarea name="content" rows="3" cols="60"></textarea></div>
<div><input type="submit" value="Sign Guestbook"></div>
</form>
</body>
</html>

# -*- coding: utf-8 -*-
import cgi
import os
import logging
from google.appengine.api import users
from google.appengine.api import memcache
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext.webapp import template
from google.appengine.ext import db

class Greeting(db.Model):
content = db.StringProperty(multiline=True)
date = db.DateTimeProperty(auto_now_add=True)

class MainPage(webapp.RequestHandler):
def get(self):
# memcacheから取得
greetings = memcache.get("greetings")
# memcacheに無ければDatastoreから取得
if greetings is None:
greetings_query = Greeting.all().order('-date')
greetings = greetings_query.fetch(10)
logging.info(u"datastoreから取得。")
# memcacheに格納(有効期限は600秒)
memcache.add("greetings", greetings, 600)
logging.info(u"memcacheへ保存。")
else:
logging.info(u"memcacheを利用しました。")

template_values = {
'greetings': greetings
}

path = os.path.join(os.path.dirname(__file__), 'index.html')
self.response.out.write(template.render(path, template_values))

class Guestbook(webapp.RequestHandler):
def post(self):
# 入力があった場合のみdatastoreへ保存し、
# memcacheをクリアします。
if self.request.get('content'):
greeting = Greeting()
greeting.content = self.request.get('content')
greeting.put()
logging.info(u"datastoreへ保存。")
memcache.delete("greetings")
logging.info(u"memcacheからクリア。")
self.redirect('/')

application = webapp.WSGIApplication([
('/', MainPage),
('/sign', Guestbook)],
debug=True)

def main():
logging.getLogger().setLevel(logging.DEBUG)
run_wsgi_app(application)

if __name__ == "__main__":
main()


重要な部分だけを抜粋すると以下のとおりだ。
from google.appengine.api import memcache

# memcacheへ登録
memcache.add("greetings", greetings, 600)
# memcacheから取得
greetings = memcache.get("greetings")
# memcacheから削除
memcache.delete("greetings")


■追記 2011-11-10
memcache.add は、値が既に存在している場合には上書きをしない。
上書きさせたい場合は memcache.set を利用する。


Memcacheの詳細は、本家の「Memcache の使用方法」を参照すべし。


ここはひとつポチっとよろしく。
人気ブログランキングへ

エキスパートPythonプログラミング
Tarek Ziade
アスキー・メディアワークス
売り上げランキング: 4805


プログラミング Google App Engine
Dan Sanderson
オライリージャパン
売り上げランキング: 40082



posted by 寄り道退屈男 at 15:20 | Comment(0) | TrackBack(0) | GAE for Python
この記事へのコメント
コメントを書く
お名前: [必須入力]

メールアドレス: [必須入力]

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
※ブログオーナーが承認したコメントのみ表示されます。
この記事へのトラックバックURL
http://blog.sakura.ne.jp/tb/47768514
※ブログオーナーが承認したトラックバックのみ表示されます。
※言及リンクのないトラックバックは受信されません。

この記事へのトラックバック