Amazon S3 のパフォーマンスの設計パターン - Amazon Simple Storage Service

Amazon S3 のパフォーマンスの設計パターン

Amazon S3 に対してオブジェクトのアップロードや取得を行うアプリケーションを設計する場合は、アプリケーションの最適なパフォーマンスを実現するためにベストプラクティスの設計パターンを使用してください。また、アプリケーションのアーキテクチャの計画時に考慮すべきAmazon S3 のパフォーマンスのガイドライン も提供しています。

パフォーマンスを最適化するには、以下の設計パターンを使用します。

頻繁にアクセスされるコンテンツにキャッシュを使用する

Amazon S3 にデータを保存するアプリケーションの多くは、ユーザーから繰り返しリクエストされる「作業セット」と言えるデータを提供します。ワークロードで一連のよく使用されるオブジェクトに対して繰り返し GET リクエストを送信する場合は、Amazon CloudFrontAmazon ElastiCacheAWS Elemental MediaStore などのキャッシュを使用してパフォーマンスを最適化することができます。キャッシュ導入が成功すると、レイテンシーが低くなり、データ転送速度が速くなります。また、アプリケーションでキャッシュを使用すると Amazon S3 にリクエストを直接送信する回数も減るため、リクエストにかかる費用を削減できます。

Amazon CloudFront は、各地に点在する一連の大規模な POP (Point Of Presence) で Amazon S3 のデータを透過的にキャッシュする高速なコンテンツ配信ネットワーク (CDN) です。複数のリージョンまたはインターネットからオブジェクトにアクセスする場合に CloudFront を使用すると、オブジェクトにアクセスするユーザーの近くにデータをキャッシュできます。これにより、Amazon S3 のアクセス数の多いコンテンツの配信パフォーマンスを高めることができます。CloudFront の詳細については、Amazon CloudFront 開発者ガイドを参照してください。

Amazon ElastiCache は、マネージド型のインメモリキャッシュです。ElastiCache を使用すると、オブジェクトをメモリにキャッシュする Amazon EC2 インスタンスをプロビジョニングできます。このキャッシュにより、GET レイテンシーが数桁減少し、ダウンロードスループットが大幅に向上します。ElastiCache を使用するには、アプリケーションのロジックを変更して、アクセス数の多いオブジェクトをキャッシュに保存し、Amazon S3 にそのオブジェクトをリクエストする前にキャッシュを確認するようにします。ElastiCache を使用して Amazon S3 の GET のパフォーマンスを向上させる例については、ブログ記事の「Turbocharge Amazon S3 with Amazon ElastiCache for Redis」を参照してください。

AWS Elemental MediaStore は、Amazon S3 の動画ワークフローとメディア配信のために特別に作成されたキャッシュおよびコンテンツ配信システムです。MediaStore には、動画専用のエンドツーエンドのストレージ API が用意されており、パフォーマンスが重視される動画ワークロードに最適です。MediaStore の詳細については、「AWS Elemental MediaStore ユーザーガイド」を参照してください。

レイテンシーの影響を受けやすいアプリケーションのタイムアウトと再試行

アプリケーションが Amazon S3 から再試行が必要なことを示すレスポンスを受け取る場合があります。Amazon S3 は、バケット名とオブジェクト名を関連するオブジェクトデータにマッピングします。アプリケーションで発生するリクエスト率が高い場合 (通常、少数のオブジェクトに対して 1 秒あたり 5,000 リクエストを超える率が持続される)、アプリケーションは HTTP 503 slowdown レスポンスを受信することがあります。これらのエラーが発生した場合、各 AWS SDK はエクスポネンシャルバックオフを使用して自動再試行ロジックを実装します。AWS SDK を使用していない場合は、HTTP 503 エラーの受信時に再試行ロジックを実装する必要があります。バックオフテクニックの詳細については、「AWS SDK とツールのリファレンスガイド」の「Retry behavior」を参照してください。

Amazon S3 は、処理を継続するための新しいリクエストレートに応じて自動的にスケールし、パフォーマンスを動的に最適化します。Amazon S3 が新しいリクエスト率のために内部的に最適化している間、最適化が完了するまで一時的に HTTP 503 リクエストレスポンスが送信されます。Amazon S3 が新しいリクエストレートに応じてパフォーマンスを内部的に最適化すると、リクエストはすべて再試行なしで通常どおり処理されます。

レイテンシーが重要なアプリケーションの場合、Amazon S3 では遅いオペレーションを追跡して積極的に再試行することをお勧めします。リクエストを再試行する際は、Amazon S3 に新しく接続して改めて DNS ルックアップを実行することをお勧めします。

可変サイズの大きいリクエスト (例えば、128 MB 超) を実行する際、達成されるスループットを追跡し、リクエストのうち、遅い方から 5 パーセントを再試行することをお勧めします。小さいリクエスト (例えば、512 KB 未満) を実行する際、レイテンシーの中央値が数十ミリ秒の範囲内であることが多い場合、2 秒後に GET または PUT オペレーションを再試行することをお勧めします。追加の再試行が必要な場合のべストプラクティスはバックオフすることです。例えば、2 秒後に 1 回目の再試行を発行し、さらに 4 秒後に 2 回目の再試行を発行することをお勧めします。

アプリケーションが Amazon S3 に固定サイズのリクエストを実行する場合は、それぞれのリクエストの応答時間はより一定になると考えられます。この場合、シンブルな戦略はリクエストのうち、遅い方から 1 パーセントを特定してそれらを再試行することです。1 回の再試行でもレイテンシーの低減において効果的でありことが多いです。

サーバー側の暗号化で AWS Key Management Service (AWS KMS) を使用している場合、ユースケースでサポートされるリクエスト率については、「AWS Key Management Service デベロッパーガイド」の「Quotas」を参照してください。

高スループットのための水平スケーリングとリクエスト並列化

Amazon S3 は大規模な分散システムです。その規模を活用できるように、並列リクエストを Amazon S3 のサービスエンドポイントに水平にスケールすることをお勧めします。このようなスケーリングのアプローチは、Amazon S3 でのリクエストの分散だけでなく、ネットワークで複数のパスに負荷を分散するためにも役立ちます。

転送のスループットを高めるために、Amazon S3 では複数の接続によってデータの GET や PUT を並列で行うアプリケーションを使用することをお勧めします。このような並列化は、AWS Java SDK の Amazon S3 Transfer Manager でサポートされています。また、その他のほとんどの AWS SDK でも同様の機能が提供されています。一部のアプリケーションでは、さまざまなアプリケーションスレッドで、またはさまざまなアプリケーションインスタンスで複数のリクエストを同時に起動することで、並列接続を実現できます。採用する最良のアプローチは、アプリケーション、およびアクセスするオブジェクトの構造によって異なります。

AWS SDK を使用して、AWS SDK で転送の管理を使用するのではなく GET リクエストまたは PUT リクエストを直接発行できます。このアプローチにより、ワークロードをより直接的に調整できると同時に、発生する可能性がある HTTP 503 レスポンスの再試行とその処理に引き続き SDK のサポートを活用できます。一般的なルールとして、リージョン内の大きなオブジェクトを Amazon S3 から Amazon EC2 にダウンロードする場合は、8~16 MB の粒度でオブジェクトのバイト範囲の同時リクエストを実行することをお勧めします。同時リクエストは、必要なネットワークスループットの 85~90 MB/秒ごとに 1 つ実行します。10 Gb/s のネットワークインターフェイスカード (NIC) を使用するには、個別の接続で約 15 の同時リクエストを使用します。より多くの接続で同時リクエストをスケールアップして、25 Gb/s や 100 Gb/s の NIC などのより高速な NIC を使用できます。

パフォーマンスの測定は、同時に発行するリクエスト数を調整する場合に重要です。一度に 1 つのリクエストから始めることをお勧めします。達成されるネットワーク帯域幅とデータの処理でアプリケーションで使用されるその他のリソースの使用を測定します。その後、ボトルネックとなっているリソース (つまり、使用量が最も高いリソース) と有用である可能性が高いリクエスト数を特定できます。例えば、一度に 1 つのリクエストの処理で CPU 使用率が 25 パーセントの場合、これは最大 4 つの同時リクエストに対応できることを示しています。測定は不可欠であり、リクエスト率としてのリソース利用が向上していることを確認する価値があります。

アプリケーションで REST API を使用して Amazon S3 にリクエストを直接発行する場合は、HTTP 接続のプールを使用して、一連のリクエストで各接続を再利用することをお勧めします。リクエストごとの接続セットアップを回避すると、各リクエストで TCP スロースタートと Secure Sockets Layer (SSL) ハンドシェイクを実行する必要がなくなります。REST API の使用については、Amazon Simple Storage Service API Reference を参照してください。

最後に、DNS に注意するとともに、リクエストが Amazon S3 の広範な IP アドレスのプールに分散されていることを確認することもお勧めします。Amazon S3 の DNS の問い合わせは、多数の IP エンドポイントのリストを確認します。ただし、キャッシュリゾルバ、または 1 つの IP アドレスを再利用するアプリケーションコードでは、アドレス多様性とそれによる負荷分散のメリットが得られません。コマンドラインツールの netstat などのネットワークユーティリティツールを使用すると、Amazon S3 との通信に使用されている IP アドレスを確認できます。また、使用する DNS 設定のガイドラインも提供しています。これらのガイドラインの詳細については、「Amazon S3 API リファレンス」の「Making requests」を参照してください。

Amazon S3 Transfer Acceleration を使用して長距離間のデータ転送を高速化する

Amazon S3 Transfer Acceleration を使用した高速かつ安全なファイル転送の設定 は、世界中のクライアントと Amazon S3 を使用する特定のリージョンのアプリケーションの距離によるレイテンシーを最小限に抑える、またはなくすために有効です。Transfer Acceleration は、データの転送に CloudFront の世界中に点在するエッジロケーションを利用します。AWS エッジネットワークでは、50 を超えるロケーションに接続ポイントがあります。現在、このネットワークは、CloudFront でのコンテンツの配信や Amazon Route 53 に対する DNS の問い合わせへの迅速な応答のために使用されています。

このエッジネットワークは、Amazon S3 との間のデータ転送の高速化にも役立ちます。これは、大陸全域または大陸間でデータを転送する、高速なインターネット接続がある、大きなオブジェクトを使用する、またはアップロードするコンテンツが多数あるアプリケーションに最適です。エッジロケーションに到着したデータは、最適化されたネットワークパスで Amazon S3 にルーティングされます。一般的に、Amazon S3 のリージョンから遠いほど、Transfer Acceleration による速度の向上が期待できます。

新しいバケットまたは既存のバケットで Transfer Acceleration をセットアップできます。離れた Amazon S3 Transfer Acceleration エンドポイントを使用して、AWS のエッジロケーションを使用することができます。Transfer Acceleration がクライアントのリクエストのパフォーマンスに役立つかどうかをテストする最も良い方法は、Amazon S3 Transfer Acceleration の速度比較ツールを使用することです。ネットワークの設定および条件は、随時、場所によって異なります。そのため、Amazon S3 Transfer Acceleration がアップロードのパフォーマンスを向上させることができると考えられる転送に対してのみ料金が発生します。さまざまな AWS SDK での Transfer Acceleration の使用については、「S3 Transfer Acceleration の有効化と使用」を参照してください。