Slide 1

Slide 1 text

GAE/Jで盛大に失敗する方法 GCPUG Okayama #11

Slide 2

Slide 2 text

森藤 敏之(もりとう) - @mmorito_0318 所属 - 株式会社エムネス - 遠隔画像診断センター - 医療支援サービス「LOOKREC」 イベント / 勉強会(担当) - GCPUG - 広島支部 organizer - Cloud Native Hiroshima

Slide 3

Slide 3 text

カープ優勝 おめでとうございます!

Slide 4

Slide 4 text

これは、GAE/J に魅了された者たちの物語です。 決してJavaを批判するものではないことをご理解ください。 はじめに

Slide 5

Slide 5 text

- サーバー: - データベース: - キャッシュ: - その他: Google App Engine(Java) Datastore Memcache 魅了された者 登場人物

Slide 6

Slide 6 text

- GAEのJava7 Runtime が2019年1月16日にShatdownする - 弊社アプリケーションの完全移行が2018年11月までに完了予定 発表のきっかけ

Slide 7

Slide 7 text

背景

Slide 8

Slide 8 text

- 人口100万人あたりのCT/MRI 設置台数 日本はダントツで1位 CT units per million population OECD Health at a Glance 2017 MRI units per million population

Slide 9

Slide 9 text

- 人口100万人あたりの放射線科医数 人口100万人あたりの 放射線科医数 日本はダントツで最下位 高額医療機器(CT/MR)と放射線科医の数

Slide 10

Slide 10 text

- データの保存や移行に莫大な時間とお金がかかる - 超高額で囲い込みの激しい医療業界の常識を撤廃 - 深刻な医師不足を解消するためのネットワーク作り - 機械学習などのIT技術を用いて、医療をサポートしたい クラウドへ移行する決意 Google Cloud Platform 上で構築へ いつでも、どこでも、だれにでも高品質な医療を提供する

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

順調に開発が進み…

Slide 13

Slide 13 text

Googleからの取材 2014年8月

Slide 14

Slide 14 text

あれから2年.... 我々はアプリのリプレイスを余儀なくされる。

Slide 15

Slide 15 text

なにがダメだったか

Slide 16

Slide 16 text

失敗① スピンアップ Frameworkなし : Slim3 : Slim3 + Struts(仮) : Slim3 + Struts(仮) + アプリ : 約2.5s 約3.3s(+800ms) 約5s (+1700ms) 約10s (+5000ms) 開発速度重視のため

Slide 17

Slide 17 text

- NoSQLであるDatastoreを非正規化したRDBのような使い方 主要なKindで自動インクリメントするKeyを設定 - KeyでGetできないため、 シングルプロパティインデックス・カスタムインデックスを貼りまくる 失敗② テーブル設計

Slide 18

Slide 18 text

- Queryでデータ取得することによる弊害 - Memcacheに載らない - トランザクションに引っかからない - Frameworkに搭載された禁断のインメモリフィルタに手を出す ※多めに取得してクライアントに返したいデータ以外を 捨てる 失敗② テーブル設計

Slide 19

Slide 19 text

- JSPの結果を返すリクエストがコンスタントに1秒を超えるようになる 失敗③ レスポンス

Slide 20

Slide 20 text

- 一方でAjaxを使い、signedURLを数百単位で要求してくるリクエストなど もあるが、スケールの恩恵を受けづらくなる 失敗③ レスポンス

Slide 21

Slide 21 text

- 軽い気持ちで30分毎に直近500件のデータを検索し、 他のテーブルに情報を更新する処理をCronジョブで実行 番外編 バッチ処理 翌月の請求額が 40万円UP↑↑

Slide 22

Slide 22 text

対応策

Slide 23

Slide 23 text

- インスタンスタイプを F1 → F2 へスケールアップ 愚策① チューニング - インスタンスが落ちるまでの時間を 最大(15秒)に設定 スピンアップやJavaのクラスロードに直面する リクエストを極力減らし、1秒でも速く処理させるため.....

Slide 24

Slide 24 text

- Memcache を 共有 → 1GB専有 に変更 愚策② キャッシュ

Slide 25

Slide 25 text

- アプリケーションを 単一Service → 複数Service にデプロイ 良策③ ディスパッチ 業務単位毎に別のServiceへルーティングを設定 (バッチ処理なども別Serviceへ)

Slide 26

Slide 26 text

そして、バージョン2開発へ

Slide 27

Slide 27 text

- AppEngineの言語を  Java → Go に変更 - クライアントを JSP → Angular2系(SPA)に変更 - Datastoreの設計を見直し インデックス数が ゼロ に Memcacheのヒット率もキャッシュサイズも大幅アップ  - Serviceを分けてデプロイ。適切な  ディスパッチ を設定 バージョン2 スピンアップが約20msに サーバ処理時間は200ms以内に 基本構成 AppEngine / Datastore は変更せず

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

Googleからの取材(2回目) 2018年6月

Slide 30

Slide 30 text

No content

Slide 31

Slide 31 text

- うまく動作しない、性能が出ないのは、 だいたいクラウドサービス側よりもアプリ側に原因がある場合が多い - 現在は、AppEngine にも 2nd Gen が登場し、 いろいろと過渡期のため、機能要件に応じて適切なプロダクトを 選択していく必要がある - クラウドサービスならではのベストプラクティスやハマりどころ が存在するため、Slackとかで雑に質問してみると良いかも - なんにしても口座へのダメージ回避が最優先(性能改善にも繋がる) まとめ

Slide 32

Slide 32 text

No content

Slide 33

Slide 33 text

ありがとうございました