CloudFront がオブジェクトの部分的リクエスト (レンジ GET) を処理する方法
大きなオブジェクトの場合、ビューワー (ウェブブラウザまたはその他のクライアント) は、複数のGET
リクエストを実行し、Range
リクエストヘッダーを使用して、小さいパートでオブジェクトをダウンロードできます。Range GET
リクエストとも呼ばれるこのバイト範囲のリクエストでは、部分的なダウンロードの効率、および部分的に失敗した転送からの回復の効率が向上します。
CloudFront は Range GET
リクエストを受け取ると、そのリクエストを受け取ったエッジロケーションのキャッシュをチェックします。そのエッジロケーションのキャッシュに、オブジェクト全体またはオブジェクトの要求されたパートがすでに含まれている場合、CloudFront は要求された範囲をキャッシュから直ちに提供します。
要求された範囲がキャッシュに含まれていない場合、CloudFront はリクエストをオリジンに転送します。(パフォーマンスを最適化するために、CloudFront は、Range GET
でクライアントから要求された範囲よりも大きい範囲を要求する場合があります)。次に実行される処理は、オリジンが Range GET
リクエストをサポートするかどうかによって異なります。
-
オリジンが
Range GET
リクエストをサポートする場合: 要求した範囲が返されます。CloudFront は要求された範囲を提供し、今後のリクエストのためにその範囲をキャッシュします。(Amazon S3 も多くの HTTP サーバーもRange GET
リクエストをサポートしています)。 -
オリジンが
Range GET
リクエストをサポートしない場合: オブジェクト全体が返されます。CloudFront は、オブジェクト全体を送信して現在のリクエストを処理し、今後のリクエストのためにオブジェクトをキャッシュします。CloudFront はオブジェクト全体をエッジキャッシュにキャッシュした後、要求された範囲を提供することで新しいRange GET
リクエストに応答します。
どちらの場合も、CloudFront は、オリジンから 1 バイト目が到着した直後に、要求された範囲またはオブジェクトをエンドユーザーに供給します。
注記
ビューワーが Range GET
をリクエストし、オリジンが Transfer-Encoding: chunked
を返す場合、CloudFront はリクエストされた範囲ではなくオブジェクト全体をビューワーに返します。
通常、CloudFront は、Range
ヘッダーの RFC 仕様に準拠します。ただし、Range
ヘッダーが以下の要件に準拠しない場合、CloudFront は、指定された範囲とステータスコード 200
を返す代わりに、完全なオブジェクトと HTTP ステータスコード 206
を返します。
-
範囲は昇順に指定されている必要があります。たとえば、
100-200,300-400
は有効で、300-400,100-200
は無効です。 -
範囲は重複できません。たとえば、
100-200,150-250
は無効です。 -
すべての範囲指定が有効である必要があります。たとえば、範囲の一部に負の値を指定することはできません。
Range
リクエストヘッダーの詳細については、RFC 7233 の「範囲リクエスト
範囲リクエストを使用して大きなオブジェクトをキャッシュする
キャッシュが有効になっている場合、CloudFront では 50 GB を超えるオブジェクトは取得またはキャッシュされません。オリジンによって、オブジェクトがこのサイズを超えていることが示される場合 (Content-Length
レスポンスヘッダーで)、CloudFront はオリジンへの接続を閉じて、ビューワーにエラーを返します。(キャッシュを無効にすることで、CloudFront はオリジンからこのサイズを超えるオブジェクトを取得し、それをビューワーに転送できます。ただし、CloudFront でオブジェクトはキャッシュされません)。
ただし、範囲リクエストで CloudFront を使用してキャッシュ可能な最大ファイルサイズを超えるサイズのオブジェクトをキャッシュできます。
例
-
100 GB のオブジェクトを持つオリジンについて考えてみます。キャッシュが有効になっている場合、CloudFront では、オブジェクトはこの大きさで取得またはキャッシュされません。ただし、ビューワーは複数の範囲リクエストを送信することにより、それぞれサイズが 50 GB 未満のパートを使用して、このパートのオブジェクトを取得できます。
-
ビューワーは、オブジェクトを 20 GB のパートに分けてリクエストする場合、ヘッダー
Range: bytes=0-21474836480
を使用したリクエストを送信して最初のパートを取得し、次にヘッダーRange: bytes=21474836481-42949672960
を使用した別のリクエストで次のパートを取得できます。以下同様です。 -
ビューワーがすべてのパートを受信すると、それらを組み合わせて元の 100 GB のオブジェクトを構築できます。
-
この場合、CloudFront はそれぞれ 20 GB のパートのオブジェクトをキャッシュし、キャッシュの同じパートの後続リクエストに対応できます。