S3にアセットを置いてCloudFrontのディストリビューションから配信する。というのは、 クラウドデザインパターンのひとつでもあり、有用な戦略である。 CloudFrontはCDNで、エッジサーバにアセットをキャッシュしてくれるから速い。というのは基本的に正しいんだけど、 たまに(大体特定のファイルだけ)遅い。ということがある。

原因

特に、特定のファイルだけ遅い。というケースでは、ファイルがハードディスクに保存され、かつうまくセクタに載ってくれてないことが多い。

つまり、

  • Bad Sectorに載ってしまっている
  • フラグメントされてしまっている

ということが考えられる。 なお、ここでいうハードディスクとは、S3側、CloudFrontのエッジ側両方の話である。

BadSectorは、日本語でもバッドセクタというっぽいけど、 ハードウェア起因でwrite/readができなくなってしまったセクタのことを言う。(たぶん)

また、フラグメントとは、ファイルの断片化を言う。 同じファイルが連続したセクタに乗らず、離れたセクタに分散してしまっていることを言う。 離れたセクタに乗ること自体はよくあることで、昔のWindowsだと デフラグ で断片化を直したりしていたはず。

切り分け方

原因がS3にあるのか、CloudFrontにあるのかを調べるのは大切。 やり方としては、CloudFrontを外してみて、S3のエンドポイントから取得した時のレイテンシを計測すればいい。 速度が変わらなければS3が原因だし、早くなったらエッジ側に原因がある。

(ただし、理論上は両方が原因ということもある。)

直し方

直し方はいくつかある。

ファイル名を変更してみる

ファイル名を変更すると、別ファイルとみなされ、セクタが変わるので、運が良ければうまくいく。 ただ、これをやるとその結果別のファイルが遅くなったりすることがある。

CloudFrontをやめる

高速化できればいいなら、Akamai、FastlyなどのフルSSDなCDNを使うという手もある。 ただし、理論上はSSDでもバッドセクタは発生する(正確にはバッドブロック)ので、注意。