Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Play Scala on AWS, C10K and DevOps

Play Scala on AWS, C10K and DevOps

arai-yusuke

April 23, 2016
Tweet

More Decks by arai-yusuke

Other Decks in Technology

Transcript

  1. C10K インフラ設計に問題がなくてもクライアントが1 万超 えだしたらサー バー パンクします問題 Web 2.0 のころから既に問題提起されている Netty

    (Java), Node.js, Play (Java, Scala) などのアプリケ ー ションフレー ムワー クがこの問題に挑戦してきた 文脈によって意味が微妙に異なるタイプのワー ド
  2. スマホ 日本国内のスマホ普及率は49.7%(2015/8 日経BP) 5000 万人以上がスマホを通じてネットにアクセス 日本で( ひいては世界で) もっとも普及ている「 イン ター

    ネットにつながったデバイス」 1 日の平均的なスマホ利用時間は2 時間くらい 10 代、20 代にフォー カスすると5 時間くらい(!) 女子高生にフォー カスすると7 時間くらい(!?)
  3. スマホアプリの受託開発 B to B to C スマホ普及率の上昇に比例して、KPI 目標数値も上昇 してきている 初年度インストー

    ル数目標は100 万のオー ダー 目標達成時には100,000 MAU 以上が容易に想定される MAU = Monthly Active User( 月間アクティブユー ザー)
  4. スマホアプリの特性 スマホアプリと《 モバイルプッシュ通知》 は切り離せま せん。 B2B2C における顧客は「 エンドユー ザー と円滑に

    コミュニケー ションをとる方法」 を求めています。 彼らにとって、 その問題のソリュー ションのひとつがス マホアプリであり、 その機能の中でも《 プッシュ通知》 はとても魅力的なコミュニケー ション方法だからです。
  5. プッシュ通知のリター ン プッシュ通知にはリター ンがあります。 エンドユー ザー が通知に反応してアプリを開いた結果、 バックエンドの API やCDN

    へのアクセスが発生します。 100 万件のプッシュ通知を発行した場合、10% のアクテ ィブユー ザー が一斉に反応すると瞬間的に10 万のアクセ スがバックエンドに集中します。
  6. 先ほどの100 万件の例で言えば、15 分毎に1 万ユー ザー ず つ配信する負荷分散があり得ます。 この場合は延べ1 日 以上の配信時間がかかります。

    ここまで極端な例でなくとも、 数時間単位で配信に時間 がかかることは、 顧客にとって受容しがたい場合がほと んどです。
  7. C10K のソリュー ション AWS 2 Tier チー ム全員がAWS のエキスパー トである前提。

    アプ リが複雑化する。iOS / Android で全く同じビジネス ロジックを書く必要がある。 AWS Lambda + Amazon API Gateway プロダクション適用はまだ厳しい。 本当にリソー ス 間のトランザクションが不要かの精査が難しい。 C10K に答えられるアプリケー ションの構築 ✔
  8. PLAY を正しく使う … ために、 以下の点に配慮して開発を進めました。 同期的なI/O の禁止 I/O のタイプ毎にExecutionContext ※を分ける

    Request-Response 形式以外の処理はAkka Actor に切り分 ける。 ※ ExecutionContext は、 平たく言えばスレッドプー ルです。Scala のFuture と密接に関係します。
  9. 壁2 スレッドプー ルの数が多くなり、 最適な設定値を探す のに苦労した ExecutionContext を細かく分割したのは高RPS に対処 する上でとても有効だったが、 副作用として設定が

    複雑になった 基本的には、I/O 処理委譲先のスルー プットを考慮 してスレッド数を決めていく 低IOPS だけど集中する予定ならスレッド数多め 高IOPS ならスレッド数低め
  10. 壁3 Future のシリアルな結合数が多すぎるとアウト 数十回のAPI 呼び出しの結果を集約して返す処理 Future はMonadOps なので、 とりあえずflatMap で結

    合したくなる もちろんシリアルに処理されるから超遅い いわゆる「Applicative で十分パター ン」 ぽいのだけ れど、 使っているのはscala.concurrent.Future 結局実装をまるっと変えるはめになった。 実力不足 感があった
  11. その他のハマった罠 Redis クライアントライブラリ(scala-redis) がデフォ ルトでスレッドセー フじゃなかった Akka のFault Torelance が難易度高い

    でステー ト持っちゃったり Amazon Linux でJava 起動するとデフォルトのopen file limit が4096 だった(※ 知ってたらハマらない) AWS のAPI 性能がボトルネックになる箇所もあった
  12. Golden AMI 方式 Packer にAnsible Playbook を実行させ、 アプリバンドル 済みAMI を作成

    このAMI をGolden AMI と呼ぶ CFn により、AutoScaling Group のRolling Update で Golden AMI のインスタンスをデプロイする Infrastructure as Code
  13. CodeDeploy の利用 「Golden AMI 方式」 で作成したAnsible Playbook を流用 CodeDeploy を利用することでインスタンスの

    Stop/Start なしでデプロイ アプリを再起動するshell script は自分で書く 速度的に優秀だが、 堅牢さでGolden AMI 方式に劣る http://aws.amazon.com/jp/documentation/codedeploy/
  14. デプロイ方式 顧客がどの程度の堅牢さを求めているのかで変わる。 開発環境 ステー ジング環境 本番環境 案件A Ansible ※ Golden

    AMI Golden AMI 案件B CodeDeploy Golden AMI Golden AMI 案件C CodeDeploy CodeDeploy CodeDeploy ※ Dynamic Inventory(ec2.py) の利用
  15. EB は使ってないの? 使っています。 ただし、JVM アプリのデプロイには使っていません。 Ruby on Rails で作成されたCMS( 管理画面)

    などの デプロイに使っています。 EC2 インスタンスにどの程度のカスタマイズが必要か、 が大きな基準です。 ほとんどカスタマイズが要らない& アプリもそんなに複雑でないなら、EB がマッチします。 BCP の有無も一つ基準になるかもしれません。