3
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

AWS CloudFrontの配信元のファイル(S3)が更新されたら自動的にキャッシュをクリアする仕組みを作る

Last updated at Posted at 2019-06-21

こまった事

こんな感じのアプリ構成で
image.png
CloudFront経由でS3に格納したコンテンツを配信する場合、
CloudFrontのCloudFrontエッジロケーション(キャッシュサーバー)からコンテンツをクライアントに配信する為、
クライアントに中々、最新のコンテンツが行き渡らない事象がしばしば発生します。

CloudFrontにキャッシュを残さないようにすれば?

設定次第でそれもできますが、
それだとCloudFrontの意味ないです。
それと毎回、配信元のS3にアクセスしに行く事になるのでS3のアクセス数が増加してしまいます。(お金がかかってしまう)

解決方法

CloudFrontの配信元のファイル(S3)が更新されたら自動的にCloudFrontのキャッシュをクリア(Invalidation)してあげる仕組みを作ります。

配信するファイルにもクライアントにキャッシュさせないようにメタ情報を付与します。
方法はこちらの記事を参考に
https://qiita.com/anchoor/items/2dc6ab8347c940ea4648

その仕組みどんな風に作るの?

配信元のファイル(S3)の更新をトリガーとして実行するLambdaFunctionを作成します。
そのLambdaFunction内でCloudFrontのキャッシュをクリア(Invalidation)してあげます。

このように作るのだ

image.png
S3のオブジェクトの更新をトリガーとして発火する
LambdaFunctionを作成します。

※詳細は、こちらの記事で記載しています。
AWS S3のオブジェクトの更新をトリガーとして発火する LambdaFunctionを作成する

LambdaFunctionの中身

今回はGoで書きました。
AWSのAPI(AWS SDK for Go)にCloudFrontののキャッシュをクリア(Invalidation)するAPIがあるので
そいつをキックしてあげるだけです。
https://docs.aws.amazon.com/sdk-for-go/api/service/cloudfront/#CloudFront.CreateInvalidation

※詳細は、こちらの記事で記載しています。
AWS S3バケット名からCloufFrontのキャッシュをクリア(CreateInvalidation)するAPIをコールする

実装に苦労した点

ロール周りや、パーミッションの問題で実際に動作させるまで時間がかかりました。
これはエラーメッセージが丁寧に出力されるので一つ一つ対応していけば問題ないのですが、

S3オブジェクトの更新トリガーについはそうもいきませんでした。
私はS3バケットの中全てのオブジェクトを更新チェック対象としている為、
オブジェクト更新したら更新した数のオブジェクトの数分、発火してしまいます。

つまり、対象のS3バケットの中身20個のファイルを格納、更新したら20回発火します。

苦労した点の対応

Goの実装内でAPI(CloudFront.CreateInvalidation)実行時に一意なIDを指定します。
そのIDには現在年月日時分秒を指定していましたが、
それを現在年月日時分を指定する事で1分に一回しかCreateInvalidationを実行しないようにしました。イベント発火の最初の1回のみ実行され、後の発火は全てIDが重複している為、エラーとなりますので1分に1回しか実行されません。

よって、S3バケットの中身20個のファイルを格納、更新したら20回発火しますが、1回だけ正常にCreateInvalidationを実行し、19回はエラーとなります。

所感

これでクライアントは常にCloudFrontエッジロケーション(キャッシュサーバー)を見に行き、見にいく先のCloudFrontエッジロケーション(キャッシュサーバー)は最新のコンテンツが行き渡っています。

CloudFront標準の機能で用意してくれててもいいような気がする機能でした。

この機能を実装した直後にこんな記事が...
「【朗報】Amazon CloudFrontのキャッシュ削除(Invalidation)が速くなりました【5秒で90%】」
https://dev.classmethod.jp/cloud/aws/cloudfront-fast-invalidation/

※構成図はこちらの記事を参考にして作成しました。
https://qiita.com/nave-m/items/68425f476b254a1a47b0

3
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?