Slide 1

Slide 1 text

Infrastructure as "型付き" Code 急成長する事業のインフラ再構築 2020/09/10 @ BIT VALLEY 2020 エムスリー株式会社 ソフトウェアエンジニア / SRE 山口 卓也

Slide 2

Slide 2 text

本セッションで話すこと 急成長する事業の裏側 ○ 複雑化するインフラ ○ スケールしない一部サービス これらの状況を解決するために どのようにしてインフラ再構築を進めているか? 2

Slide 3

Slide 3 text

山口 卓也 / @no_clock エムスリー株式会社 ソフトウェアエンジニア / SRE ● Ruby, C#, 京都, 猫が好き ● 大手 SIer (6 年) → エムスリー (2 年) ● 小学 5 年でプログラミング (VB6) ● 中学 3 年で「 P2P 地震情報」を公開 ● 今もサービス運用中 (15 年以上) 3

Slide 4

Slide 4 text

クラウド電子カルテ「エムスリーデジカル」 カルテ(診療録)作成を含む クリニックの「受付」「診察」 「会計」を支える Web サービス ● 2015/10 サービス開始 背景 課題 立案 実行 まとめ 4 AWS: ECS (EC2, Fargate), S3, SQS, ELB, RDS (Aurora/PostgreSQL), … 言語/FW: Ruby on Rails, Scala, Node.js / TypeScript, Swift (iPad App), …

Slide 5

Slide 5 text

急成長する事業 x10 2 年間で 利用施設数は 10 倍 背景 課題 立案 実行 まとめ 5

Slide 6

Slide 6 text

急成長する事業 x10 2 年間で 利用施設数は 10 倍 8 チームの エンジニア人数 背景 課題 立案 実行 まとめ 6

Slide 7

Slide 7 text

急成長するインフラ [5 年前] 施設数 1 → 100 ☑ Configuration Management (Ansible) ☐ Infrastructure Definition (Terraform) ☑ 主要サービスのコンテナ化 ☐ 主要サービスの ECS 化、オートスケール ● EC2 インスタンス 十数台 ● 手作業でぬくもりのあるスケール作業 背景 課題 立案 実行 まとめ 7

Slide 8

Slide 8 text

急成長するインフラ [2 年前] 施設数 100 → 1,000 ☑ Configuration Management (Ansible) ☑ Infrastructure Definition (Terraform) ☑ 主要サービスのコンテナ化 ☑ 主要サービスの ECS 化、オートスケール ほぼスケーラブルなインフラ完成 背景 課題 立案 実行 まとめ 8

Slide 9

Slide 9 text

急成長するインフラ [半年前] 施設数 1,000 → 10,000 ☑ IaC, 主要部分のオートスケール ☑ 全サービスのコンテナ化 ☑ SQS 活用、 ECS クラスタ分割等   のスケーラビリティ改善 ほぼスケーラブルだから、 このままスケールさせればヨシ! 背景 課題 立案 実行 まとめ 9

Slide 10

Slide 10 text

背景 課題 立案 実行 まとめ 10 ほぼスケーラブルだから、 このままスケールさせればヨシ! (よくない)

Slide 11

Slide 11 text

急成長するインフラは複雑さを増す 増え続けるインフラ ● 管理対象は 2 倍以上 ● コード量は 3 倍以上 複雑さが増すインフラコード ● 微妙なモジュール構成 ● 長い長い値の引き回し 背景 課題 立案 実行 まとめ 11

Slide 12

Slide 12 text

急成長するインフラは複雑さを増す 「割れ窓」「作業ミス」… ● IaC を部分適用しはじめる (実態との差が残り続ける) ● 適用対象を選ぶ手間が増える ● 適用対象を間違える ● 不具合の原因に 「 IaC の適用漏れ」 が加わり調査が難しくなる 背景 課題 立案 実行 まとめ 12

Slide 13

Slide 13 text

急成長するインフラに近づく限界 最大までスケールアップした RDS ● db.r4.16xlarge (R4 で最大) ● vCPU: 64, Mem: 488 GiB 主要でないサービスはスケールしないまま ● ECS だがスケールはしない (コンテナ化、自動復旧が目的) ● 当初設計で想定していない 成長ステージに突入 背景 課題 立案 実行 まとめ 13

Slide 14

Slide 14 text

次のステージに向けた課題 施設数 1,000 → 10,000 ● 複雑化するインフラを うまく管理したい ● RDS と主要でないサービスも スケーラビリティを確保したい 背景 課題 立案 実行 まとめ 14

Slide 15

Slide 15 text

課題をどう乗り越えるか ※実際はリモート チームで議論 ● 解決策の立案、技術選定 ○ チームに裁量がある (運用まで責任を持つ) ● チームを超えて相談 ○ Slack 、雑談、その他 ○ CTO にも気軽に相談 ● ビジネスサイドも理解し、 尊重してくれている 背景 課題 立案 実行 まとめ 15

Slide 16

Slide 16 text

アイディア ざっくりした検討結果 チューニング、負荷軽減 10,000 施設までスケールしない RDS シャーディング 多くの場合アプリケーションでの考慮が必要 複雑さが増す、開発スピードが落ちる 主要でないサービスの 再設計、再実装 スケールさせる代わりにサービスの複雑さが増す 10,000 までスケールするか不透明 DBMS の変更 テーブル・クエリの再設計が必要 (アプリも修正) システム全体の水平分割 (シャーディング) インフラの複雑さが大幅に増すが、 アプリケーションの修正はほぼ無し 課題をどう乗り越えるか スケーラビリティ編   インフラ管理編 背景 課題 立案 実行 まとめ 16

Slide 17

Slide 17 text

課題をどう乗り越えるか スケーラビリティ編   インフラ管理編 アイディア ざっくりした検討結果 割れ窓の修復 10,000 施設までは耐えられない ドキュメント整備 ミスは減るが手間は減らない Terraform コード書き直し 水平分割したシステムの表現・管理が難しい 肥大化する tfstate の分割・管理が必要 別の IaC ツールに移行 - AWS CDK + TypeScript 全面書き直し・ツール学習コスト等の問題あるが 自動化・効率化・水平分割の表現がしやすい 背景 課題 立案 実行 まとめ 17

Slide 18

Slide 18 text

課題を乗り越える スケーラビリティの確保 システム全体の水平分割 (シャーディング) 18 複雑化するインフラの管理 別の IaC ツールに移行 AWS CDK + TypeScript 背景 課題 立案 実行 まとめ

Slide 19

Slide 19 text

課題を乗り越える スケーラビリティの確保 システム全体の水平分割 (シャーディング) 19 複雑化するインフラの管理 別の IaC ツールに移行 AWS CDK + TypeScript 背景 課題 立案 実行 まとめ

Slide 20

Slide 20 text

イメージ図 スケーラビリティの確保:  システム全体の水平分割 構成 ● 同じシステム構成(シャード) を複数用意 ● 各サービスは原則変更なし (シャードを意識しない) ● 施設はいずれかのシャードに所属 ● 約 300 施設ごとに 1 シャード 背景 課題 立案 実行 まとめ シャードC 施設601~900 シャードB 施設301~600 シャードA 施設1~300 20

Slide 21

Slide 21 text

スケーラビリティの確保:  システム全体の水平分割 欠点 ● シャード間のデータ参照は不可  →カルテは相互参照しない  →薬剤等のマスタは複製 ● 管理対象のインフラ増加 ● リリース管理がシャード毎に  →ラッパーツールで   緩和 (後述) 利点 ● 原則インフラ変更のみ ○ サービスへの機能追加の スピードを維持 ● 約 300 施設で 1 シャード ○ 運用ノウハウのある規模 (スケールしないサービスも大丈夫) ○ リリースやテーブル変更も シャード毎に可能 ○ 障害発生時の影響を局所化 背景 課題 立案 実行 まとめ シャードC 施設601~900 シャードB 施設301~600 シャードA 施設1~300 21

Slide 22

Slide 22 text

課題を乗り越える スケーラビリティの確保 システム全体の水平分割 (シャーディング) 22 複雑化するインフラの管理 別の IaC ツールに移行 AWS CDK + TypeScript 背景 課題 立案 実行 まとめ

Slide 23

Slide 23 text

複雑化するインフラの管理:  IaC: AWS CDK + TypeScript AWS CDK (Cloud Development Kit) ● 2019/07: GA (一般提供) ● プログラミング言語で IaC ● CloudFormation 経由で プロビジョニング (*1) TypeScript ● 2020/08: TypeScript 4.0 ● JavaScript + 型システム AWS CDK 薄いラッパーツール Cloud Formation (*1) プレビュー版として CDK for Terraform もある: Introducing the Cloud Development Kit for Terraform (Preview) 背景 課題 立案 実行 まとめ 23

Slide 24

Slide 24 text

複雑化するインフラの管理: IaC: AWS CDK + TypeScript  による Ruby on Rails サービスの表現 構成図抜粋 2 つの ECS クラスタ ● オンライン (API サーバ) ● バッチ (DelayedJob) クラスタ間の違い ● スケーリング、起動コマンド ● ロードバランサの有無 背景 課題 立案 実行 まとめ 24

Slide 25

Slide 25 text

複雑化するインフラの管理: IaC: AWS CDK + TypeScript  による Ruby on Rails サービスの表現 スケーリング、起動コマンドの違い サブクラスで定義するだけ ● RailsAppEcs 抽象クラス ○ RailsAppApi サブクラス ○ RailsAppBatch サブクラス 背景 課題 立案 実行 まとめ 25

Slide 26

Slide 26 text

複雑化するインフラの管理: IaC: AWS CDK + TypeScript  による Ruby on Rails サービスの表現 背景 課題 立案 実行 まとめ 26 オンライン 固有定義 LB設定 バッチ 固有定義 (まだない) 共通定義 EcsApp Pattern Props EcsBatchAppPatternProps EcsHttpAppPatternProps ロードバランサの有無の違い ● TypeScript の型システムを活用 ● Intersection Types (&) ● Union Types (|)

Slide 27

Slide 27 text

複雑化するインフラの管理: IaC: AWS CDK + TypeScript  による Ruby on Rails サービスの表現 背景 課題 立案 実行 まとめ 27 ロードバランサの有無の違い ● TypeScript の型システムを活用 ● Intersection Types (&) ● Union Types (|) ● 分かりやすい、重複がない ● Ruby on Rails 以外の サービスでも再利用可能 バッチ Ecs BatchApp Pattern Props オンライン Ecs HttpApp Pattern Props

Slide 28

Slide 28 text

複雑化するインフラの管理: IaC: AWS CDK + TypeScript  による Ruby on Rails サービスの表現 (おまけ) 環境ごとの設定値の差 ● Mapped Type TypeScript サポート (VSCode) ● 補完、定義ジャンプ、参照検索 がしっかり効く 背景 課題 立案 実行 まとめ 28

Slide 29

Slide 29 text

課題を乗り越える スケーラビリティの確保 システム全体の水平分割 (シャーディング) 29 複雑化するインフラの管理 別の IaC ツールに移行 AWS CDK + TypeScript 背景 課題 立案 実行 まとめ 水平分割で生まれる課題に… 薄いラッパーツール

Slide 30

Slide 30 text

水平分割で生まれる課題に…  薄いラッパーツール 水平分割で大量に増えるインフラの 自動的・効率的な管理 ● Stack (tfstate 相当) の管理 ● Stack の依存関係の可視化 ● CloudFormation の 面倒なところの隠蔽 ● 差分表示及びレビュー管理 ● 実行ログの記録、 Slack 通知 AWS CDK 薄いラッパーツール Cloud Formation 背景 課題 立案 実行 まとめ 30 シャードC 施設601~900 シャードB 施設301~600 シャードA 施設1~300

Slide 31

Slide 31 text

水平分割で生まれる課題に…  薄いラッパーツール 水平分割で大量に増えるインフラの 自動的・効率的な管理 ● Stack (tfstate 相当) の管理 ● Stack の依存関係の可視化 ● CloudFormation の 面倒なところの隠蔽 ● 差分表示及びレビュー管理 ● 実行ログの記録、 Slack 通知 背景 課題 立案 実行 まとめ 31 シャードC 施設601~900 シャードB 施設301~600 シャードA 施設1~300

Slide 32

Slide 32 text

複雑化するインフラの管理:  IaC: AWS CDK + TypeScript 良い点 ● CDK や CloudFormation の API が充実、自動化しやすい ● 自由度が高く柔軟 ● TypeScript の型システムを活用 ○ 分かりやすい、間違いにくい ○ ライフサイクルが比較的長いインフラを堅実にコード化 ● Node.js エコシステム 背景 課題 立案 実行 まとめ 32

Slide 33

Slide 33 text

複雑化するインフラの管理:  IaC: AWS CDK + TypeScript 微妙な点 ● AWS ロックイン ● CloudFormation の制限や仕様 ○ リソース数やテンプレートのサイズ制限 (*1) ○ ドリフト検出(コードと現状との差分検出)の誤検出 ○ 新機能の対応が Terraform より遅い場合も (*2) ● CDK の型定義が完全ではなく、時折 any が出現する ● 自由度が高いのでスパゲッティコード化しやすい ● Node.js / TS の進化速度とインフラの進化速度のズレ (*1) AWS CloudFormation のクォータ - AWS CloudFormation (*2) [ECS][Fargate]: Add EFS volumes through CloudFormation · Issue #825 · aws/containers-roadmap 背景 課題 立案 実行 まとめ 33

Slide 34

Slide 34 text

メリット・デメリットあるが 総合的には良さそう! 本番稼働に向けて絶賛作業中! 34

Slide 35

Slide 35 text

Infrastructure as "型付き" Code 急成長する事業のインフラ再構築 スケーラビリティの確保 ● システム全体の水平分割 (シャーディング) 複雑化するインフラの管理 ● AWS CDK + TypeScript での Infrastructure as Code We’re hiring! 興味があればカジュアル面談で! 背景 課題 立案 実行 まとめ AWS CDK 薄いラッパーツール Cloud Formation シャードC 施設601~900 シャードB 施設301~600 シャードA 施設1~300 35