2023/6/22 AWS Dev Day 2023 Tokyo 登壇資料
© 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
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.シニア ソリューションアーキテクトアマゾン ウェブ サービス ジャパン ⼤阪好きな AWS サービス:• AWS 技術サポート藤原 吉規2001 年から Web マルチテナント SaaSに取り組んできた “firefighter” 🧑🚒
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.Ұ൪ॏཁͰҰ൪͔͍ͬͳεΩϧγεςϜΛઃܭ͢ΔͨΊͷஅྗͩɻݶΓͳ͘γϯϓϧͳσβΠϯͱ͍͏ͷͳ͔ͳ͔ڭ͑ΒΕΔͷͰͳ͘ɺେํܦݧΛॏͶ֮ͯ͑Δͷͩɻ͜ͷʮஅྗʯɺϓϩάϥϚʔʹͱͬͯඇৗʹॏཁͳͷ͕ͩɺͦ͏؆୯ʹڭ͑ΒΕΔͷͰͳ͍ɻ΅͕͘ΔݶΓɺஅྗΛ͚ͭΔҰ൪ͷํ๏ɺࣗͰઃܭͨ͠γεςϜΛ͍ؒϝϯς͢Δ͜ͱͩͱࢥ͏IUUQTLOPIKQBOTXFSTEDBEvan Priestley質とスピード(2022春版、質疑応答⽤資料付き) / Quality and Speed 2022 Spring Edition: P99
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.セッション対象者とゴール想定視聴者• 各種データベースやストレージを利⽤してクラウド上に Web アプリを設計・開発する、サーバーサイド/バックエンド開発エンジニア、テックリード、アーキテクトの⽅• クラウド上の Web アプリの安定性・コストに課題感をお持ちの⽅ゴール• クラウド上の Web アプリ設計時のアーキテクチャ選択がネットワークおよびストレージ I/O 最適化余地を決定し、⾮機能要件である安定性・コストへより直接的に影響することを理解する• 過去に選択した設計アーキテクチャのトレードオフが後に顕在化する可能性を理解する
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.アジェンダ• はじめに• 失敗知識事例1. 100 万の Database Table 🔥2. 毎⽉ 11 億の Amazon S3 PUT, COPY, POST, LIST リクエスト 🔥• まとめ
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.はじめにあくまでも、よくあるケース (仮想ストーリー) です 💭• 私⾃⾝の過去の AWS 上での Web アプリ設計・開発・運⽤経験や、過去の技術⽀援で発⽣した複数の事例を組合せています• 開発や QA、スモールスタートローンチ時のユーザーやデータが限られている時は課題になりませんが、成⻑期に⾮機能要件の安定性・コストが課題となるケースを紹介します
© 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 🔥
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.新規の業務系 SaaS をローンチ 🚀してから 3 年後のとある⽇。。。
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.我が社の SaaS テナント契約が 1万社を達成しました 👏
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.しかし、良いことばかりではなく 😢業務開始時間ピークの朝 9 時ごろに頻繁にエラーになったり、レスポンスが遅いとエンドユーザーからクレームが⼊るように 😱
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.業務系 SaaS AWS アーキテクチャ例アベイラビリティゾーン Cアベイラビリティゾーン Bアベイラビリティゾーン AClusterVolumeDatabase100 Table...ApplicationloadbalancerData CopiesAPPAmazon Aurora MySQL writerクライアント
© 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 が常に増減しており、特にピーク時間帯にスパイクする
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.クエリチューニングでは根本解決しない 🤔MySQL クエリの改善内容• Index 付与• スロークエリ改修• N+1 問題によるクエリ実⾏回数• パーティショニング• 更新ロック• MySQL のパラメータ変更
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.CPU 使⽤率⾼ / DB 接続数, 接続試⾏回数スパイクアベイラビリティゾーン Cアベイラビリティゾーン Bアベイラビリティゾーン AClusterVolumeDatabase100 Table...ApplicationloadbalancerData CopiesAPPAmazon Aurora MySQL writerクライアントアプリサーバーCPU 使⽤率 ⾼ピーク時 DB 接続数接続試⾏回数のスパイクAurora インスタンスCPU 使⽤率 ⾼
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.ソリューションアーキテクト SAに技術⽀援のご相談をいただく 🧑🚒
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.SA からテックリードの⽅にヒアリング 👂環境と発⽣していた事象• 前述の通りエンドユーザーへの影響以外に困っていることはありますか︖• クエリチューニングのために Table へカラム追加や Index 付与したのですが、テナント契約が増えた結果、 Web フレームワーク経由のスキーママイグレーションにとても時間がかかるようになりました。1⽇以上かかることもあります。Table 数は 100 個ありますが、テナント毎のレコード数は多くても数⼗万程度です。機能追加にも影響出ています。• テナント契約増加にあわせてスケールアップしたため、 EC2 インスタンスと Auroraインスタンスのコストも課題なのですが、Aurora ストレージ I/O のコスト⽐率が⼤きくなっていて、削減を検討したいです。
© 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 に接続されるためです。
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.1 万 テナント Database x 100 Table100 万の Database Table 🔥
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.100 万の Database Table, リクエスト毎 DB 接続Aurora ストレージ I/O のコスト⽐率⾼アベイラビリティゾーン Cアベイラビリティゾーン Bアベイラビリティゾーン AClusterVolumeテナント毎 DB100 Table...ApplicationloadbalancerData CopiesAPPAmazon Aurora MySQL writer100 x 10,000 テナント= 1,000,000 Tables...クライアント 💸💸💸Aurora ストレージI/O のコスト⽐率⾼リクエスト毎の DB 接続Aurora エンドポイント名前解決TCP ハンドシェイク
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.テナント毎に Database Table を作成した理由は、3 年前のアプリ設計時に遡ります 🕐
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.テナント毎に Database Table を作成した理由市場投⼊までの時間を短縮したい• 個社向けに提供していた既存の Web アプリを SaaS にして新規ビジネスを早急に⽴ち上げたい︕アプリ改修を避けるために、テナント毎に database を作成しよう︕• テナント毎に database を作成する OSS Web フレームワークのマルチテナント対応プラグインを活⽤しよう︕運⽤・セキュリティ・データアクセスレイヤー作り込みの懸念• database をテナント毎に分ければ、解約時の削除が簡単• セキュリティ厳格化でテナントごとに DB 接続ユーザーと database を分けたい• シャード Database Table に複数テナントのデータを⼊れると、アプリ側でテナント分離アクセス制御の作り込みが必要になってしまうが、ノウハウがない
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.時間がかかる”より良いアプローチ”を使⽤する代わりに、今すぐ簡単で限定的な解決策を選択することが、設計判断時点ではビジネス上必要であった可能性も 🤝
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.設計判断のトレードオフを評価可能なメトリクスを定義・計測し、運⽤開始後に⾒直しできるようにすることが最も重要 🔎mysql> select count(*) from information_schema.tableswhere TABLE_SCHEMA like ‘tenant%';+----------+| count(*) |+----------+| 1000000 |+----------+
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.定常状態リソース (ファイルシステム内のログファイルであれ、 データベース内の⾏であれ、メモリ内のキャッシュであれ)を蓄積するメカニズムは、 ⾼校の微積分に出てくるバケツに似ている。 バケツにデータを蓄積していくと、⼀定の速度で満たされていく。 同じ速度かそれ以上で排出しなければ、いずれ溢れてしまう。 バケツが溢れたら⼤変だ。 サーバがダウンしたり、 データベースが遅くなったりエラーを投げたり、 レスポンス時間が天⽂学的に膨れ上がったりする。 リソースを蓄積するあらゆるメカニズムでは、そのリソースをリサイクルする何らかのメカニズムがほかに存在しなければならない。 これが 「定常状態」 パターンの考え⽅だ。Release It︕ 本番⽤ソフトウェア製品の設計とデプロイのために (p. 107)Michael T. Nygard 著、でびあんぐる 監訳
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.対策1:Aurora ストレージ I/O コスト 🧯
© 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 の使⽤のベストプラクティス – テーブルの数
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.単⼀インスタンス、シャード Database(プールモデル) でテナント毎のテーブル数増加を防ぐブリッジモデル プールモデルサイロモデルアプリレイヤーInstancedatabase1 database2database databaseInstance Instance InstancedatabaseTenant 1 84049-49 TrueTenant 2 82-84-949 FalseTenant 1 Bob SmithTenant 2 Lisa Johnsonテナント毎インスタンス 単⼀インスタンス、シャード Database単⼀インスタンス、テナント毎 DatabaseSaaS Storage Strategies - Building a multitenant storage model on AWS | AWS Whitepaper
© 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 AuroraPostgreSQL では 8 KB のページサイズをサポートしています。ページサイズは、データベースエンジンが実⾏する最⼩の I/O 操作です。99.98% 以上を⽬標に、バッファキャッシュのヒット率: BufferCacheHitRatio を監視します。Planning I/O in Amazon Aurora | AWS Database Blog
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.シャード Database Table とテナント毎 Database Table の⽐較シャード Database Table (プールモデル)• 16KB ページに複数テナントデータが含まれ、バッファプールがより効率的に。※データ・アクセス頻度依存table_aTenantAtable_aTenantATenantBTenantCTenantDtable_aTenantBtable_aTenantCバッファキャッシュテナント毎 Database TableLRU でバッファプールから削除DB TenantA DB TenantB DB TenantC DB TenantDtable_aTenantDバッファキャッシュシャード Database TableDB TenantAllテナント毎 Database Table (ブリッジモデル)• 16KB ページは単⼀テナントデータのみで I/O オーバーヘッドが⼤きい。⾼アクセス頻度ページが LRU でバッファプールから削除されやすく I/O 読込が増え、性能維持にはより多くのメモリを持つインスタンスが必要に。
© 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
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.初期設計時に PostgreSQL ⾏レベルセキュリティ(RLS) を候補に⼊れるinstancedatabaseschematenant_id user_id usernametenant1 1 Suzukitenant1 2 Satotenant2 1 Nakamuratenant2 2 Takahashitenant3 1 Yamadauser_id usernameuser_id username1 Yamadauser_id username1 Suzuki2 Sato-- Tenant1SET app.current_tenant = ‘tenant1’;SELECT user_id,usernameFROM usersWHERE tenant_id = ‘tenant1’;-- Create TableCREATE TABLE users(tenant_id VARCHAR(20),user_id INT,username VARCHAR(20),PRIMARY KEY(tenant_id,user_id));-- Insert DataINSERT INTO users VALUES('tenant1',1,'Suzuki’);INSERT INTO users VALUES('tenant1',2,'Sato’);INSERT INTO users VALUES('tenant2',1,'Nakamura’);INSERT INTO usersVALUES('tenant2',2,'Takahashi’);INSERT INTO users VALUES('tenant3',1,'Yamada’);-- Create PolicyCREATE POLICY tenant_isolation_policy ON usersUSING (tenant_id =current_setting('app.current_tenant’)::varchar);ALTER TABLE users ENABLE ROW LEVEL SECURITY;Aurora PostgreSQL の RLS 設定※ PostgreSQL 9.5 以降users tablePostgreSQL の⾏レベルのセキュリティを備えたマルチテナントデータの分離-- Tenant2SET app.current_tenant = ‘tenant2’;SELECT user_id,usernameFROM usersWHERE tenant_id = ‘tenant1’;-- Tenant3SET app.current_tenant = ‘tenant3’;SELECT user_id,usernameFROM users;※プライマリキーには数値シーケンスを使⽤し、⼤規模なデータセットのスケーラビリティとパフォーマンスを向上させることを推奨
© 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 クラスター設定
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.対策2:アプリサーバー、リクエスト毎の DB 接続 🧯
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.コネクションプーリング (持続的接続)Python SQLAlchemy のコード例import sqlalchemypool = 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 ハンドシェイクを都度実⾏
© 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 クォータ
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.Private subnet CPublic subnet CPublic subnet A Private subnet Aすべての接続でコネクションプーリング有効化を検討 VPCアベイラビリティゾーン AAPPクライアントInternetInternetgateway APP SG DB SGAurorawriterALB SGアベイラビリティゾーン CAPPApplication loadbalancerElastiCacheRedisAurorareaderElastiCacheRedis負荷テストツール
© 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 loadbalancerwriter readerwrite readAWS での分散負荷テスト | 実装 | AWS ソリューション
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.改善後アーキテクチャアベイラビリティゾーン Cアベイラビリティゾーン Bアベイラビリティゾーン AClusterVolumeApplicationloadbalancerData CopiesAPPAmazon Aurora MySQL writer10,000 テナント = 100 Tableクライアントシャード Database Table(プールモデル)によるバッファキャッシュの活⽤コネクションプーリングの活⽤tenant_id user_id nameTenantA UserA FujiwaraTenantB UserB HamaTenantC UserC MazdaTenantD UserD HondaDatabase100 Table...
© 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 リクエスト 🔥
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.アクセス解析のためにクライアントからログ収集する仕組みを追加 ⚙してから 3 年後のとある⽇。。。
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.アクセス解析対象の DAU (Daily Access User)が 30,000 を超えました👏
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.しかし、良いことばかりではなく 😢経理の⽅から、Amazon Simple Storage Service (S3) の⽉額コストが $ 5,000 を超えていると指摘が💸💸💸
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.S3 のアクセス解析ログ⽉間処理データ量は約 400GB なので、ストレージ費⽤は⼗数ドル程度のはずなのに 🤔
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.EC2 instanceEC2 instanceEC2 instanceログ収集 AWS アーキテクチャ例Applicationloadbalancerクライアント APPAPP プログラムログオブジェクトS3 バケットEC2 instanceログ集計 BATCHプログラムログ集計BATCHAmazon Aurora集計済ログデータ400GB/⽉
© 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 が最も多いが、リクエスト元が不明
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.EC2 instanceEC2 instanceEC2 instanceS3 PUT : GET : DELETE : LIST = 1 : 1 : 1 : 3以上で LIST が最も多いApplicationloadbalancerクライアント APPAPP プログラムログオブジェクトS3 バケットEC2 instanceログ集計 BATCHプログラムログ集計BATCHAmazon Aurora集計済ログデータ30,000クライアント x 1時間 60回 x ⽇中 8時間x 平⽇ 20⽇間 = 288,000,000/⽉S3 PUTS3 GETS3 DELETES3 LIST のリクエスト元が不明400GB/⽉
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.ソリューションアーキテクト SAに技術⽀援のご相談をいただく 🧑🚒
© 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 バケットをマウントしています。プログラミング⾔語からファイルシステム経由で直接読み書きでき、実装が簡単だからです。
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.EC2 instanceEC2 instanceEC2 instanceOSS の S3 ファイルシステム経由でリクエスト毎に都度 JSON Log を S3 PUTApplicationloadbalancerクライアント APPAPP プログラムログオブジェクトS3 バケットOSS S3Filesystem/mnt/s3bucketEC2 instanceログ集計 BATCHプログラムOSS S3Filesystem/mnt/s3bucketログ集計BATCHAmazon Aurora集計済ログデータリクエスト毎にJSON Log を都度 S3 PUTJSON Log1.5KB perObjectOSS の S3 ファイルシステムOSS の S3 ファイルシステムS3 LIST のリクエスト元が不明
© 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 のコスト要因でした。
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.毎⽉ 11 億の Amazon S3 PUT, COPY, POST,LIST リクエスト 🔥
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.EC2 instanceEC2 instanceEC2 instance毎⽉ 11 億の Amazon S3 PUT, COPY, POST,LIST リクエストApplicationloadbalancerクライアント APPAPP プログラムログオブジェクトS3 バケットOSS S3Filesystem/mnt/s3bucketEC2 instanceログ集計 BATCHプログラムOSS S3Filesystem/mnt/s3bucketログ集計BATCHAmazon Aurora集計済ログデータJSON Log1.5KB perObjectOSS S3 Filesystem書込S3 PUT, S3 LISTOSS S3 Filesystem削除S3 DELETE, S3 LIST30,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
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.OSS の S3 ファイルシステムを採⽤した理由は、3 年前のアプリ設計時に遡ります 🕐
© 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 と⼩容量なのでコストは問題ないだろう
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.時間がかかる”より良いアプローチ”を使⽤する代わりに、今すぐ簡単で限定的な解決策を選択することが、設計判断時点ではビジネス上必要であった可能性も 🤝再掲
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.設計判断のトレードオフを評価可能なメトリクスを定義・計測し、運⽤開始後に⾒直しできるようにすることが最も重要 🔎-- Querying CloudTrail logs - Amazon AthenaSELECT COUNT(eventname) AS cnt, eventname,useridentity.principalidFROM "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.principalidORDER BY cnt DESC再掲
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.定常状態リソース (ファイルシステム内のログファイルであれ、 データベース内の⾏であれ、メモリ内のキャッシュであれ)を蓄積するメカニズムは、 ⾼校の微積分に出てくるバケツに似ている。 バケツにデータを蓄積していくと、⼀定の速度で満たされていく。 同じ速度かそれ以上で排出しなければ、いずれ溢れてしまう。 バケツが溢れたら⼤変だ。 サーバがダウンしたり、 データベースが遅くなったりエラーを投げたり、 レスポンス時間が天⽂学的に膨れ上がったりする。 リソースを蓄積するあらゆるメカニズムでは、そのリソースをリサイクルする何らかのメカニズムがほかに存在しなければならない。 これが 「定常状態」 パターンの考え⽅だ。Release It︕ 本番⽤ソフトウェア製品の設計とデプロイのために (p. 107)Michael T. Nygard 著、でびあんぐる 監訳再掲
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.対策:毎⽉ 11 億の Amazon S3 PUT, COPY, POST,LIST リクエスト 🧯
© 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.00037S3 PUT/LIST リクエストは GET リクエストに⽐べて、10倍以上⾼額なため、S3 PUT はバッファリング・バルク処理しつつ、S3 LIST リクエストを削減できる AWS サービスを併⽤するAmazon S3 の料⾦
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.EC2 instanceEC2 instanceEC2 instance改善後アーキテクチャApplicationloadbalancerクライアント APPAPPプログラムログオブジェクトS3 バケット ログ集計JSON Log< 128MB perObjectAWS SDKAmazon KinesisData Firehose30,000クライアント x 1時間 60回x ⽇中 8時間 x 平⽇ 20⽇間= 288,000,000/⽉Amazon KinesisData StreamsEC2 instanceログ集計プログラムAWS SDKAmazon Aurora集計済ログデータバッファリングサイズ: 128MBインターバル: 300秒JSON Log1.5KB perObjectAmazon SQSS3 EventNotificationsS3 PUT オブジェクトキー情報をログ集計で利⽤アプリ・ログ集計で AWS SDK を使⽤
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.S3 署名付き URL HTTP POST で画像など⼤容量ファイルをクライアントから直接アップロードimport loggingimport boto3def create_presigned_post(bucket_name, object_name,fields=None, conditions=None, expiration=60):# Generate a presigned S3 POST URLs3_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 fieldsreturn responseGenerating a presigned URL to upload a file – Boto3Python boto3 のコード例EC2 instanceAPPプログラムAWS SDK S3 バケットクライアントWeb ブラウザーAPP1. 署名付きURL ⽣成リクエスト2. HTTP POSTで直接アップロードresponse[ʻurlʼ], response[ʻfieldsʼ] にHTTP FORM に必要な URL,FIELD データが含まれるため、クライアント JavaScript でアップロード可能
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.まとめ
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.まとめ• クラウド上の Web アプリ設計時のアーキテクチャ選択がネットワークおよびストレージ I/O 最適化余地を決定し、⾮機能要件である安定性・コストへより直接的に影響する• 過去に選択した設計アーキテクチャのトレードオフが後に顕在化する可能性• システム設計の判断⼒をつける⼀番の⽅法は、⾃分で設計したシステムを⻑い間メンテすること• 失敗知識は貴重です︕ぜひみなさんも社内外で共有しましょう︕
© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.Thank you!© 2023, Amazon Web Services, Inc. or its affiliates. All rights reserved.