appengine java night #3に行ってきた。 #appengine #ajn3

いやー今回も濃くておもしろかったですね。こんな濃い人が集まるApp Engine勉強会はたぶん日本でここが一番なんじゃないかと思います。
ソースを見るなり質問が飛ぶ飛ぶ!しかも普通の質問じゃないんですよね。裏でクラウドがどういう風になっているかを話したりするそんな勉強会。
今回はグリーの一井さんに会場をお借りしました。一井さん会場提供ありがとうございます。しかも11:30くらいまで付き合ってくれるなんてやさしすぐる。
 

おしながき

  • 本編
    • 私:実際に作ってわかったApp Engineの困ったところ
    • 竹嵜さん:ぶいてく流 スケーラブルアプリの作り方
  • LT(Lightning Talk?, Long Talk?)

実際に作ってわかったApp Engineの困ったところ

私が発表させていただきました。機会を与えてくれた皆さんに感謝します。
以下は資料の補足

  • バッチ処理も30秒以内
    • AppEngineはjoinできないことが移行の壁のように語られてるけどバッチ処理の壁の方が辛い
    • その壁を越えると同時に高速化されてスケールするアプリになる
  • TaskQueueで高速化 + 事前Key採番
    • TaskQueueを使う場合は事前Key採番の方法は私の中では鉄板
    • この仕組みは実はマスタ取り込みにおすすめ。
      • App Engineではまだデータのインポートが弱いのでロジックで登録することになる。
      • csvをループさせて一レコードに対して資料と同じ考えで1TaskQueueで処理してマスタ取り込みするのがおすすめ
  • バッチ終了の判断
    • 実はカウントを使用しない方法がある。
      • 事前Key採番の仕組みを使ってKeyを採番する
      • 採番したKeyをキャッシュやDatastore、TaskQueueのパラメータなどで保持しておく
      • あとはそのKeyに対するEntityがすべてDatastoreService#getで取得できれば全部バッチが終わったという事がわかる。
      • 注意点はキャッシュならキャッシュが消えていないか、TaskQueueの場合はパラメータは10kのサイズ制限があること。
      • この方法が実は一番のおすすめだったりするのだが、ページ構成の都合上説明できなかった。
  • メール送信で二重送信の可能性があるについて資料では説明を記載していないので補足する。@shin1ogawaさんがばっちり解説してくれている。こういうこと

@shin1ogawa Datastoreにメールをキュー(未送信状態=ON)→メール送信→OKなら未送信状態をOFFに設定…という方法だと、最後の未送信状態をOFFにするDatastoreの操作が失敗した時に、同じメールが複数回送信されてしまう可能性がある。 #ajn3

    • これは別にこのやり方が悪いと言うわけではなくメール送信の場合は下記のいずれかをとる必要があるという事
      • MailApiがエラー時にメールされない。 0 or 1回のメール送信。
      • Datastoreがエラー時に二重送信される。 1回以上のメール送信。

ここで一番やっかいなのはDatastoreが読み取り専用(CapabilityDisabledException)になることがある事。googleがメンテナンス時にはこういう事が起こるようだ。これに対する対策をしていなかった場合に後者の方針を取ったアプリは大量のメール送信になる。

  • メール送信でスケールしない件について
    • 課金設定をすれば1分間で32回の制限は簡単に超えられる。しかも、実はたいていの場合お金はかからない。課金対象になるのは24時間あたり170万回以上のメールを送信するようになってからなのだ。
    • メール回数をコーディングするのはよくない。制限にあわせてソースを変更するなんてApp Engineの自動スケールアウトの考えから間違っている。そうメールの正しい実装はTaskQueueを用いたメール送信だと思う。当初はTaskQueueがなかった事とエラー(OverQuotaException)は出ないように実装すべきだと考えていた事からこの実装になっている。しかし、App Engineを使ってわかるのはエラーは出るものとして考えてエラーが出たらリトライするように実装するのが正しいApp Engineの使い方じゃないかと考えを改めている。
  • Entity Group
    • 雨の日めーるではUserとMailQueueはEntity Groupにした
    • Entity Groupがどんな時に使っていいのか、どんな時に問題なのかを少しは伝えられたらと思って資料は記載した。私はajn1でEntityGroupがKeyで構成されていることに衝撃を受けたがまだ使うには至らなかった。動きがわからないものは使えないと思ったのだ。Keyの構成と排他処理の問題等を理解することでUserとMailQueueはEntity Groupにしてもいいという結論が出せた。
  • 最後にまとめ
    • App Engineについて話すにあたって制約はさけては通れない。しかし、制約をdisって使わないというのではなく制約をルールだと思って乗り越えると勉強になる部分が多くあってみんなも使ったらいいよという思いで記載した。
      • 「制約ではなくルール。ルールを守りながらプログラムするゲーム。このゲームは必ず開発者を成長させる」
      • 野球やサッカーもルールがないとおもしろいゲームにならないよね?とか限られたルールの中でソフトウェアでどうできるかを競うような感覚をもって使ってみるのはどうだろうか?という思いがあった。
  • hidemonさんのセッション中にあった話のよいまとめ

(Memcache のlow level API)
contains はやらないほうがいい by ひがさん
(containsをするとネットワークアクセスが発生して遅くなる)


JDOだと関連をもとに勝手にentity groupを作ってしまっていて混乱のもと.byひがさん


transaction 開始後最初のget/putで そのときのタイムスタンプをどこかに取っておく.
commit のときに取っておいたタイムスタンプと同じかどうかを比較する.
ancestor query 以外のqueryではtransactionがかからない.keyに対するgetだとだいtransactionになる.
queryは本来複数の行を相手にしているので,そもそもどのentityグループにぞくしたqueryなのか定義できないから.
ancestor queryは entity groupに対するqueryなので,定義できるから.


KeyRange keys = service.allocateIds(KIND, 1);
<- これ,結構重い.まとめてやったほうがいい.1件20msぐらい.
String key = KeyFactory.keyToString(keys.getStart())

雨の日めーるの紹介

http://www.amenohimail.com

ちょっとサイトの説明とかあんまりしなかったのでちょっとだけさせて下さい。

  • 雨の日めーるは朝の天気予報が雨の場合に天気予報をメールしてくれるサービスです
  • 雨の日めーるのコンセプト
    • サービスは登録するだけで受けられる事
    • サーバがその人に必要な情報を必要なタイミングでユーザに提供する
    • ユーザは能動的に何もする必要はない。サーバプッシュ型。
    • 登録は簡単にする。
    • 年代に関係なく誰にでも紹介しやすいサービスにする。

など思いがあります

  • 雨の日めーるは慣れると便利さが実感出来ると思います。
    • 朝メールが来てたら傘を持って行く。
    • 天気予報を見る必要はない。
    • 慣れるとメール本文はどうでもよくて着信があったかで人の動きを変える。

そんなサービスです。

登録はもちろん無料ですので良かったら使ってみてください。バグや要望はもちろんのこと、App Engineでどうやっている?とかあればレスを頂ければ嬉しいです。

そうそう、雨の日めーるは愛のあるサービスなんです。愛情込めて作ってます。開発のきっかけとなったエピソードがあっていつかお話する機会があれば話したいと思います。

ぶいてく流 スケーラブルアプリの作り方

資料はこちら

  • いきなりデモが凄すぎる。
    • 帳票イメージのWeb画面でそのままPDFを編集しているかのように修正できる。すぐにその画面をPDFとしてRESTで取れる。
      • なんぞこれ!
  • 俳句のところが笑えた。うまい。
    • 私もこういうネタ考えよう。
  • 目的重要。GAEやってると目的と全然関係ないことに時間をかけてしまう。

常に目的を忘れるな
GAEで作ることが目的ではない(本末転倒になりがち)
リニアにスケールしなければ意味がない
速くなければ意味がない
安くなければ意味がない

  • スケールするためにKindを複数をに分けてみた
    • この発想はなかった。会場からはKind分ける必要はないよという声もあった。しかし、今は何がいいのか何が悪いのかがわからない。なのでいろんな発想を見て意見できる場があるのは本当にステキ
  • アプリKey+Revision番号でユニークになるようにした
    • データを更新することなく常にInsertする手法
    • すべての操作をログとして残す。
    • 履歴管理によるトレーサビリティの向上につながる。
    • 内部統制の観点からもいい案だと思う。
      • Keyをしっかり理解してうまく使いこなしてる感じ
  • トランザクションの非同期実行、サービス指向アーキテクチャなどなど
    • 実際にApp Engineでここまで作り込んでいるのはまだ事例が少ないんじゃないかと思う。App Engineでもここまで出来るよという事がわかる。実際に仕事でやっている人の話が聞けるのはとてもためになる。
    • ただ、この部分はソースレベルでどのようにしたのかノウハウを公開してほしいところ。PDFのところは内緒らしい。。
      • PDF操作の既存ライブラリはGAEでは使えない事が多いのでノウハウを集めたいところ
  • Memcacheはあんまり早くない?
    • MemcacheのGET/PUTは15msほど、DatastoreのGET(20ms)
    • DatastoreのGETが想像以上に早いのでGETで対応できるところはキャッシュの必要なし
      • ※DatastoreのQueryは620msほどなので遅い
  • GAEのサーバインスタンスは4つ?
    • あっためる(一定の負荷をかけ続ける)とサーバのインスタンスは増えるらしい。
    • Googleに相談すると解決することも。ニュースバリューがあると対応はもっといいらしい。

スケールアウトの真実?

スケールアウトについての考察。大変興味深い内容だった。

  • 1リクエスト30秒以内以外に10秒制限の話
    • リクエストは一旦リクエストキューにたまる。
    • このキューは10秒以内にリクエスト実行されなかった場合は「Request was aborted after waiting too long」のエラーが出る
  • AppEngineが1instance/vm、1Thread/instance
    • 実はAppEngineでは1インスタンスで1リクエストしか受け付けていないのではないかという内容。ぶいてくさんの内容も考えてみるとそのように感じる。これはjavaをやっている人から見るとおどろきのアーキテクチャである。
  • スケールするためにはあっため重要
    • どうやればスケールするのかは今のところはわかっていない。負荷状態が続くと使用できるインスタンスが増えるようで負荷状態を続けることをあっためと呼んでいた。会場では「あっため。あっため。」を連呼していてかなり面白かった。

Kay (Python 版の framework) について

資料はどこかな?http://takashi-matsuo.blogspot.com/

  • LLTVでも話のあった陣痛がきたのでリリースタグをうった話。
    • Kayは子供の名前からとった。
      • この話個人的にかなり好きでLLTVでとても感銘を受けた。私も子供の名前でなにかを作ろうと思った。

pythonでのフレームワークでもAppEngineのspin upを早めるためにこんなことしてるとかそんな話が聞けたのが有益だった。

makeSyncCallでいろいろ試してみた

資料はこちら
潜れ、潜れ一番下まで潜るんだ。そこがあるまで潜り続けろ!一番低レイヤーを抑えれば何ができるのか。何ができないのかがわかるはずだ。
いやもー変態です。下記は名言です。

  • 「ほとんどの方がご存知のmakeSyncCall」
  • 「LowLevelAPIももぅダサイ!」(low level apiは@marblejenkaにとっては高レベルAPI

みんなお酒が入っていたせいか話が盛り上がりがピークにたっしていた。makeSyncCallはエンジニア心くすぐる最高のおもちゃですもんね。
そんな内容が見れるのはまーぶるさんのこのフレームワーク。興味ある人は必見です。

twitterのログ

この遠慮のない濃さが #ajn3 クオリティ。良くも悪くも。俺は #appengine に関する高速道路をつくりたいんだ。そのための努力は惜しまない

App Engineの高速道路をajnで作りたい!

    • そうそう。twitterで#appengineのハッシュタグをつけるとたぶんajnの誰かがかまってくれると思います。

過去のappengine java nightの発表資料などをみたい方はこちら(リンクメモです)