$30 off During Our Annual Pro Sale. View Details »

失敗知識から学ぶ!クラウドアプリ設計で避けるべき事例とその対策

 失敗知識から学ぶ!クラウドアプリ設計で避けるべき事例とその対策

2023/6/22 AWS Dev Day 2023 Tokyo 登壇資料

@twingo_b

June 22, 2023
Tweet

More Decks by @twingo_b

Other Decks in Technology

Transcript

  1. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    失敗知識から学ぶ︕
    クラウドアプリ設計で避けるべき
    事例とその対策
    藤原 吉規
    A - 5
    シニア ソリューションアーキテクト
    アマゾン ウェブ サービス ジャパン 合同会社

    View Slide

  2. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    シニア ソリューションアーキテクト
    アマゾン ウェブ サービス ジャパン ⼤阪
    好きな AWS サービス:
    • AWS 技術サポート
    藤原 吉規
    2001 年から Web マルチテナント SaaS
    に取り組んできた “firefighter” 🧑🚒

    View Slide

  3. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    Ұ൪ॏཁͰҰ൪΍͔͍ͬͳεΩϧ͸γεςϜΛઃܭ͢ΔͨΊͷ൑அྗͩɻ
    ݶΓͳ͘γϯϓϧͳσβΠϯͱ͍͏ͷ͸ͳ͔ͳ͔ڭ͑ΒΕΔ΋ͷͰ͸ͳ
    ͘ɺେํܦݧΛॏͶ֮ͯ͑Δ΋ͷͩɻ
    ͜ͷʮ൑அྗʯ͸ɺϓϩάϥϚʔʹͱͬͯඇৗʹॏཁͳͷ͕ͩɺͦ͏؆୯
    ʹڭ͑ΒΕΔ΋ͷͰ΋ͳ͍ɻ΅͕͘஌ΔݶΓɺ൑அྗΛ͚ͭΔ
    Ұ൪ͷํ๏͸ɺࣗ෼Ͱઃܭͨ͠γεςϜΛ௕͍ؒϝϯς͢Δ
    ͜ͱͩͱࢥ͏
    IUUQTLOPIKQBOTXFSTEDB
    Evan Priestley
    質とスピード(2022春版、質疑応答⽤資料付き) / Quality and Speed 2022 Spring Edition: P99

    View Slide

  4. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    セッション対象者とゴール
    想定視聴者
    • 各種データベースやストレージを利⽤してクラウド上に Web アプリを設計・開発す
    る、サーバーサイド/バックエンド開発エンジニア、テックリード、アーキテクトの⽅
    • クラウド上の Web アプリの安定性・コストに課題感をお持ちの⽅
    ゴール
    • クラウド上の Web アプリ設計時のアーキテクチャ選択がネットワークおよび
    ストレージ I/O 最適化余地を決定し、⾮機能要件である安定性・コストへより
    直接的に影響することを理解する
    • 過去に選択した設計アーキテクチャのトレードオフが後に顕在化する可能性を
    理解する

    View Slide

  5. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    アジェンダ
    • はじめに
    • 失敗知識事例
    1. 100 万の Database Table 🔥
    2. 毎⽉ 11 億の Amazon S3 PUT, COPY, POST, LIST リクエスト 🔥
    • まとめ

    View Slide

  6. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    はじめに
    あくまでも、よくあるケース (仮想ストーリー) です 💭
    • 私⾃⾝の過去の AWS 上での Web アプリ設計・開発・運⽤経験や、
    過去の技術⽀援で発⽣した複数の事例を組合せています
    • 開発や QA、スモールスタートローンチ時のユーザーやデータが
    限られている時は課題になりませんが、成⻑期に⾮機能要件の
    安定性・コストが課題となるケースを紹介します

    View Slide

  7. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    失敗知識事例 1:
    100 万の Database Table 🔥

    View Slide

  8. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    新規の業務系 SaaS をローンチ 🚀
    してから 3 年後のとある⽇。。。

    View Slide

  9. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    我が社の SaaS テナント契約が 1万社を
    達成しました 👏

    View Slide

  10. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    しかし、良いことばかりではなく 😢
    業務開始時間ピークの朝 9 時ごろに
    頻繁にエラーになったり、レスポンスが遅いと
    エンドユーザーからクレームが⼊るように 😱

    View Slide

  11. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    業務系 SaaS AWS アーキテクチャ例
    アベイラビリティゾーン C
    アベイラビリティゾーン B
    アベイラビリティゾーン A
    Cluster
    Volume
    Database
    100 Table
    ...
    Application
    load
    balancer
    Data Copies
    APP
    Amazon Aurora MySQL writer
    クライアント

    View Slide

  12. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    環境と発⽣していた事象を整理
    環境
    • アプリサーバーは Python, Ruby, PHP などの軽量プログラミング⾔語と
    OSS Web フレームワーク
    • DB は Amazon Aurora MySQL、1 万テナントを単⼀の Aurora クラスターに収容
    Amazon CloudWatch メトリクス
    • テナント契約増加に合わせてスケールアップを続けてきたが、アプリサーバー
    Amazon EC2 インスタンスと Aurora インスタンスの両⽅の CPU 使⽤率:
    CPUUtilization が常に⾼い傾向
    • Aurora の DB接続数: DatabaseConnections 、接続試⾏回数:
    ConnectionAttempts が常に増減しており、特にピーク時間帯にスパイクする

    View Slide

  13. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    クエリチューニングでは根本解決しない 🤔
    MySQL クエリの改善内容
    • Index 付与
    • スロークエリ改修
    • N+1 問題によるクエリ実⾏回数
    • パーティショニング
    • 更新ロック
    • MySQL のパラメータ変更

    View Slide

  14. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    CPU 使⽤率⾼ / DB 接続数, 接続試⾏回数スパイク
    アベイラビリティゾーン C
    アベイラビリティゾーン B
    アベイラビリティゾーン A
    Cluster
    Volume
    Database
    100 Table
    ...
    Application
    load
    balancer
    Data Copies
    APP
    Amazon Aurora MySQL writer
    クライアント
    アプリサーバー
    CPU 使⽤率 ⾼
    ピーク時 DB 接続数
    接続試⾏回数
    のスパイク
    Aurora インスタンス
    CPU 使⽤率 ⾼

    View Slide

  15. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    ソリューションアーキテクト SA
    に技術⽀援のご相談をいただく 🧑🚒

    View Slide

  16. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    SA からテックリードの⽅にヒアリング 👂
    環境と発⽣していた事象
    • 前述の通り
    エンドユーザーへの影響以外に困っていることはありますか︖
    • クエリチューニングのために Table へカラム追加や Index 付与したのですが、
    テナント契約が増えた結果、 Web フレームワーク経由のスキーママイグレーション
    にとても時間がかかるようになりました。1⽇以上かかることもあります。
    Table 数は 100 個ありますが、テナント毎のレコード数は多くても数⼗万程度です。
    機能追加にも影響出ています。
    • テナント契約増加にあわせてスケールアップしたため、 EC2 インスタンスと Aurora
    インスタンスのコストも課題なのですが、Aurora ストレージ I/O のコスト⽐率
    が⼤きくなっていて、削減を検討したいです。

    View Slide

  17. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    SA からの質問
    Web フレームワークで DB コネクションプーリングは有効にしていま
    すか︖
    • リクエスト毎に都度 DB コネクション処理を⾏うと EC2 インスタンスと Aurora
    インスタンスの両⽅の CPU 使⽤率が⾼くなりやすいです。
    • DB コネクション処理は、Aurora エンドポイントの名前解決と
    TCP ハンドシェイクが⾏われるためです。
    テックリードの⽅のご⾒解
    • いいえ。DB コネクションプーリングは有効にできないので無効にしています。1万
    のテナント毎に database を作成しているので、リクエスト毎に都度異なる
    database に接続されるためです。

    View Slide

  18. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    1 万 テナント Database x 100 Table
    100 万の Database Table 🔥

    View Slide

  19. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    100 万の Database Table, リクエスト毎 DB 接続
    Aurora ストレージ I/O のコスト⽐率⾼
    アベイラビリティゾーン C
    アベイラビリティゾーン B
    アベイラビリティゾーン A
    Cluster
    Volume
    テナント毎 DB
    100 Table
    ...
    Application
    load
    balancer
    Data Copies
    APP
    Amazon Aurora MySQL writer
    100 x 10,000 テナント
    = 1,000,000 Tables
    ...
    クライアント 💸💸💸
    Aurora ストレージ
    I/O のコスト⽐率⾼
    リクエスト毎の DB 接続
    Aurora エンドポイント名前解決
    TCP ハンドシェイク

    View Slide

  20. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    テナント毎に Database Table を作成した理由
    は、3 年前のアプリ設計時に遡ります 🕐

    View Slide

  21. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    テナント毎に Database Table を作成した理由
    市場投⼊までの時間を短縮したい
    • 個社向けに提供していた既存の Web アプリを SaaS にして新規ビジネスを早急に
    ⽴ち上げたい︕アプリ改修を避けるために、テナント毎に database を作成しよう︕
    • テナント毎に database を作成する OSS Web フレームワークのマルチテナント
    対応プラグインを活⽤しよう︕
    運⽤・セキュリティ・データアクセスレイヤー作り込みの懸念
    • database をテナント毎に分ければ、解約時の削除が簡単
    • セキュリティ厳格化でテナントごとに DB 接続ユーザーと database を分けたい
    • シャード Database Table に複数テナントのデータを⼊れると、アプリ側でテナント
    分離アクセス制御の作り込みが必要になってしまうが、ノウハウがない

    View Slide

  22. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    時間がかかる”より良いアプローチ”を使⽤する
    代わりに、今すぐ簡単で限定的な解決策を選択
    することが、設計判断時点ではビジネス上必要
    であった可能性も 🤝

    View Slide

  23. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    設計判断のトレードオフを評価可能なメトリクス
    を定義・計測し、運⽤開始後に⾒直しできるよう
    にすることが最も重要 🔎
    mysql> select count(*) from information_schema.tables
    where TABLE_SCHEMA like ‘tenant%';
    +----------+
    | count(*) |
    +----------+
    | 1000000 |
    +----------+

    View Slide

  24. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    定常状態
    リソース (ファイルシステム内のログファイルであれ、 データベース内の⾏であ
    れ、メモリ内のキャッシュであれ)を蓄積するメカニズムは、 ⾼校の微積分に出
    てくるバケツに似ている。 バケツにデータを蓄積していくと、⼀定の速度で満た
    されていく。 同じ速度かそれ以上で排出しなければ、いずれ溢れてしまう。 バケ
    ツが溢れたら⼤変だ。 サーバがダウンしたり、 データベースが遅くなったりエ
    ラーを投げたり、 レスポンス時間が天⽂学的に膨れ上がったりする。 リソース
    を蓄積するあらゆるメカニズムでは、そのリソースをリサイ
    クルする何らかのメカニズムがほかに存在しなければならな
    い。 これが 「定常状態」 パターンの考え⽅だ。
    Release It︕ 本番⽤ソフトウェア製品の設計とデプロイのために (p. 107)
    Michael T. Nygard 著、でびあんぐる 監訳

    View Slide

  25. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    対策1:
    Aurora ストレージ I/O コスト 🧯

    View Slide

  26. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    MySQL の使⽤のベストプラクティス
    テーブル数合計は 1 万未満に
    多数のテーブル (1 万以上) のためにパフォーマンスの低下がある場合、それは MySQL がストレー
    ジファイルのオープンとクローズを含む作業を⾏うことによって引き起こされるものです。この問題
    に対処するには、table_open_cache および table_definition_cache パラメータのサイズを⼤きく
    します。ただし、これらのパラメータの値を⼤きくすると、MySQL が使⽤するメモリの量が⼤幅に
    増加し、使⽤可能なメモリがすべて使⽤される場合もあります。詳細については、MySQL ドキュメ
    ントの「MySQL でのテーブルのオープンとクローズの⽅法」を参照してください。
    さらに、テーブルが多すぎると、MySQL のスタートアップ時間に⼤きな影響を与える可能性があり
    ます。特に MySQL 8.0 より前のバージョンでは、クリーンシャットダウンと再起動およびクラッ
    シュ復旧の両⽅が影響を受ける可能性があります。
    DB インスタンス内のすべてのデータベースで、テーブル数合計を 1 万
    未満にすることをお勧めします。MySQL データベース内で多数のテーブルを使⽤する
    ユースケースについては、「MySQL 8.0 の 100 万テーブル」を参照してください。
    Amazon RDS のベストプラクティス - MySQL の使⽤のベストプラクティス – テーブルの数

    View Slide

  27. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    単⼀インスタンス、シャード Database
    (プールモデル) でテナント毎のテーブル数増加を
    防ぐ
    ブリッジモデル プールモデル
    サイロモデル
    アプリレイヤー
    Instance
    database1 database2
    database database
    Instance Instance Instance
    database
    Tenant 1 84049-49 True
    Tenant 2 82-84-949 False
    Tenant 1 Bob Smith
    Tenant 2 Lisa Johnson
    テナント毎インスタンス 単⼀インスタンス、
    シャード Database
    単⼀インスタンス、
    テナント毎 Database
    SaaS Storage Strategies - Building a multitenant storage model on AWS | AWS Whitepaper

    View Slide

  28. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    Aurora の I/O 計画: バッファキャッシュヒット率
    は 99.98% 以上を⽬標に
    バッファプールは、InnoDB がアクセス時にテーブルおよびインデックスデータを
    キャッシュするメインメモリー内の領域です。 バッファープールを使⽤すると、頻繁に
    使⽤されるデータをメモリーから直接処理できるため、処理速度が向上します。
    ⼤容量読み取り操作の効率を⾼めるため、バッファプールは複数⾏を保持できるページに分割されま
    す。 キャッシュ管理を効率化するために、バッファプールはページのリンクリストとして実装され
    ます。使⽤頻度が低いデータは、LRU アルゴリズムのバリエーションを使⽤して
    キャッシュから削除されます。
    MySQL 8.0 リファレンスマニュアル - バッファプール
    Amazon Aurora MySQL では 16 KB のページサイズをサポートし、Amazon Aurora
    PostgreSQL では 8 KB のページサイズをサポートしています。ページサイズは、データベースエン
    ジンが実⾏する最⼩の I/O 操作です。
    99.98% 以上を⽬標に、バッファキャッシュのヒット率: BufferCacheHitRatio を
    監視します。
    Planning I/O in Amazon Aurora | AWS Database Blog

    View Slide

  29. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    シャード Database Table と
    テナント毎 Database Table の⽐較
    シャード Database Table (プールモデル)
    • 16KB ページに複数テナントデータが含まれ、バッファプールがより効率的に。
    ※データ・アクセス頻度依存
    table_a
    TenantA
    table_a
    TenantA
    TenantB
    TenantC
    TenantD
    table_a
    TenantB
    table_a
    TenantC
    バッファキャッシュ
    テナント毎 Database Table
    LRU でバッファプールから削除
    DB TenantA DB TenantB DB TenantC DB TenantD
    table_a
    TenantD
    バッファキャッシュ
    シャード Database Table
    DB TenantAll
    テナント毎 Database Table (ブリッジモデル)
    • 16KB ページは単⼀テナントデータのみで I/O オーバーヘッドが⼤きい。⾼アクセス頻度ページが LRU でバ
    ッファプールから削除されやすく I/O 読込が増え、性能維持にはより多くのメモリを持つ
    インスタンスが必要に。

    View Slide

  30. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    データアクセスレイヤー (DAL) をアプリに実装
    • テナント情報からアクセス先 DB のルーティング
    の実施や、テナントレベルのセキュリティ担保、
    コネクションプーリングの管理などを実施する
    • 例)通常はプールモデル、特定テナントだけサイ
    ロモデルとしている Hybrid な場合では、テナン
    トのパーティショニングモデル毎にアクセス⽅法
    の変更が必要になるため、DAL で抽象化出来る
    ことが望ましい
    § プールモデル︓インスタンスへの接続と⾏レベルの
    アクセス制御
    § サイロモデル︓インスタンスへの接続の実施
    SaaS Storage Strategies - Building a multitenant storage model on AWS | AWS Whitepaper

    View Slide

  31. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    初期設計時に PostgreSQL ⾏レベルセキュリティ
    (RLS) を候補に⼊れる
    instance
    database
    schema
    tenant_id user_id username
    tenant1 1 Suzuki
    tenant1 2 Sato
    tenant2 1 Nakamura
    tenant2 2 Takahashi
    tenant3 1 Yamada
    user_id username
    user_id username
    1 Yamada
    user_id username
    1 Suzuki
    2 Sato
    -- Tenant1
    SET app.current_tenant = ‘tenant1’;
    SELECT user_id,username
    FROM users
    WHERE tenant_id = ‘tenant1’;
    -- Create Table
    CREATE TABLE users(
    tenant_id VARCHAR(20),
    user_id INT,
    username VARCHAR(20),
    PRIMARY KEY(tenant_id,user_id));
    -- Insert Data
    INSERT INTO users VALUES('tenant1',1,'Suzuki’);
    INSERT INTO users VALUES('tenant1',2,'Sato’);
    INSERT INTO users VALUES('tenant2',1,'Nakamura’);
    INSERT INTO users
    VALUES('tenant2',2,'Takahashi’);
    INSERT INTO users VALUES('tenant3',1,'Yamada’);
    -- Create Policy
    CREATE POLICY tenant_isolation_policy ON users
    USING (tenant_id =
    current_setting('app.current_tenant’)::varchar);
    ALTER TABLE users ENABLE ROW LEVEL SECURITY;
    Aurora PostgreSQL の RLS 設定
    ※ PostgreSQL 9.5 以降
    users table
    PostgreSQL の⾏レベルのセキュリティを備えたマルチテナントデータの分離
    -- Tenant2
    SET app.current_tenant = ‘tenant2’;
    SELECT user_id,username
    FROM users
    WHERE tenant_id = ‘tenant1’;
    -- Tenant3
    SET app.current_tenant = ‘tenant3’;
    SELECT user_id,username
    FROM users;
    ※プライマリキーには数値シーケンスを使⽤し、
    ⼤規模なデータセットのスケーラビリティとパ
    フォーマンスを向上させることを推奨

    View Slide

  32. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    Amazon Aurora I/O 最適化クラスターで
    ⼀次対応を検討 特徴
    • Aurora I/O 最適化では、読み取りと書き込み
    I/O オペレーションの料⾦は発⽣しない。デー
    タベースインスタンスとストレージ使⽤量に対
    してのみ課⾦
    • Aurora I/O 最適化は、I/O 料⾦が Aurora
    データベースの総消費量の 25% を超える場合、
    I/O 集約型アプリケーションのコストを最⼤
    40% 削減可能
    • 既存の Aurora クラスターでは、ストレージ構
    成を 30 ⽇に 1 回 Aurora I/O-Optimized に
    切り替えたり、いつでも Aurora Standard に
    戻すことが可能
    注意点
    • Aurora MySQL v3.03.1 (MySQL 8.0.26 互
    換) 以上か Aurora PostgreSQL v15.2 以上,
    v14.7以上, v13.10 以上に対応
    設定画⾯例
    既存クラスターの変更はオンラインで可能
    新規 – I/O 集約型のアプリケーションで最⼤ 40%
    のコスト削減を実現する Amazon Aurora I/O-
    Optimized クラスター設定

    View Slide

  33. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    対策2:
    アプリサーバー、リクエスト毎の DB 接続 🧯

    View Slide

  34. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    コネクションプーリング (持続的接続)
    Python SQLAlchemy のコード例
    import sqlalchemy
    pool = sqlalchemy.create_engine(
    sqlalchemy.engine.url.URL.create(
    drivername="mysql+pymysql",
    username=db_user,
    password=db_pass,
    database=db_name,
    host=db_host,
    port=db_port,
    ),
    pool_size=20,
    max_overflow=0,
    pool_timeout=2,
    pool_recycle=3600,
    )
    コネクション
    初期化
    リクエスト
    Thread
    ⽣成
    Transaction

    コネクション
    クローズ

    Thread
    破棄
    レスポンス
    APP DB
    コネクション
    初期化
    リクエスト
    Thread
    ⽣成
    Transaction

    レスポンス
    APP DB
    リクエスト
    Transaction

    レスポンス
    リクエスト
    Transaction

    レスポンス
    コネクションプーリングなし コネクションプーリングあり
    DB 接続ユーザー
    database 毎に
    コネクションプーリング
    コネクション初期化時に
    Aurora エンドポイント名前解決
    TCP ハンドシェイクを都度実⾏

    View Slide

  35. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    コネクションプーリングは
    VPC DNS スロットリング対策に有効
    DNS クォータ
    各 EC2 インスタンスは、Route 53 Resolver (具体的には 10.0.0.2、169.254.169.253
    などの .2 アドレス) にネットワークインターフェイスあたり 1024 パケット/秒でパ
    ケットを送信できます。このクォータを増やすことはできません。
    クォータに達すると、Route 53 Resolver はトラフィックを拒否します。クォータ
    に達する原因には、DNS スロットリングの問題や、Route 53 Resolver ネットワークイン
    ターフェイスを使⽤するインスタンスメタデータクエリがあります。VPC DNS スロットリ
    ングの問題を解決する⽅法については、「VPC DNS スロットリングが、Amazon が提供
    している DNS サーバーへのDNS クエリの失敗の原因となっているかどうかを判断する⽅
    法を教えてください。」を参照してください。
    Amazon VPC - VPC の DNS 属性 - DNS クォータ

    View Slide

  36. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    Private subnet C
    Public subnet C
    Public subnet A Private subnet A
    すべての接続でコネクションプーリング有効化
    を検討 VPC
    アベイラビリティゾーン A
    APP
    クライアント
    Internet
    Internet
    gateway APP SG DB SG
    Aurora
    writer
    ALB SG
    アベイラビリティゾーン C
    APP
    Application load
    balancer
    ElastiCache
    Redis
    Aurora
    reader
    ElastiCache
    Redis
    負荷テスト
    ツール

    View Slide

  37. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    フェイルオーバー時の再接続を
    障害テストで確認
    実際のワークロードによる負荷テスト中に障害テスト
    を実施することで確認
    • アプリ側のエラーハンドリング
    • レスポンス低下時のサービス影響
    • データ不整合の有無
    Aurora では⼿動フェイルオーバー/障害挿⼊クエリを実⾏
    して障害をシミュレーション可能
    ex.) ALTER SYSTEM CRASH
    フェイルオーバー時はコネクションプーリングをアプ
    リ/ミドルウェアで再接続する仕組みが必要
    Amazon Aurora - 障害挿⼊クエリを使⽤した Amazon Aurora MySQL のテスト
    AWS Fault Injection Simulator FIS とは︖
    APP
    負荷テスト
    ツール
    Application load
    balancer
    writer reader
    write read
    AWS での分散負荷テスト | 実装 | AWS ソリューション

    View Slide

  38. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    改善後アーキテクチャ
    アベイラビリティゾーン C
    アベイラビリティゾーン B
    アベイラビリティゾーン A
    Cluster
    Volume
    Application
    load
    balancer
    Data Copies
    APP
    Amazon Aurora MySQL writer
    10,000 テナント = 100 Table
    クライアント
    シャード Database Table
    (プールモデル)による
    バッファキャッシュ
    の活⽤
    コネクションプーリングの活⽤
    tenant_id user_id name
    TenantA UserA Fujiwara
    TenantB UserB Hama
    TenantC UserC Mazda
    TenantD UserD Honda
    Database
    100 Table
    ...

    View Slide

  39. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    失敗知識事例 2:
    毎⽉ 11 億の Amazon S3 PUT, COPY,
    POST, LIST リクエスト 🔥

    View Slide

  40. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    アクセス解析のために
    クライアントからログ収集する仕組みを追加 ⚙
    してから 3 年後のとある⽇。。。

    View Slide

  41. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    アクセス解析対象の DAU (Daily Access User)
    が 30,000 を超えました👏

    View Slide

  42. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    しかし、良いことばかりではなく 😢
    経理の⽅から、
    Amazon Simple Storage Service (S3) の
    ⽉額コストが $ 5,000 を超えていると指摘が
    💸💸💸

    View Slide

  43. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    S3 のアクセス解析ログ⽉間処理データ量は
    約 400GB なので、ストレージ費⽤は
    ⼗数ドル程度のはずなのに 🤔

    View Slide

  44. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    EC2 instance
    EC2 instance
    EC2 instance
    ログ収集 AWS アーキテクチャ例
    Application
    load
    balancer
    クライアント APP
    APP プログラム
    ログオブジェクト
    S3 バケット
    EC2 instance
    ログ集計 BATCH
    プログラム
    ログ集計
    BATCH
    Amazon Aurora
    集計済
    ログデータ
    400GB/⽉

    View Slide

  45. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    環境と発⽣していた事象を整理
    環境
    • アプリ・バッチサーバーは Python, Ruby, PHP などの軽量プログラミング⾔語の
    OSS Web フレームワーク
    • クライアントは 30,000、平⽇⽇中に 1分に 1回、ログをアプリサーバーに送信
    • 30,000クライアント x 1時間60回 x ⽇中8時間 x 平⽇20⽇間 = 288,000,000/⽉
    • バッチ集計サーバーは 5分に 1回、ログを集計して Amazon Aurora に保存
    Amazon CloudWatch メトリクス
    • 該当バケットの S3 リクエストメトリクスを有効にして確認、リクエスト⽐率は
    PutRequests : GetRequests : DeleteRequests : ListRequests = 1:1:1:3以上
    で ListRequests が最も多いが、リクエスト元が不明

    View Slide

  46. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    EC2 instance
    EC2 instance
    EC2 instance
    S3 PUT : GET : DELETE : LIST = 1 : 1 : 1 : 3以上
    で LIST が最も多い
    Application
    load
    balancer
    クライアント APP
    APP プログラム
    ログオブジェクト
    S3 バケット
    EC2 instance
    ログ集計 BATCH
    プログラム
    ログ集計
    BATCH
    Amazon Aurora
    集計済
    ログデータ
    30,000クライアント x 1時間 60回 x ⽇中 8時間
    x 平⽇ 20⽇間 = 288,000,000/⽉
    S3 PUT
    S3 GET
    S3 DELETE
    S3 LIST の
    リクエスト元
    が不明
    400GB/⽉

    View Slide

  47. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    ソリューションアーキテクト SA
    に技術⽀援のご相談をいただく 🧑🚒

    View Slide

  48. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    SA からテックリードの⽅にヒアリング 👂
    環境と発⽣していた事象
    • 前述の通り
    S3 PUT 時に複数リクエストのログを集約していますか︖
    • いいえ。リクエスト毎に JSON Log を 都度 S3 PUT しています。リクエスト
    あたり最⼤ 1.5KB と⼩容量だからです。
    アプリ・バッチサーバーは S3 バケットへのログ保存・取得・削除操作
    にプログラミング⾔語⽤の AWS SDK を使⽤していますか︖
    • いいえ。アプリ・バッチサーバーに OSS の S3 ファイルシステムをインストール
    して S3 バケットをマウントしています。プログラミング⾔語からファイルシステム
    経由で直接読み書きでき、実装が簡単だからです。

    View Slide

  49. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    EC2 instance
    EC2 instance
    EC2 instance
    OSS の S3 ファイルシステム経由でリクエスト毎に
    都度 JSON Log を S3 PUT
    Application
    load
    balancer
    クライアント APP
    APP プログラム
    ログオブジェクト
    S3 バケット
    OSS S3
    Filesystem
    /mnt/s3bucket
    EC2 instance
    ログ集計 BATCH
    プログラム
    OSS S3
    Filesystem
    /mnt/s3bucket
    ログ集計
    BATCH
    Amazon Aurora
    集計済
    ログデータ
    リクエスト毎に
    JSON Log を
    都度 S3 PUT
    JSON Log
    1.5KB per
    Object
    OSS の S3 ファイル
    システム
    OSS の S3 ファイル
    システム
    S3 LIST の
    リクエスト元
    が不明

    View Slide

  50. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    SA からの提案
    対象の S3 バケット・オブジェクトの AWS CloudTrail イベントログ
    記録を有効化して、S3 LIST のリクエスト元を特定しましょう
    テックリードの⽅のご⾒解
    • CloudTrail イベントログ記録を有効化し、OSS の S3 ファイルシステムの書込、
    読込、削除操作毎に S3 LIST リクエストがそれぞれ 1回以上実⾏されているこ
    とがわかりました。PUT : GET : DELETE : LIST = 1 : 1 : 1 : 3以上の⽐率とも⼀致
    しています。ファイルやディレクトリの更新・存在チェックのために実⾏される
    ように⾒えます。
    • 30,000クライアント x 1時間60回 x ⽇中8時間 x 平⽇20⽇間 = 288,000,000/⽉
    • JSON Log 1Object 毎に PUT 1回, LIST 3回で合計 4 回 1,152,000,000/⽉となり、
    S3 PUT, COPY, POST, LIST リクエストが $ 5,000 のコスト要因でした。

    View Slide

  51. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    毎⽉ 11 億の Amazon S3 PUT, COPY, POST,
    LIST リクエスト 🔥

    View Slide

  52. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    EC2 instance
    EC2 instance
    EC2 instance
    毎⽉ 11 億の Amazon S3 PUT, COPY, POST,
    LIST リクエスト
    Application
    load
    balancer
    クライアント APP
    APP プログラム
    ログオブジェクト
    S3 バケット
    OSS S3
    Filesystem
    /mnt/s3bucket
    EC2 instance
    ログ集計 BATCH
    プログラム
    OSS S3
    Filesystem
    /mnt/s3bucket
    ログ集計
    BATCH
    Amazon Aurora
    集計済
    ログデータ
    JSON Log
    1.5KB per
    Object
    OSS S3 Filesystem
    書込
    S3 PUT, S3 LIST
    OSS S3 Filesystem
    削除
    S3 DELETE, S3 LIST
    30,000クライアント x 1時間 60回 x ⽇中 8時間
    x 平⽇ 20⽇間 = 288,000,000/⽉
    x PUT 1回, LIST 3回で合計 4回 = 1,152,000,000/⽉
    OSS S3 Filesystem
    読込
    S3 GET, S3 LIST

    View Slide

  53. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    OSS の S3 ファイルシステムを採⽤した理由は、
    3 年前のアプリ設計時に遡ります 🕐

    View Slide

  54. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    OSS の S3 ファイルシステムを採⽤した理由
    市場投⼊までの時間を短縮したい
    • オンプレミスで稼働中の既存の Web アプリはストレージに拡張性・耐久性の課題
    があるため Amazon S3 を利⽤したい︕アプリの改修を避けるために、OSS の S3
    ファイルシステムを利⽤しよう︕
    S3 データアクセスの作り込みの懸念
    • プログラミング⾔語で S3 データアクセスする作り込みが必要になってしまうが、
    AWS SDK の利⽤ノウハウがない︕ OSS の S3 ファイルシステムはプログラミング
    ⾔語からファイルシステム経由で直接読み書きでき、実装が簡単︕
    コスト試算や PoC が不⼗分または実施していなかった
    • JSON Log はリクエストあたり最⼤ 1.5KB と⼩容量なのでコストは問題ないだろう

    View Slide

  55. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    時間がかかる”より良いアプローチ”を使⽤する
    代わりに、今すぐ簡単で限定的な解決策を選択
    することが、設計判断時点ではビジネス上必要
    であった可能性も 🤝
    再掲

    View Slide

  56. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    設計判断のトレードオフを評価可能なメトリクス
    を定義・計測し、運⽤開始後に⾒直しできるよう
    にすることが最も重要 🔎
    -- Querying CloudTrail logs - Amazon Athena
    SELECT COUNT(eventname) AS cnt, eventname,
    useridentity.principalid
    FROM "cloudtrail_logs_ap_northeast_1_pp"
    WHERE eventsource = 's3.amazonaws.com'
    AND requestparameters LIKE ‘%[s3_bucket_name]%'
    AND useridentity.principalid LIKE '%:i-%'
    AND timestamp '[yyyy/MM/dd]'
    GROUP BY eventname,useridentity.principalid
    ORDER BY cnt DESC
    再掲

    View Slide

  57. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    定常状態
    リソース (ファイルシステム内のログファイルであれ、 データベース内の⾏であ
    れ、メモリ内のキャッシュであれ)を蓄積するメカニズムは、 ⾼校の微積分に出
    てくるバケツに似ている。 バケツにデータを蓄積していくと、⼀定の速度で満た
    されていく。 同じ速度かそれ以上で排出しなければ、いずれ溢れてしまう。 バケ
    ツが溢れたら⼤変だ。 サーバがダウンしたり、 データベースが遅くなったりエ
    ラーを投げたり、 レスポンス時間が天⽂学的に膨れ上がったりする。 リソース
    を蓄積するあらゆるメカニズムでは、そのリソースをリサイ
    クルする何らかのメカニズムがほかに存在しなければならな
    い。 これが 「定常状態」 パターンの考え⽅だ。
    Release It︕ 本番⽤ソフトウェア製品の設計とデプロイのために (p. 107)
    Michael T. Nygard 著、でびあんぐる 監訳
    再掲

    View Slide

  58. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    対策:
    毎⽉ 11 億の Amazon S3 PUT, COPY, POST,
    LIST リクエスト 🧯

    View Slide

  59. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    Amazon S3 の料⾦
    S3 標準ストレージ: リクエストとデータ取り出し
    ※AWS アジアパシフィック (東京) リージョン
    • PUT、COPY、POST、LIST リクエスト (1,000 リクエストあたり)
    $0.0047
    • GET、SELECT、他のすべてのリクエスト (1,000 リクエストあたり)
    $0.00037
    S3 PUT/LIST リクエストは GET リクエストに⽐べて、10倍以上⾼額
    なため、S3 PUT はバッファリング・バルク処理しつつ、
    S3 LIST リクエストを削減できる AWS サービスを併⽤する
    Amazon S3 の料⾦

    View Slide

  60. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    EC2 instance
    EC2 instance
    EC2 instance
    改善後アーキテクチャ
    Application
    load
    balancer
    クライアント APP
    APP
    プログラム
    ログオブジェクト
    S3 バケット ログ集計
    JSON Log
    < 128MB per
    Object
    AWS SDK
    Amazon Kinesis
    Data Firehose
    30,000クライアント x 1時間 60回
    x ⽇中 8時間 x 平⽇ 20⽇間
    = 288,000,000/⽉
    Amazon Kinesis
    Data Streams
    EC2 instance
    ログ集計
    プログラム
    AWS SDK
    Amazon Aurora
    集計済
    ログデータ
    バッファリング
    サイズ: 128MB
    インターバル: 300秒
    JSON Log
    1.5KB per
    Object
    Amazon SQS
    S3 Event
    Notifications
    S3 PUT オブジェクト
    キー情報を
    ログ集計で利⽤
    アプリ・ログ集計
    で AWS SDK を使⽤

    View Slide

  61. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    S3 署名付き URL HTTP POST で画像など⼤容量
    ファイルをクライアントから直接アップロード
    import logging
    import boto3
    def create_presigned_post(bucket_name, object_name,
    fields=None, conditions=None, expiration=60):
    # Generate a presigned S3 POST URL
    s3_client = boto3.client('s3')
    response = s3_client.generate_presigned_post(bucket_name,
    object_name,
    Fields=fields,
    Conditions=conditions,
    ExpiresIn=expiration)
    # The response contains the presigned URL and required fields
    return response
    Generating a presigned URL to upload a file – Boto3
    Python boto3 のコード例
    EC2 instance
    APP
    プログラム
    AWS SDK S3 バケット
    クライアント
    Web ブラウザー
    APP
    1. 署名付き
    URL ⽣成
    リクエスト
    2. HTTP POST
    で直接
    アップロード
    response[ʻurlʼ], response[ʻfieldsʼ] に
    HTTP FORM に必要な URL,
    FIELD データが含まれるため、
    クライアント JavaScript でアップロード可能

    View Slide

  62. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    まとめ

    View Slide

  63. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    まとめ
    • クラウド上の Web アプリ設計時のアーキテクチャ選択が
    ネットワークおよびストレージ I/O 最適化余地を決定し、
    ⾮機能要件である安定性・コストへより直接的に影響する
    • 過去に選択した設計アーキテクチャのトレードオフが後に
    顕在化する可能性
    • システム設計の判断⼒をつける⼀番の⽅法は、⾃分で設計した
    システムを⻑い間メンテすること
    • 失敗知識は貴重です︕ぜひみなさんも社内外で共有しましょう︕

    View Slide

  64. © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.
    Thank you!
    © 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.

    View Slide