29
Google App Engine 最新情報 松尾 貴史 Google Developer Day 2010年9月28日

Google Developer Day 2010 Japan: Google App Engine についての最新情報 (松尾貴史)

Embed Size (px)

DESCRIPTION

Google App Engine で最近リリースされた機能 1) Task Queue の強化 2) Multitenancy 3) 高速イメージ配信 4)カスタムエラーページ 等について紹介します。

Citation preview

Page 1: Google Developer Day 2010 Japan: Google App Engine についての最新情報 (松尾貴史)

Google App Engine 最新情報松尾 貴史

Google Developer Day2010年9月28日

Page 2: Google Developer Day 2010 Japan: Google App Engine についての最新情報 (松尾貴史)

アジェンダ

自己紹介

Python pre-compilation

Task Queue の強化

高速イメージ配信

カスタムエラーページ

count と query での 1000 件制限の撤廃

Multitenancy

知らないかもしれない注意点

Page 3: Google Developer Day 2010 Japan: Google App Engine についての最新情報 (松尾貴史)

自己紹介

Googleデベロッパーリレーションデベロッパーアドボケイト松尾 貴史[email protected]

Page 4: Google Developer Day 2010 Japan: Google App Engine についての最新情報 (松尾貴史)

Python pre-compilationPython script の事前コンパイルができるようになりました。

やり方は app.yaml に下記2行を追加するだけ

derived_file_type:- python_precompiled

どのくらい変化があるのか?

411ms 621cpu_ms →

Page 5: Google Developer Day 2010 Japan: Google App Engine についての最新情報 (松尾貴史)

Python pre-compilationPython script の事前コンパイルができるようになりました。

やり方は app.yaml に下記2行を追加するだけ

derived_file_type:- python_precompiled

どのくらい変化があるのか?

411ms 621cpu_ms → 247ms 271cpu_ms

Page 6: Google Developer Day 2010 Japan: Google App Engine についての最新情報 (松尾貴史)

Task Queue の強化

queue.yaml で total_storage_limit が指定できるようになりました。下記のように記載します。

total_storage_limit: 100Gqueue:- name: default rate: 50/s

Task Queue で使えるストレージ容量が設定できます。B は byte, K は kilobyte, M は megabyte, G は gigabyte, T は terabyte です。デフォルト値は 100M です。

Page 7: Google Developer Day 2010 Japan: Google App Engine についての最新情報 (松尾貴史)

Task Queue の強化

total_storage_limit: 100Gqueue:- name: default rate: 50/s

Page 8: Google Developer Day 2010 Japan: Google App Engine についての最新情報 (松尾貴史)

Task Queue の強化

Version 1.3.4 までのTask Queue ではアプリケーション毎に最大 50qps でした

Page 9: Google Developer Day 2010 Japan: Google App Engine についての最新情報 (松尾貴史)

Task Queue の強化

Version 1.3.5 からは queue 毎に最大 50qps 

Page 10: Google Developer Day 2010 Japan: Google App Engine についての最新情報 (松尾貴史)

高速イメージ配信

blobstore に保存したイメージを高速に配信する仕組みです。images.get_serving_url(blob_key, size=None, crop=False)

パブリックで推測しずらい URL が生成され、キャッシュが効きやすいです。生成された URL は元の blob が存在するうちはずっと使えます。URL をいじる事で resize, crop など行えます。resize や crop にかかる CPU コストは課金されません

=SXX=SXX-C

Page 11: Google Developer Day 2010 Japan: Google App Engine についての最新情報 (松尾貴史)

高速イメージ配信 Sample

モデル

class AlbumImage(db.Model): title = db.StringProperty() original_image_url = db.StringProperty(indexed=False) thumbnail_url = db.StringProperty(indexed=False) created_at = db.DateTimeProperty(auto_now_add=True)

Page 12: Google Developer Day 2010 Japan: Google App Engine についての最新情報 (松尾貴史)

高速イメージ配信 Sample

ハンドラー - フォームとサムネイルを表示

class MainHandler(webapp.RequestHandler): def get(self): upload_url = blobstore.create_upload_url('/upload') self.response.out.write("""<html><body><form action="%s" method="POST" enctype="multipart/form-data">Title: <input name="title"><br>Upload File: <input type="file" name="file"><br><input type="submit" name="submit" value="Submit"></form>""" % upload_url) album_images = AlbumImage.all().order("-created_at").fetch(5) for album_image in album_images: self.response.out.write(album_image.title + "<br>") self.response.out.write('<a href="%s"><img src="%s"></a><br>' % (album_image.original_image_url, album_image.thumbnail_url)) self.response.out.write("</body></html>")

Page 13: Google Developer Day 2010 Japan: Google App Engine についての最新情報 (松尾貴史)

高速イメージ配信 Sample

ハンドラー - アップロードされた画像を処理

class UploadHandler(blobstore_handlers.BlobstoreUploadHandler): def post(self): # 'file' is file upload field in the form upload_files = self.get_uploads('file') blob_info = upload_files[0] original_image_url = images.get_serving_url(str(blob_info.key())) uploaded_image = AlbumImage( title=self.request.get("title"), original_image_url=original_image_url, thumbnail_url=original_image_url+"=S320" ) uploaded_image.put() self.redirect('/')

Page 14: Google Developer Day 2010 Japan: Google App Engine についての最新情報 (松尾貴史)

カスタムエラーページ

app.yaml にて設定できます。

error_handlers: - file: default_error.html

- error_code: over_quota file: over_quota.html

有効な error_codeover_quotados_api_denialtimeout

Page 15: Google Developer Day 2010 Japan: Google App Engine についての最新情報 (松尾貴史)

1000件制限

カウントと fetch の limit で 1000 以上指定可能

q = MyModel.all()number = q.count(100000)

entries = q.fetch(100000)

システムの30秒制限にてタイムアウトする可能性はあります

Page 16: Google Developer Day 2010 Japan: Google App Engine についての最新情報 (松尾貴史)

Multitenancynamespace を指定して実行できるサービス

datastorememcachetaskqueue

注意: blobstore では namespace を使えません。

Page 17: Google Developer Day 2010 Japan: Google App Engine についての最新情報 (松尾貴史)

Multitenancygoogle.appengine.api.namespace_manager で namespace を指定できます

namespace_manager.set_namespace()namespace_manager.get_namespace()

namespace に指定できる文字[0‑9A‑Za‑z._‑]{0,100}_で始まる namespace はシステム予約

Page 18: Google Developer Day 2010 Japan: Google App Engine についての最新情報 (松尾貴史)

MultitenancyMultitenancy 以外のユースケース

ユーザー情報を namespace で分ける管理用のデータとアプリケーションデータを分けるテストと本番運用でデータストアを分けるひとつの App Engine スロットで複数のアプリケーションを運用する

Page 19: Google Developer Day 2010 Japan: Google App Engine についての最新情報 (松尾貴史)

Multitenancy一時的に namespace を設定したい場合

namespace = namespace_manager.get_namespace()try: namespace_manager.set_namespace('-global-') some_operation()finally: namespace_manager.set_namespace(namespace)

Page 20: Google Developer Day 2010 Japan: Google App Engine についての最新情報 (松尾貴史)

MultitenancyGoogle Apps のドメインで namespace を分けたい場合のパターンappengine_config.py にて下記のようにします。

from google.appengine.api import namespace_manager# Called only if the current namespace is not set.def namespace_manager_default_namespace_for_request(): # The returned string will be used as the Google Apps domain. return namespace_manager.google_apps_namespace()

appengine_config.py ?

Page 21: Google Developer Day 2010 Japan: Google App Engine についての最新情報 (松尾貴史)

appengine_config.pyApp Engine の設定システム

この設定システムはライブラリの動作をそのライブラリの使用者が設定によって変更できる仕組みです。

google.appengine.api.lib_config.py を読むと使用方法が分かります。

Page 22: Google Developer Day 2010 Japan: Google App Engine についての最新情報 (松尾貴史)

appengine_config.py例えば mylib.py を appengine_config.py 対応にするには

mylib.py:

from google.appengine.api import lib_config

config_handle = lib_config.register( 'mylib', {'do_something': lambda obj: obj})

def do_something(obj): return config_handle.do_something(obj)

Page 23: Google Developer Day 2010 Japan: Google App Engine についての最新情報 (松尾貴史)

appengine_config.pydo_something を上書きするにはappengine_config.py:

def mylib_do_something(obj): # implement as you like # ...

Page 24: Google Developer Day 2010 Japan: Google App Engine についての最新情報 (松尾貴史)

Multitenancyテスト用に namespace を分ける...

クラウド上でもユニットテストがしたいhttp://code.google.com/p/appengine-py-testhelper/wiki/GAETestBasesetUp で set_namespace("test") などとすれば良い?でもテストする側のコードで set_namespace("-global-") などとしたらどうなる?ネームスペースを二つに分けて、テスト専用の部分とユーザーランド専用の部分を別々に設定できるようにすれば良い?

そこで...

Page 25: Google Developer Day 2010 Japan: Google App Engine についての最新情報 (松尾貴史)

Multitenancymy_namespace_manager.pyimport os

from google.appengine.api import namespace_manager

current_namespace = ""test_namespace = ""pattern = "%s--%s"

def _set_namespace(): if test_namespace: namespace_manager.set_namespace(pattern % (test_namespace, current_namespace)) else: namespace_manager.set_namespace(current_namespace)

def _initialize(): if not namespace_manager.get_namespace(): initialize("")

続く

Page 26: Google Developer Day 2010 Japan: Google App Engine についての最新情報 (松尾貴史)

Multitenancy(続き)

def initialize(namespace): global test_namespace, current_namespace current_namespace = namespace test_namespace = ""

def get_namespace(): return current_namespace

def set_namespace(namespace): global current_namespace _initialize() current_namespace = namespace _set_namespace()

def set_test_namespace(namespace): global test_namespace _initialize() test_namespace = namespace _set_namespace()

Page 27: Google Developer Day 2010 Japan: Google App Engine についての最新情報 (松尾貴史)

Multitenancyappengine_config.py では

import my_namespace_manager

def namespace_manager_default_namespace_for_request(): ns = namespace_manager.google_apps_namespace() my_namespace_manager.initialize(ns) return ns

Page 28: Google Developer Day 2010 Japan: Google App Engine についての最新情報 (松尾貴史)

知らないかもしれない注意点

平均 1000ms で Response を返すアプリケーションのみ AutoScale します。

実際には 800ms を目指してください。400ms くらいだと理想的です。

Query per minutes limit課金をオンにしたアプリケーションの最大 qpm は 500 qps のスパイクをさばける程度に制限されています。それ以上必要なら相談してください。

Page 29: Google Developer Day 2010 Japan: Google App Engine についての最新情報 (松尾貴史)

Thanks

Takashi MatsuoGoogle, [email protected]