re:Invent 2024: AWSが解説するAmazon S3のパフォーマンス最適化戦略
はじめに
海外の様々な講演を日本語記事に書き起こすことで、隠れた良質な情報をもっと身近なものに。そんなコンセプトで進める本企画で今回取り上げるプレゼンテーションはこちら!
📖 AWS re:Invent 2024 - Optimizing storage performance with Amazon S3 (STG328)
この動画では、Amazon S3のパフォーマンス最適化について、AWSのエンジニアリングディレクターのChristoph BartensteinとPrincipal ScientistのValentin Flunkertが解説しています。一桁ミリ秒でのアクセスを実現するS3 Express One Zoneや、パフォーマンスを2倍に向上させるAWS Common Runtime (CRT)、ファイルインターフェースのMountpointなど、最新の改善点を紹介しています。また、並列化やプリフェッチ、キャッシング、適切なデータパーティショニングなど、ワークロード全体のパフォーマンスを最適化するための具体的な手法も説明しています。特に、Apache Sparkを使用したTPC-DSベンチマークでは、ファイルサイズの最適化により実行時間を8分の1に短縮できた事例など、実践的な最適化手法が示されています。
※ 動画から自動生成した記事になります。誤字脱字や誤った内容が記載される可能性がありますので、正確な情報は動画本編をご覧ください。
※ 画像をクリックすると、動画中の該当シーンに遷移します。
re:Invent 2024関連の書き起こし記事については、こちらのSpreadsheet に情報をまとめています。合わせてご確認ください!
本編
Amazon S3のパフォーマンス最適化セッション:概要と重要性
皆様、こんにちは。本日の Amazon S3 のパフォーマンス最適化に関するセッションへようこそ。おそらく今日最後のセッションになりますので、価値のあるものにしていきましょう。私は Christoph Bartenstein です。AWS のエンジニアリングディレクターとして約10年間勤務しています。ここ数年は、お客様向けのシステムのパフォーマンスをどのように改善できるか、パフォーマンス改善について多くの時間を費やしてきました。本日は同僚の Principal Scientist の Valentin Flunkert も一緒です。
今日は、S3 のパフォーマンスをどのように最適化できるかについてお話しします。ストレージのパフォーマンスがなぜ重要なのかを説明し、お客様がパフォーマンスに関してどのような取り組みを行い、どのような影響があったのかの実例をご紹介します。その後、パフォーマンスに関するメンタルモデル、リクエストパフォーマンスとワークパフォーマンスの違い、リクエストの考え方、そしてその背後にあるアーキテクチャについて掘り下げていきます。また、新しいストレージクラス、ライブラリ、ファイルなど、この数ヶ月間で実施してきた改善についてもご紹介します。本日のセッションで最も重要なポイントは、これらのパフォーマンス改善をどのようにアプリケーションの高速化に活用できるかということです。
ストレージパフォーマンスの重要性とその影響
では、ストレージのパフォーマンスが重要な理由から始めましょう。Amazon S3 にデータを保存している方は手を挙げてください。かなりの数の方がいらっしゃいますね。おそらく皆さんも、スロットリングの問題や、レイテンシーが期待通りでない、あるいはお客様の体験が望ましいものではないなど、何らかのパフォーマンスの課題に直面されたことがあるのではないでしょうか。様々なユースケースを考えると、バックアップ、データレイク、機械学習モデルの実行など、それぞれで求められるパフォーマンス要件は大きく異なります。
お客様からは、データがかつてないスピードで増加しているという声を多く聞きます。これは2つのことを意味します。1つ目は、パフォーマンスがデータの可能性を解き放つということです - より迅速な洞察、より深い洞察が得られ、それらの洞察からより多くのことができるようになります。結果として、より素早く市場投入戦略を立て、トレンドに迅速に対応できるようになります。2つ目は、ワークロードが高速化されることで、お客様の体験が向上するということです。コンテンツをより速く提供できれば、エンドユーザーに良い影響を与えることができます。パフォーマンスがデータの可能性を解き放つということを、お客様は繰り返しおっしゃっています。
データがかつてないスピードで増加している世界では、パフォーマンスはコストに大きな影響を与えます。請求書を見ると、ストレージは恐らく最大の項目ではなく、コンピューティングの方がはるかに大きいかもしれません。非常に重要なのは、コンピューティングリソースが適切に活用されていることを確認することです。S3 からのデータの取り出しと保存を迅速に行えるようにすることで、コンピューティングワークロードの利用率を向上させ、Total Cost of Ownership を削減することができます。
S3の仕組みとリクエスト・ワークロードの違い
S3の仕組みと、リクエストとワークロードの違いについてお話ししましょう。 多くの方がS3にデータを保存されているので、アーキテクチャの概要を説明させていただきます。これは本当に高レベルな概要です。基本的に、S3は400兆以上のオブジェクト、エクサバイト規模のデータを保存し、1秒間に数億のリクエストを処理する非常に大規模な分散サービスです。S3へのデータの書き込みや読み取りなど、すべてのリクエストにおいて、クライアントはルックアップを行い、Webサーバーに接続し、そのサーバーがインデックスを参照します。インデックスはストレージフリート内のストレージブロックの場所をリクエストに示し、その後すべてのデータがクライアントにストリーミングで返されます。実際にはもっと多くのステップが関係していますが、1つのリクエストでもかなりの処理が必要なことがお分かりいただけると思います。
リクエストが重要な理由を理解するために、1つのS3リクエストの裏側で何が起きているのか、詳しく見ていきましょう。これには複数のステップが含まれており、First Byteまでの時間というオーバーヘッドに関する重要な考え方があります。すべてのリクエストにおいて、サーバーへの接続、ハンドシェイク、認証などのプロセスを含むオーバーヘッドが最初に発生し、その後データ転送が始まります。究極的には、このオーバーヘッドをできるだけ削減することが目標で、後ほどその方法の例をご紹介します。
ワークロードを考える際、レイテンシーに敏感なものがあります。例えば、Amazon S3に保存した画像を取り出してお客様に提供する場合、そのリクエストのレイテンシーが重要で、そのリクエストを最適化したいと考えます。一方で、S3に対して何千、何百万というリクエストを実行するETLジョブのような別のワークロードもあります。S3は非常に広範に水平スケーリング可能な大規模分散システムで、数千、数万のリクエストを処理するのは普通のことです。このような場合、個々のリクエストのレイテンシーよりも、ワークロード全体のパフォーマンス、つまりスループットが重要になります。
ワークロードの特性を見極めることで、異なるリクエストを並列化したり、S3全体に広く分散させたり、多くのオブジェクトを結合してオーバーヘッドを削減したり、プリフェッチを実装したり、キャッシングを活用したりすることができます。これらの手法については後ほど詳しく説明しますが、まずはパフォーマンスについて考えるための基本的な考え方をご理解ください。 もう1つ重要な側面は、リクエストとパフォーマンスの測定方法です。測定できないものは改善できません。
幸いなことに、測定を支援する複数のサービスと機能があります。Amazon CloudWatchやAmazon S3 Storage Lensでワークロードのパフォーマンスメトリクスを確認できます。各S3リクエストのパフォーマンスを詳細に理解したい場合は、Amazon S3 Server Access Logsを調べることができます。重要なのは、改善したい項目を測定することです。レイテンシーに敏感なワークロードでは、First ByteレイテンシーとLast Byteレイテンシーに注目します。スループットに敏感なワークロードでは、スロットリングを避けるため、集計スループットとリクエストレートを考慮します。
Amazon S3の最新の改善点:新ストレージクラスとライブラリ
パフォーマンスをどのように改善してきたか、そしてお客様がそれらの改善をどのように活用できるのか、いくつかの具体例をご紹介させていただきます。この数ヶ月間、私たちはいくつかの重要な改善を実現してきました。 一桁ミリ秒でのアクセスを実現する新しいストレージクラスのAmazon S3 Express One Zoneをリリースしました。また、AWS Common Runtimeという新しいライブラリの導入や、新しいファイルコネクターのMountpointの発表、さらにS3AやS3Fによるオープンソース世界への貢献も行いました。これらの貢献は、特にデータレイクやMachine Learningのユースケースにおいて重要な意味を持っています。
後ろのスライドをご覧いただくと、これまでに私たちがリリースしてきた様々なストレージクラスがわかります。これらのストレージクラスは、お客様のニーズに応じて様々な価格とパフォーマンスのオプションを提供しています。数十ミリ秒でのアクセスを実現するStandardがあり、データへのアクセス頻度が低い場合にはS3 IAやS3 Intelligent-Tieringをご利用いただけます。tier間のデータ移動を自動化したい場合は、Intelligent-Tieringが自動的に処理してくれます。そして、取り出しコストを最小限に抑えたアーカイブ用のストレージクラスもあります。そして左端に新しく加わったのが、一桁ミリ秒でのアクセスを実現するS3 Express One Zoneです。
S3 Express One Zoneについて詳しくお話ししたいと思います。これは本当にエキサイティングな機能で、すでに多くのお客様にご利用いただいています。 Express One Zoneでは、一桁ミリ秒の低レイテンシーと非常に高いスループットを実現しています。結果として、Standardと比較してパフォーマンスを10倍向上させながら、リクエストコストを50%削減することができます。頻繁にアクセスされるデータに最適化され、1分間に数百万のリクエストまでスケールでき、Machine Learningのトレーニング、インタラクティブな分析、メディアファイルを扱うコンテンツ制作などに最適です。これは、頻繁にアクセスされるオブジェクト向けに最適化された、大幅なパフォーマンス向上を実現する高性能ストレージクラスなのです。
お客様からよくその仕組みについて質問を受けますので、その背景についてもご説明させていただきます。 S3 Express One Zoneは、その名前が示す通り、複数のAvailability Zoneにデータを保存する他のストレージクラスとは異なり、単一のAvailability Zoneにデータを保存します。これにより、Computeと同じAvailability Zoneにストレージを配置することができ、この近接性によってパフォーマンスが向上します。Express One Zoneは、標準的なストレージクラスと比べて特別に高速なメディアにデータを保存し、認証やオーバーヘッドが最適化されています。また、従来のフラットなバケットではなく、階層的なディレクトリバケットという新しいタイプのバケットを採用しています。これらの機能が組み合わさることで、先ほど申し上げたパフォーマンスの向上を実現しているのです。
S3 Express One Zoneは非常に人気があり、多くのお客様にご利用いただいています。その一例が、モバイルアプリを開発しているLyrebird Studioです。彼らはS3にデータを保存していますが、頻繁にアクセスされるデータの一部をAmazon S3 Express One Zoneに移行しました。このデータは頻繁にアクセスされていたため、取り出し時間が大幅に短縮され、TCOを約18%削減することができました。
このStorage Classへの投資を続けているのは、パフォーマンスが重要な焦点だからです。Express One Zoneでは、先週、Append操作の機能をリリースしました。これにより、変更を加える際にオブジェクトを書き直す必要がなく、追加できるようになり、大幅なパフォーマンス向上が実現しました。また、Lifecycle Expiration、KMSのサポートなど、さらに多くの機能が追加され、パフォーマンスの最適化を目指すお客様にとって、ますます魅力的なStorage Classとなっています。
AWS Common Runtime(CRT)とMountpointによるパフォーマンス向上
AWS Common Runtime(CRT)についてお話ししましょう。すでにご存知の方もいらっしゃると思いますが、無料で利用できることをご存知でしょうか。CRTは裏側でさまざまな最適化を行っており、I/O集中型ワークロードのベストプラクティスを実装しています。C++で書かれており、タイムアウト、リトライ、ロードバランシング、並列化の最適化をバックグラウンドで処理します。CRTは数ヶ月前にリリースされ、Java SDKなど多くのSDKに統合されており、最大2倍のパフォーマンス向上を実現しています。
CRTの仕組みについて説明させていただきます。CRTはクライアントとAmazon S3の間に位置し、クライアントからCRTにリクエストが送られると、そのリクエストが最適化されます。例えば、1つのリクエストが並列化され、複数のS3へのリクエストに分割されます。並列化によってスループットが最適化され、データがクライアントに戻されます。これらの処理は裏側で行われるため目には見えませんが、スループットのパフォーマンスを最適化する方法の良い例といえます。
具体的な例を挙げてみましょう。インスタンスに1ギガバイトのファイルを100個ダウンロードしたいとします。AWS CLIを使用した場合、約8分かかります。まったく同じことを、SDKでAWS Common Runtime(CRT)を有効にして実行すると、4分で完了し、2倍の速さになります。つまり、特にI/O集中型のワークロードでは、裏側でパフォーマンスが向上するということです。
次の改善点についてお話ししましょう。お客様の中には、ファイルアプリケーションを使用しながらも、POSIXに準拠する必要がない、あるいはAmazon S3のようなスケーラビリティを求めているため、Amazon S3にデータを保存したいと考える方々がいます。そういったお客様向けに、昨年私たちはMountpoint for Amazon S3というファイルインターフェースを導入しました。これは、オブジェクトをファイルとしてマウントし、ファイルアプリケーションのAPIコールをREST APIコールに変換して、パフォーマンスを向上させる機能です。CRTと統合されており、データのプリフェッチ、シーケンシャルデータの最適化、データのキャッシングによってパフォーマンスが向上します。
Mountpointに関して興味深いのは、この1、2週間でさらに多くの改善を発表したことです。まず、MountpointがMulti-NICをサポートするようになりました。Multi-NICをサポートする2つのインスタンスで広帯域を実現する場合、Mountpointもそれに対応できるようになりました。次に、とても興味深い機能として、分散キャッシングが挙げられます。先ほどStandardクラスとExpressクラスについて触れましたが、Mountpointを使用すると、データをStandardに保存し、そこからデータを取り出す際に、最もアクセス頻度の高いデータをExpressにキャッシュすることができます。ローカルキャッシュに加えて、分散キャッシュも利用できるようになりました。キャッシュのサイズを考えたり、スケールアップやダウンを気にしたりする必要はなく、必要に応じて使用でき、データをS3に保存して可用性を確保しながら、Expressのパフォーマンス向上を実現できます。
自動車部品サプライヤーとして皆さんご存じのContinentalは、S3にデータを保存し、データシミュレーションやテストシミュレーション用にS3からDockerコンテナにデータを移動するワークロードを持っています。彼らはこのデータを高速に取り出すためにMountpointを使用し、約20%というかなり印象的なパフォーマンス向上を達成しました。
Machine Learningは、皆さんがよく話題にする使用例の1つでしょう。私たちには多くのMachine Learningのユースケースを持つお客様がいますが、彼らと話をすると興味深いことに、GPUの高い利用率を確保することが大きな課題の1つだとよく言われます。つまり、S3からデータを素早く取得する必要がありますが、同時に、数時間から数日間実行されることの多いMachine Learningモデルを実行する際には、頻繁にチェックポイントを取りたいと考えます。つまり、データを高速に取り出し、チェックポイントを高速に書き戻す必要があるのです。
多くのお客様が、おそらく最も人気のあるMachine Learningフレームワークの1つであるPyTorchを使用しています。私たちは比較的新しいAmazon S3 connector for PyTorchをリリースしましたが、これはトレーニングジョブを本当に最適化します。S3からトレーニングデータを4〜5倍速く取得できます。今週は分散チェックポイントをリリースし、分散方式でチェックポイントを取得し、より高速にS3にデータを書き戻すことができるようになりました。試してみたい方は、ぜひチェックしてみてください。PyTorchは非常に人気のあるフレームワークで、現在S3との相性も抜群です。
もう1つのユースケースとしてデータベースについてお話ししたいと思います。Amazon S3はデータレイクとして非常に人気があり、数万ものデータレイクがAmazon S3上に存在しています。
これらのデータレイクについて、私たちはお客様のパフォーマンスを最適化するためにどのようなサポートができるか検討しました。データレイクを考えるとき、最も一般的なファイル形式の1つがParquetです。S3上にエクサバイト規模のデータがParquet形式で保存されているだけでなく、それらがどのように接続されているかも考える必要があります。多くのお客様から、S3のようなコネクタを使ってデータに接続していると聞いています。そこで、これらのユースケースのパフォーマンスを最適化する方法を検討しました。
ここで少し立ち止まって考えてみましょう。多くの方がご存知のParquetファイルについて調査することにしました。Parquetファイルは、フッターサイズ、フッター、そして実際の行グループで構成されています。通常、まずフッターのサイズを確認するためのリクエスト、次にフッターへのリクエスト、そして3番目にデータセットを確認するためのリクエスト、最後にデータ行グループへのリクエストが行われます。すでにかなりの数のリクエストが発生していることがわかります。そこで、これをどのように最適化できるか検討しました。 最初に行ったのは、フッターサイズをオーバーリードして1回のリクエストにまとめることでした。リクエストサイズを調整してみたところ、まさにそれが最初のリクエストを改善する方法となりました。オーバーリードにより2回のリクエストを1回に減らしました。1メガバイトを読み込むことで、99.9%のフッターサイズをカバーできます。言い換えれば、99%のフッターが1メガバイト以下だということです。
2番目の改善点については、お客様からの声とデータから、同じフッターに対して何度も繰り返しリクエストが行われていることがわかりました。そこでフッターをキャッシュすることでパフォーマンスを向上させました。3番目の改善点は並列化に関するものです。行グループへの様々なリクエストをどのように最適化できるか検討し、先ほど説明した方法を使って並列化することで、パフォーマンスとスループットを大幅に最適化することができました。 これらの改善点をすべて組み合わせて、Analytics Accelerator Libraryと呼ばれるオープンソースライブラリとして公開しました。GitHubリポジトリで利用可能で、先週アルファリリースとして公開されたばかりです。フィードバックをお待ちしています。このライブラリは、プリフェッチ、シーケンシャルアクセス、優先順位付け、Parquetファイルフッターのキャッシングなどを処理します。このライブラリに接続するだけで、パフォーマンスの向上を得ることができます。
これが最近のオープンソースへの貢献の一部です。最後に、基調講演やストレージの講演ですでにお聞きになったかもしれませんが、Amazon S3 Tablesについてお話ししたいと思います。 これは今週リリースしたばかりの完全に新しい機能です。S3上にデータテーブルを保存することができ、コンパクションやスナップショット管理といったIcebergの最適化をすべて活用できる点で非常に興味深い機能です。その結果、1秒あたりのトランザクション数が10倍に、クエリのパフォーマンスが3倍に向上します。これは完全に新しい機能で、今まさにリリースされたばかりです。私たちはこの機能に非常に期待しており、今後さらに多くの情報をお届けできると思います。
ワークロードパフォーマンス最適化:並列化とスロットリング回避
これらが私たちが実現した改善点の一部です。 ここでValentinに引き継ぎますが、Storage Classから、CRT、ライブラリ、そしてオープンソースのConnectorまで、皆さんにご紹介した改善点について、Valentinがそれらの活用方法を実演してくれます。そして、私たちからさらに多くの進展をお見せできると思います。では、Valentin、お願いします。ありがとう、Christoph。ワークロードのパフォーマンスをさらに向上させる方法についてお話しさせていただきます。私はS3のScientistのValentin Flunkertです。私のチームは、データアクセスパターンの分析と、パフォーマンス最適化の可能性について、広範な研究を行ってきました。その知見の一部を皆さんと共有したいと思います。
まず、ワークロードのパフォーマンスを改善するための主要な手段について見ていきましょう。改善できる主な要因の一つが並列化です。並列化を増やすことで、ワークロードのパフォーマンスを向上させることができます。これは最も重要な手段の一つで、後ほど詳しくご説明します。また、個々のリクエストに目を向けると、リクエストのオーバーヘッドを削減できますし、プリフェッチやキャッシングを適用することでもワークロードを高速化できます。
最初の最適化である並列化について詳しく見ていきましょう。並列化は全体的なスループットを改善するため、非常に重要です。通常、多数のリクエストを並列で送信することで実現します。Multipart Uploadを使用してデータを並列にアップロードしたり、多数の並列Range-GETを使用してダウンロードを並列化したりできます。この高度な並列化においては、スロットリングを避けるために、データを適切に分割することが重要なポイントとなります。
一般的なワークロードは単一のリクエストだけではありません。何千、何百万ものリクエストが含まれる可能性があります。左側の図は、アプリケーションがリクエストを送信し、データが返ってくるのを待ってから次のリクエストを送信する、シーケンシャルなワークロードを示しています。これは非常に非効率的です。リクエストを並列化できれば、はるかに優れたパフォーマンスが得られます。並列でリクエストを送信することで、パフォーマンスがどれだけ向上するかがわかります。
具体例を見てみましょう。100メガバイトのファイルをAmazon S3にアップロードする場合、単一のPUTリクエストでデータをアップロードすることができ、1つの接続で一定のスループットが得られます。しかし、実際にはオブジェクトやファイルを小さな部分に分割し、Multipart Uploadを使用してそれらの部分を並列にアップロードする方が、はるかに効果的です。これにより、アップロードのパフォーマンスが大幅に向上します。
これがCLIでの動作方法です。単一のPutリクエストを送信する代わりに、Multipart Uploadを開始し、その後、多数のパートを並列でアップロードします。同じことがデータのダウンロード時にも当てはまります。例えば、100メガバイトのオブジェクトがあるとします。単一の接続でダウンロードすると、およそ90メガバイト/秒のスループットが得られます。しかし、ダウンロードを並列化すると、はるかに高速なダウンロードレートを実現できます。実際、十分に並列化すれば、単一のオブジェクトに対して数百ギガビット/秒という速度を実現することも可能です。これが、アプリケーションのパフォーマンスを向上させる主な方法の1つです。
単一のパートをダウンロードしたり、Range Requestを使用して特定のデータチャンクをダウンロードしたりすることができます。重要なポイントとして、AWS Common Runtime(CRT)やMountpointなど、多くのクライアントでは、これらの最適化が最初から組み込まれています。つまり、CRTやMountpointを使用する場合、特別な設定をしなくても、アップロードとダウンロードが自動的に並列化されます。ただし、独自のアプリケーションロジックを使用している場合は、この並列化を活用し、次のリクエストを送信する前にブロックしないようにすることが非常に重要です。
並列化は素晴らしい機能で、ワークロードを大幅に高速化できますが、では、際限なく並列化を増やせば、どんどんパフォーマンスが向上するのでしょうか?残念ながら、そうではありません。並列化には一定の限界があるのです。その理由は、並列化によってクライアントに負荷がかかるためです。リクエストを送信するたびに、クライアントはCPU、メモリ、ネットワークの一部などのリソースを使用します。並列化を増やしていくと、CPUが他のリクエストの処理で忙しくなるため、個々のリクエストの処理時間が長くなってしまいます。ある時点で収穫逓減が発生し、さらに並列化を進めると、実際にワークロードが遅くなってしまうのです。
ここで明確にしておきたいのは、むしろ多くの場合、お客様は並列化を十分に活用できていないということです。これは極端な例で、非常に高度な並列化を使用した場合に見られる現象です。ほとんどのユースケースでは、並列化のレベルを高く保つことが重要です。並列化のもう1つの制限はS3側にあり、これはクラスターから多数のリクエストを送信する場合に発生する可能性があります。
例えば、数十万台のマシンを持つSparkクラスターからデータにアクセスする場合を考えてみましょう。このようなクラスターから多数のリクエストを送信すると、スロットリングが発生する可能性があります。これは503のレスポンスコードとして現れ、Amazon S3が本質的にリクエストを抑制しているということです。では、これがいつ発生し、どのように回避できるのか見ていきましょう。
スロットリングがどのように発生するのか理解するために、先ほど見たリクエストのパスを振り返ってみましょう。多数の並列リクエストを送信すると、S3のフロントエンドで並列化が行われ、これはボトルネックなく完全に並列化されます。しかし、すべてのキーが共通のプレフィックスを共有している場合、インデックスにホットスポットが発生する可能性があります。インデックスは基本的に、特定のスループットやTPSを提供するパーティションを持つ、すべてのキーをアルファベット順にソートしたリストです。すべてのキーが1つのパーティションにある場合、これらの並列リクエストがその単一のパーティションに集中し、オーバーワhelm状態になることがあります。このような状況が発生すると、S3は自身と他の顧客を保護するために、スロットリングや503エラーを発生させる必要があります。
データを適切にパーティション化することで、このスロットリングを回避する簡単な方法があります。 後ほど詳しく説明しますが、これらのプレフィックスは、最初から非常に高いリクエストレートを提供します。1秒あたり3,500回のPutと5,500回のGetを送信できます。大多数のワークロードやお客様にとって、これはスロットリング問題を回避するのに十分な数値です。ただし、クラスターから非常に大きなリクエストレートがある場合、スロットリングが発生する可能性があります。ここで疑問が生じます:この制限を超えた場合はどうなるのでしょうか?この制限以上のリクエストレートを持つワークロードがある場合、より高いリクエストレートを達成できないということなのでしょうか?
バケットは必要なだけTPSにスケールできますが、その仕組みを理解する必要があります。 プレフィックスという概念について説明しましょう。 この概念は少し微妙です。プレフィックスとは、バケット名の後に続く任意の文字列のことです。例えば、reinvent-bucketというバケットがあるとします。 そのバケット名の後に続くキー名のどの部分もプレフィックスとなります。
これらのプレフィックスがリクエストレート、TPS、スロットリングにどのように関係するのか、例を見てみましょう。 このreinvent-bucketがあり、re:Inventの1日目にday1というプレフィックスにデータを入れると、そのプレフィックスは最初から5,500 TPSを提供します。より高い負荷を送信すると、S3はそのプレフィックスへの持続的な高負荷を検知し、分割操作を実行します。最初は1つのパーティションにあったキーが2つのパーティションに分割され、それぞれが5,500 TPSを提供します。S3は、キーを2つの部分に分離するプレフィックスを見つけようとします。この例では、一方がday1/catsプレフィックス、もう一方がday1/dogsプレフィックスとなり、それぞれ異なるパーティションに配置されます。負荷がさらに高い場合、S3は別のラウンドの分割を実行します。この例では、最終的にそのバケットで22,000 TPSを得ることができ、必要なTPSを達成するまでこのプロセスを続けることができます。
S3が負荷に応じてスケールアップするため、これは素晴らしく聞こえますが、問題があります。 パーティションを効率的に再利用できない可能性があるのです。例えば、re:Inventの2日目に、day2という新しいプレフィックスを作成してそこにデータを置くと、day1のパーティションは未使用のまま残ります。day2プレフィックスをスケールアップする必要がありますが、そのプロセスが進行する間はスロットリングを経験する可能性が高いのです。
この Day2 プレフィックスに対する負荷を以前に見たことがないため、これは新しいプレフィックスの新しいデータということになります。以前に負荷がなかったため、スケールアップされていません。その結果、スケーリングが完了するまでスロットリングが発生することになります。これは理想的ではありません。私たちが望むのは、すでにスケールアップされているプレフィックスを再利用することです。Day1 でプレフィックスをスケールアップするために多くの作業を行ったので、それを活用して再利用する方法を見つける必要があります。
実はこれは簡単に実現できます。キー名において Day1 を右側に移動すると、初日には次のようなことが起こります。S3 がプレフィックスをスケールアップします。この場合「data」という共通のプレフィックスがあるので、そのプレフィックスがスケールアップされます。そのバケットに対して22,000 TPS を得ることができます。翌日には、Day2 の文字列がそのプレフィックスの一部となるため、バケットとプレフィックスはすでにスケールアップされており、プレフィックスをスケールアップした際の22,000 TPS がすぐに利用可能になります。
ここでの一般的な考え方は、日付や時間とともに変化する要素をキー名の中でできるだけ右側に移動させるということです。ID や高いカーディナリティを持つ文字列は左側に配置すべきで、通常はそれで十分です。データをさらに細かくパーティション分割したい場合は、キー名にランダム性を導入することができます。お客様の中には、キーの一部をハッシュ化してプレフィックスとして使用することで、最適なユースケースを実現している例もあります。
これは複雑に聞こえるかもしれませんが、いくつかのシナリオでは実装がはるかに簡単です。必ずしも手動で行う必要はありません。Apache Icebergテーブルを使用する場合、Icebergが自動的にこれを行ってくれます。キー名のこのランダム性は、Icebergが最適化する要素の1つなので、すぐに利用できます。Christophが言及したように、より高い TPS を提供する S3 Tables もあります。Icebergテーブルの場合は、S3 Tables を使用することで、すぐに高い TPS を得ることができます。最後に、スケーリングを待つ余裕がない非常にバースティな負荷の場合は、事実上無制限のリクエストレートを提供する S3 Express One Zone の使用を検討することができます。
リクエスト最適化とキャッシング:効率的なデータアクセスの実現
スループットの最適化と並列化によるダウンロードの最適化について説明してきましたが、ここで単一のリクエストに注目して、最適化できることを見ていきましょう。最初に考慮すべきはリクエストサイズとオブジェクトサイズで、これについては詳しく見ていきます。レイテンシーを最適化したい場合は、クライアント側に十分なリソースがあることを確認する必要があります。クライアントには十分なCPUとメモリが必要です。そうでないと、リクエストが遅くなる可能性があります。シングルディジットミリ秒のレイテンシーが本当に重要な場合は、S3 Express One Zone を使用することができます。
リクエストサイズとその最適化方法について見ていきましょう。リクエストは、サイズに関係なく、通常同じようなオーバーヘッドを持っています。クライアントがS3に接続し、S3がデータを見つけ、ディスクからデータを読み込むなどの処理が必要です。すべてのリクエストは、最初のバイトを受け取るまでの時間がほぼ同じですが、小さなリクエストではその作業量がごくわずかです。小さなリクエストでは、大きなオーバーヘッドの割に転送されるデータ量が少ないのに対し、大きなリクエストではより多くのデータを転送できます。このように、大きなリクエストサイズを使用することで、オーバーヘッドを分散させ、全体的なパフォーマンスを大幅に向上させることができます。
この例では、小さなファイルと小さなリクエストサイズを使用するワークロードがあり、多くのオーバーヘッドが発生していることがわかります。このワークロードを改善する一つの方法は、S3 Express One Zoneを使用してオーバーヘッドを削減することです。もう一つの改善方法は、より大きなファイルを使用することです。 このワークロードの例では、多数の小さなファイルがあるため、クライアントは多くのリクエストを送信する必要があります。
これらの多数のリクエストは、個々では大きな成果を上げられません。しかし、これらの小さなファイルを一つの大きなファイルにまとめることで、同じデータをより効率的に1回のリクエストで転送できる大きなリクエストを作成できます。これによってワークロードの実行時間を大幅に短縮できます。このアプローチがワークロードのパフォーマンスをどれだけ改善できるか、具体例を見てみましょう。
ここでは、Apache Sparkでよく使用されるデータレイクベンチマークであるTPC-DSを使用し、3テラバイトのデータで検証しています。 一つのシナリオでは1メガバイトサイズの小さなファイルでデータを保存し、もう一つのシナリオでは同じデータを128メガバイトの大きなファイルサイズで保存しています。大きなファイルを使用したワークロードは8倍速く実行され、全体のコストは25分の1に削減されました。これは、クラスターの実行時間が8分の1になることで大幅な計算コストが節約され、さらにリクエスト数が減ることでリクエストコストも削減されるためです。
次に、プリフェッチとキャッシングという2つの要因について見ていきましょう。 プリフェッチとは、データが必要になる前にダウンロードしておくという考え方です。 先ほど並列化について説明しましたが、これは必ずしも可能とは限りません。その代わりとなる有効な選択肢がプリフェッチです。逐次的なアプローチでは、データをダウンロードするリクエストを送信し、それを処理してから次のリクエストを送信します。代わりに、リクエストを送信してデータを取得し、そのデータを処理している間に次のリクエストを送信することで、処理が終わった時にはデータが準備できている状態にすることができます。これは特にMachine Learningのワークロードで重要で、現在のバッチを処理している間に次のバッチをダウンロードすることで、GPUのアイドル時間を防ぎ、必要なときにGPUがデータを利用できるようにします。
パフォーマンスを向上させるもう1つの重要な方法は、キャッシングです。最も高速なリクエストは、そもそも送信する必要のないリクエストです。 多くの場合、データは、前日のデータを照会するような頻繁にアクセスされる小さな部分と、1年前のデータのようにめったにアクセスされない部分に分かれています。このパターンを活用して、頻繁にアクセスされるデータをローカルインスタンスストレージやAmazon S3 Express One Zoneにキャッシュすることで、パフォーマンスを向上させることができます。Mountpointはこのキャッシング機能を標準で提供しており、CloudFrontも頻繁にアクセスされるデータのキャッシングによりリクエストを高速化するオプションの1つです。
本日の3つの重要なポイントをご紹介します: パフォーマンスは重要であり、私たちはパフォーマンス向上への投資を継続していきます。ワークロードのパフォーマンス向上のために、いくつかの改善を導入しました。単一のリクエストのパフォーマンスだけでなく、ワークロード全体のパフォーマンスの最適化に注力すべきです。これは、測定を行い、新しいクライアントや説明したパフォーマンスレベルを活用することで実現できます。具体的には、並列化、ファイルサイズの最適化、適切なデータパーティショニング、プリフェッチ、そしてキャッシングを行って、ワークロードのパフォーマンスを最適化してください。
より詳しい情報については、ウェブサイトをご覧ください。ご視聴ありがとうございました。モバイルアプリでアンケートにご協力をお願いいたします。
※ こちらの記事は Amazon Bedrock を利用することで全て自動で作成しています。
※ 生成AI記事によるインターネット汚染の懸念を踏まえ、本記事ではセッション動画を情報量をほぼ変化させずに文字と画像に変換することで、できるだけオリジナルコンテンツそのものの価値を維持しつつ、多言語でのAccessibilityやGooglabilityを高められればと考えています。






























































Discussion