@thorikiriのてょりっき

@thorikiriがWebとかAndroidとかの技術ネタや本を読んだブログです

appengine ja night #23 #ajn23 に行ってきました

初めてGoogle本社に行って来ました。
と言うことで、メモったことなどを投下します。

Optimizing Your App Engine App (with Appstats)

資料 → http://proppy-appstats.appspot.com/

  • App Engine アプリの最適化と Appstats
  • アンチパターン 1
    • UserのKindにnameとdataプロパティを持つケース
    • nameでクエリー実行する。
    • 結果は、1回のリクエストで2回のデータストアのリードが発生している
    • なぜでしょうか?
    • queryで検索した場合には、Indexを読みに行ってから、実体を読みに行くから合計で2回見に行くことになる
    • 1件しかないことが事前にわかっている場合には、IDで検索するべきです
    • IDであれば1回のReadで済みます
  • アンチパターン 2
    • Index Propertyを使いすぎるケース
    • デフォルトではインデックスが作成されます
    • User Kindのsecret等のpropertyのような、検索キーにならないのにIndexを作成してしまう
    • secretを更新してまたputすると、Datastoreへのwriteが9回も発生してしまう
    • indexed=falseにしておくと、writeは3回で済むようになる
    • これはupdate操作のために、Indexを削除してから、propertyごとにIndexをwriteするため
  • アンチパターン 3
    • Entity全体に対して検索するのはさける
    • User Kindに、city, email, phoneのpropertyがあるケース
    • 2つのEntityを作っておく
    • Londonに住んでいる全てのユーザのemailが知りたい場合
    • 3回のreadが発生する
    • projection queryでemailと指定しておくと、readの回数は3回で変わらないが、small readになる
    • Indexから直接読み込ませることが出来ることになる
    • ただし、必ずしも良いわけではない。
    • writeの場合にはpeopertyをIndexに書き込むコストが発生することは忘れないでください
    • すでにインデックスされているpropertyの場合には有効です
  • アンチパターン 4
    • 20人のUserのEntityがある場合、10人にクエリ、さらに残りの10人にoffsetを指定してクエリする
    • 結果32回のクエリが発生する
    • cursolを使ってみましょう。
    • fetch_pageとcursolを使えば、Readの回数が23回に減る
    • offsetを使用した場合の動作は、offsetの前全部readしてから捨てている
    • もし、offsetを大きい値にすると、ものすごくコストがかかってしまう
    • 一方カーソルを使えば、前回のクエリからやるので早く安くなる
  • アンチパターン 5
    • どんな時もDatastoreから検索する
    • putして、すぐgetするような場合
    • memcachedを使えば改善される
    • User Entityをputした後、memcachedに入れてしまっておけばよい
    • 読むときは、memcachedを見て、なければDatastoreから取ってくるようにする
    • もっと良いPythonでの方法はライブラリを使うこと
      • memcachedとOnMemoryで持つようになり、memcachedの読み込みもなくなる。
  • アンチパターン 6
    • RPC個別実行してしまう
    • 100個のEntityをputする場合
    • 1個1個をそれぞれputするとすごいコストがかかかる
    • 100個のEntityを予め作成してから、一度にputすることで軽減出来る
    • さらにput_asyncを利用することで、並列にputすることも出来る
    • put処理をしている間に別のことができるようになる
      • 処理を待つ場合はwaitモードを使う必要がある
    • put_multiまたは、put_asyncでバッチモードを使って、並列モードでやればRPC呼び出しが減る
    • 他のRPCを使うAPIにも同じ事が言える
  • アンチパターン 7
    • RPCを順番に実行してしまう
    • 3つのURLフェッチを順番に書くと、順番に実行されてしまう
    • ndbのcontextオブジェクトを使えば、並列に実行することが出来る
    • futuresで終わるのを待てば良い
    • 3つ分の時間ではなく、一番遅い時間で済むようになる
  • アンチパターン 8
    • Parentがあって、Parent実行後にエラーが発生した場合に不整合になる
    • 本当は、2つのEntityをグループ化したかったけれども、望ましくない状態になってしまう
    • こういう場合にはトランザクションを使う必要があります
    • functionを作って、@nbb.transactionalを指定する
    • トランザクションとは、全てのオペレーションを実行するか、何もされないかである
    • TaskQuereでも同じことが言える
  • アンチパターン 9
    • 同じトランザクションでUpdateとReadをしてしまう
    • Readの結果、なぜかUpdate前のデータが取れてしまう
    • 同じトランザクションで削除後にReadした場合にも、取得出来てしまう
    • トランザクション中に、getするtrannsationが開始された時点のスナップショットをgetする
    • なので、トランザクションの外で取る必要がある。
    • ndbの自動キャッシュ機能を使う場合にも中が必要
  • アンチパターン 10
    • すごい重要
    • Global Queryは避けること、整合性が重要な場合は特に
    • 変更しても、古いデータが取れるケースがある
    • 更新の動作は内部的にIndexを更新してからレプリケーションするので反映が間に合わない事がある
    • レプリケーションされるまでには時間がかかるので、クエリーを実行するたびに結果が変わってしまう可能性がある
    • この場合には、AnsesterQueryを使う
    • 親のEntityを指定すると良いです
    • しかしながら、トレードオフがあり、1秒間に1回の書き込みしか出来ない
    • 別の方法keys_get & get_multiで取ればOK
    • KeyOnlyQueryを実行し
    • 取得したKeyでget_multiで検索すると、古いデータが検索されることがなくなる。
  • さらに
  • QA
  • いくつまでputはまとめられるの?
    • 自動的にチャンクを作ってやってくれるみたいです
    • ndbライブラリでやってくれるらしいです
  • Java
    • slim3とかでやってくれるんじゃないの?
    • 500位で区切ってたと思う
    • 昔はそれ超えるとエラーになってたから
  • AppStats使うとパフォーマンスは遅くなるの?
  • キーは一位じゃないらしいですが、本当?
    • EntityGroup内では一位ですよ。
  • キーを削除した場合に、再利用されるケースはありますか?
    • 微妙です
    • データストアの仕組みとして、Keyの辞書順でソートされているので、一箇所に溜まってしまうことがあるので
    • 採番は自分でやったほうがいいです。
    • データストアチームでは、自動採番を実装中です。
    • 将来的には新しいAPIを呼べばいいようになると思います。
  • WebApp2のキーがNumericキーだったけど、大丈夫ですか?

Google Compute Engine 最新動向と App Engine 連携

資料 → appengine ja night 23 Jan 2013: Compute Engine what's new and integration with App Engine - Google スライド

  • 目次
    • Google Compute Engineについて
    • Google I/O 2012からのアップデート
    • App Engineとの連携について
  • Google Compute Engine
    • Googleのインフラで動かすLinuxで、Linuxで動けばなんでも動く感じ
    • VMとStorageとネットワークが提供されている
  • アクセス方法
    • APIの上で、コマンドラインアプリケーションがあり、gcutilと言う
    • APIs Consoleの中でCompute Engineは使えます
    • GoogleのClient Librariesでサポートされている
    • これらはAPIを呼び出している。RESTなHTTPとJSONAPIです
  • プロジェクト
    • VMLinuxです
    • Rootアクセスしてなんでも出来ます
    • Modern CPUで1, 2, 4, 8を選べるし、メモリも選べる
    • ネットワークは、2つ分類されている
    • PrivateネットワークとInternetにつながるネットワーク。設定次第で、どこにつながるか設定出来る
    • Privateの場合、Compute Engine内のDNSに名前をつけているので、インスタンス名でアクセス出来る
    • Storageは、PersitentDisk、LoclaDisk、CloudStorageがある。
      • Persistent:永続化される
      • Ephemeral:テンプで消える、ここに保存するといつかなくなるよ
    • または、App Engine Datastoreなどを使ったり色々出来る
  • デモ
  • Google I/O 2012からのアップデート
    • 変わってないこと、Limited Previewのまま
    • 最初はCPUとメモリの割り当てが固定でした
    • しかしながら、ソフトウェアによっては、何を使うかが違うので、色々なタイプが選べるようになりました
    • テンポラリストレージがないものもあります
    • IPアドレスをつなぎ替えることが出来るようにもなりました
      • アプリのバージョンアップの時に使えそうです
    • Read Only Persistent Disk
      • 書き込みは1つのものにしかつながらないけれども、読むだけのものであれば、いくつでもつなげることが出来ました
      • データを準備してから、他のマシンにつなげたり
      • 両方一変にはできません。ReadOnlyかRewirteかどちらかしか使えません。
      • Diskのスナップショットも可能です。5Gしか使ってなければ5Gしか消費しない
    • Better Command Line Scripting
    • And それ以外もあるよ
      • インスタンスのクローンが出来る
      • ヨーロッパのゾーンが出来た。アメリカとヨーロッパ
  • ComputeEngine と AppEngine
    • インスタンスを落とし忘れてしまうことがある
    • 特別なインスタンス以外は自動的に落としてしまうようなアプリケーション
    • Timeout Sample
    • AppEngine
    • ComputeEngine
      • 普通に立ち上がっているだけ
    • OAuth2 Auth
      • ユーザが使っている場合はOK、クーロンジョブの場合は、ユーザは居ない
      • 自分のアプリケーションだけ
      • でも、誰でも消せたら困るので、AppEngineの管理ユーザを作って、設定しておく
      • ComputeEngineのインスタンスにタグをつけて、落としてはいけないタグをは消せないようにしておけばいい
    • REST APIにプロジェクト名を入れるだけで、一覧が取得することが出来ます
    • cronのコードでは、Expiredだったら落とす
  • QA
    • ゾーンにアジアは追加されますか?
      • IssueTrackerに星をつけてください。
      • ドキュメントにあるらしいです。Starなりメールなりしましょう。
    • ハードウェア障害になったらどうなるの?
      • Terminateのステータスになります
    • そのままですので、ご自分で立ち上げてください
      • コントロールするソフトが必要になります
      • 自分で書くか、ライブラリを使うかしましょう
      • LifeScale?経由で色々出来るらしいです
      • オーケストレーション?のソフトウェア
      • HTTPのリクエストはAppEngineで、バックエンドはComputeEngineでやるのがおすすめかもしれない
    • Linuxディストリビューションは選べるの?
    • TaskQuereの連携以外は?
    • ComputeEngineからDatastoreの操作は出来るの?
      • 今はAppEngineのAPIをそのまま呼び出すことはできません。
      • HTTPのリクエスト経由で操作するように、作ってください。
      • 自分のアプリでやる方法と、EndPointsを使ってAPIとして公開する方法があります
      • JavaScriptやモバイル以外からも呼び出せるので、それでやる方法もあります
    • AppEngineとComputeEngineのゾーンの組み合わせは?
      • Googleのネットワーク上しか通らないし、出来るだけ早くなるようにしてます
      • わからないので、ご自分でやって試してみてください
      • ComputeEngineのレイテンシーが安定しています
    • Persistentディスクの種類は選べるの?
    • SSDとか選べるの?
      • 特に選べないようです
    • WebApplicationはAppEngine一択なの?
      • ComputeEngineとしては、特におすすめはしていないようです
      • アーキテクチャが合致するのであれば、別にWebアプリを作るのも問題ないです
      • 計画停止があるので、ご自分でIPの付け替えをするなどしてください
    • 無料枠あるの
      • 今はないです
      • Limited Previewは時間帯によって無料で使えたりするらしい
    • Amazon EC2との差別化は?
    • 1台のハードウェアを複数インスタンスで共有していると思うけど、1つのインスタンスが高負荷状態になると影響あるの?
      • あんまり影響ないようにがんばってるよ
      • 昨日エンジニアがテストしてたけどね。
    • VMはなんなの?
      • KVMをベースに色々と手を加えている
      • 今までGmailなどで培った技術の上にのっているよ。

Google API Expertが解説する Google App Engine for Java実践ガイド

Google API Expertが解説する Google App Engine for Java実践ガイド