appengine ja night #13(atndのリンク)に参加してきました。関係者のみなさまお疲れさまでした。
appengine ja night に出席したのは初めてだったのですが、有意義な時間を過ごせました。
Beer Talk で、小心者のおいらは隅っこでまわりの様子見をメインにしていたのですが・・・(^^;
概要については上記リンクを参照していただくとわかるかと思いますが、セッション1、2に関してメモした内容などを。
- セッション1:mixi Xmas 2010
mixi Xmas は、宣伝してたりするのはわかっていたのですが、自分ではやってませんでした。
最近、mixi 放置気味ですし・・・って、まぁそんなことはおいといて。
2日半で 100万ユーザを集め、1週間で 200万ユーザになったそうです。
アプリの性質上、1日1回、通勤時間?とかにやる人が多かったのでは?という話で、朝の通勤時間帯にピークがきていたそうですが、瞬間最大風速的には、630 req/sec だったそうです(1度だけ1000を超えたとか)。
1ヶ月のリクエストは2200万〜2500万くらいで、総計が5.3億だったとか(12月だけだったかも)。
Datastore のサイズが 95GB、レコード数は2億オーバーとか。
クライアント:Flash
モバイル:HTML
サーバ:GAE/J + Slim3
その他:AWS / MPP
サーバ側、実装に費やした時間は2ヶ月ほど。設計とかもあったので、実質は1ヶ月半だったとか。
実装は1人で行ったそうです。
工夫した点とか。
1) 設定を static 変数に保持
memcache や Datastore に入れるのではなく、static 変数に設定を保持する。その変数には有効期限を設定しておいて、有効期限が切れたら memcache や Datastore から取得することで、設定をデプロイしたあと、時間差はあるが全インスタンスに浸透するとのこと。
即時性が求められる場合はデプロイしなおし。
2) mixiアプリの制約への対応
mixiアプリの場合、10秒制限、(モバイルの場合)JOIN禁止という制限にひっかからないようにいろいろと工夫したそうです。
Datastore がときたま遅くなるケースへの対応では、DatastoreServiceConfig にデフォルトのタイムアウト値を設定することで対処。
3) spin-up に対する施策
(検証できなかったので実際にはやらなかったそうですが)、spin-up かどうかの判定を static 変数を使って判定して、spin-up 時は、クライアントに再リクエストしてもらうようにすることで対応できるかも、とのことでした。
4) やらなかったこと
カスタムインデックスの使用とマージジョイン。こちらは過去にはまったことがあったからとのことでした。
task queue の多用。まったく使わなかったわけではないが、限定した場面でのみ利用したそうです。
はまった点。
(モバイルの話)PVを取得するために、透明画像をGETするログを集めることで実現。最初は別のGAEアプリにリクエストしていたが、コストが予想外にかかった(言っちゃダメだそうです)ので、結局は Amazon EC2 に Apache たてて、Apache のログを収集する形で行ったとのことです。
Key の命名で、タイムスタンプをプレフィックスに設定していたら、同じ時間帯のデータのキーが似通ってしまうため、Datastore 上同じ tablet にデータが固まり、Tablet Server 分割が発生、結果パフォーマンス低下という事態が発生した。
ハッシュ値をプレフィックスにすることで解決したそうです。
この問題、Key 自動裁判の場合でも起きる「かも」、とのことです。
まとめ。
・GAE はパフォーマンスがどんどん改善されています。使えます。
・ソーシャルアプリに向いている
・ログはちょっととりにくい
・Slim3 最高!
- セッション2:The Actress
こちらは LUX のプロモーションアプリとのこと。
これまで LUX のターゲット外?だった10代、20代にアプローチするという目的で、mixi を選んだそうです。
すごくわかりやすいターゲッティングですね。
こちらは現在進行形のアプリなので、現時点での話。
・ユーザ80万人以上
・DAU 10万人くらい(Daily Active User)
・1日、1000万〜1500万リクエスト
・瞬間最大風速:200〜300 req/sec
だそうです。
mixi Xmas と比べて、1回訪問したらだいたい10分くらい、1日平均 4回くらい遊んでもらえているそうですので、1人1日40分くらい使われているそうです。
構成。こちらのサーバ側は Python を利用されているようです。
クライアント:Flash
モバイル:HTML
サーバ:GAE/Py + Kay
苦労した話。
※私は Python には明るくないので、とりあえずメモ。
DeadlineExceededError が多発した。
このエラーはどこで起きるかわからないので、どこでエラーが起きても大丈夫なようにしましょう。
static 変数の設定は Atomic に行いましょう。
※なかの人の話によりますと、現在、このエラーが発生するとインスタンスが自動で落とされるようになるので、今回説明したような現象は起きないでしょう、とのことです。
Import Error の連続発生。
ロード中に、Jinja2 内部で DeadlineExceededError が発生したときに、フレームワーク内部でこのエラーを握りつぶしてしまっていたために起きていた現象。フレームワーク作者のほうに報告して修正してもらったそうです。
ただ、こちらもインスタンス死亡対象となるそうですので、遅延ロードや warmup を駆使して DeadlineExceeded が発生しないようにしないといけませんね、とのことです。
メモリ使用制限にひっかかった。
だいたい 150〜200MB 使用時にインスタンスが落とされたそうです(200〜300MB)だったかも。
対策としては、task queue で分けるなどして1リクエストの処理を減らす、遅延ロードを使う(使わないものはロードしない)、変数によるキャッシュを減らして memcache や Datastore を使う、といったことを行っているそうです。
マイミクが多く、そのマイミクの多くが同アプリで遊んでいるときに発生するというお話だったと思いますが、ちょっと仕方ないような気も・・・(実際に作ったことがないので一部想像がつかないとも言ふ)
まとめ
・例外はハンドリングしましょう
・1リクエストの処理は小さく
・GAE はスケールするよ!
- セッション1、2のまとめ:GAE のメリット
1) スケーラビリティ
2) コスト
ダイナミックリクエスト、1000万リクエスト=100ドルくらい。
スタティックなリクエストについては AWS を利用している。
以上、とても有用な情報を得られることができました。
また次回もタイミングが合えば参加したいなぁ。
でもまぁ、その前に自分でちゃんとアプリケーションを作ったりしてレベルアップせねば。
もし間違いなどがあったらすみません。