WordPressをCloudFront上で動かす

課題~EFSで冗長化したWordPressサイトが遅い~

先日、NLB+EFS+MySQLレプリケーション+HaproxyでWordPressを冗長化したのだが、EFSの部分がボトルネックとなりすごく遅い。
なのでCloudFront+OPCacheで速くします。
今回はCloudFrontの設定をしていきます。
OPcacheはこちら

設定~WordPressサイトのCloudFront設定~

まずはGeneralから。

General項目設定解説
Price ClassUse U.S., Canada, Europe, Asia, Middle East and Africaリージョンを限定して価格を抑えることもできるようだ。3つあり、真ん中のランクのものは日本を含むほとんどの地域が該当する。最も高価な地域は除外される、とのことだがこれでよいだろう。
AWS WAF Web ACLNoneアクセス元の国やIPアドレスでリクエスト許可や拒否ができる。ウザいアクセスが来るようになったら導入を検討しよう。
Alternate Domain Names(CNAMEs)diary.hdora.tokyo代替ドメイン(独自ドメイン)を使える。証明書も指定しないといけない。
SSL CertificateCustom SSL Certificate (example.com):代替ドメイン使うのであれば指定必須。
Custom SSL Client SupportClients that Support Server Name Indication (SNI) - (Recommended)SNIを使用したHTTPSリクエスト処理のままにしておく。専用 IP アドレスを使用した HTTPS リクエストの処理、だとかなりお金がかかってしまう。
Security PolicyTLSv1.2_2018 (recommended)CloudFrontがビューアとの通信に使用するSSL / TLSプロトコルと、CloudFrontがビューアに返すコンテンツを暗号化するために使用する暗号の2つの設定する。TLSv1.2 をサポートしないブラウザやデバイスをビューワーが使用している場合を除き、TLSv1.2_2018 を指定することをお勧めとのことなのでTLSv1.2。
Supported HTTP VersionsHTTP/2, HTTP/1.1, HTTP/1.0HTTP/2にも対応してきたようなのでこれを選択。関係ないがそのうちサイトをHTTP/2化してみたい。
Default Root Object[ ]デフォルトルートオブジェクトを指定できる。が、apache側でindex.phpをドキュメントルートとしているのでやる必要なさそう。
Logging OffOffログはまた後で設定する。
Enable IPv6[ ]IPv6を有効にするとAAAAレコードを追加しないといけないとかいけなくないとか。IPv6を有効にするかは後日決めよう。
Comment[ ]使っていないが日本語かけるのかな。
Distribution StateEnabledDistributionを有効にしたい場合ははEnableにする。

続いてOrigins。

Origins項目設定解説
Origin Domain Name********.elb.ap-northeast-1.amazonaws.comデータ元。S3やロードバランサー、サーバなど。今回はNLBのDNS名を指定。
Origin Path[ ]オプション。オリジン全体をキャッシュさせたいので何も書く必要はない。
Origin IDCustom-origindiary.hdora.tokyoシステムが自動で決める。こっちは何もしない、というかできない。
Minimum Origin SSL ProtocolTLSv1.2CloudFrontとオリジン間のやり取りで使用する最小の?SSLプロトコル。サーバで対応する最新がよいとのことなので、TLSv1.2にした。
Origin Protocol PolicyHTTPS OnlyCloudFrontとカスタムオリジンと通信はHTTPSのみ!セキュア!
Origin Connection Attempts3この設定を [オリジン接続タイムアウト] とともに使用すると、セカンダリオリジンに接続しようとしたり、ビューワーにエラーレスポンスを返したりするまでに CloudFront が待機する時間の長さを指定できる。
Origin Connection Timeout10この設定を [オリジン接続試行回数] とともに使用すると、セカンダリオリジンに接続しようとしたり、ビューワーにエラーレスポンスを返したりするまでに CloudFront が待機する時間の長さを指定できる。
Origin Response Timeout30CloudFrontがリクエストをオリジンに転送してからレスポンス受け取るまでの時間。あるいはCloudFrontがオリジンからレスポンスパケットを受け取って次のパケットを受け取るまでの時間。つまりオリジンの応答が遅い場合に504エラー出すまでの時間。この値は低い値を維持したほうがいいらしい。
Origin Keep-alive Timeout5CloudFrontがレスポンス最後のパケットを取得した後にカスタムオリジンへの接続を維持する時間。接続を維持するとTCP接続やら後続リクエストに対するTLSハンドシェイクの時間を短くできる。(デフォルトの)5でいいのか悩み中。
HTTPS Port443443使ってるからそのまま。
Origin Custom Headers[ ]オリジンに送信されるリクエストにカスタムヘッダーを追加できる。現在必要ないが、そのうちいじってみたい。

最後にBehavior。

Behavior項目設定解説
Path PatternDefault (*)このキャッシュ動作をどのリクエストに割り当てるか指定。デフォルトは最初からあり消せない。
Origin or Origin GroupCustom-origindiary.hdora.tokyoリクエストをルーティングさせる宛先となるオリジン、またはオリジングループ。今回はオリジンひとつしかないので選択する余地がない。
Viewer Protocol PolicyRedirect HTTP to HTTPS閲覧者がコンテンツにアクセスするときのプロトコル。常時SSLにしたいので「HTTPをHTTPSにリダイレクト」を選択
Allowed HTTP MethodsGET, HEAD, OPTIONS, PUT, POST, PATCH, DELETECloudFrontがオリジンに転送するhttpメソッド。今回はCludFront経由でサイト更新もするのでこれを選択。
Field-level Encryption Config[ ]POST リクエストの特定データフィールドを特定のアプリケーションのみアクセスできるように保護する。
Cached HTTP MethodsGET, HEAD (Cached by default) [ ] OPTIONSGET, HEAD はキャッシュする。OPTIONSメソッドを含めるかどうか。※OPTIONSメソッドがよくわかっていない。
Cache Based on Selected Request HeadersWhitelistデフォルトではヘッダーは考慮されない。allにするとキャッシュされない。
Whitelist HeadersAuthorization, Host指定されたヘッダーすべての値に基づいてオブジェクトをキャッシュする。指定したヘッダーの値が異なる場合、別々にキャッシュされます。
Object CachingCustomizeオリジンがCache-Controlヘッダーを追加してキャッシュにとどまる時間を制御する「Use Origin Cache Headers」と、Cache-Controlヘッダーに関係なくキャッシュにとどまる時間を指定する「Customize」がある。
Minimum TTL3600オブジェクトが更新されたかどうか調べるためにCloudFrontがオリジンに別リクエストを送るまでCloudFrontキャッシュに保持する最小期間
Maximum TTL3600オブジェクトが更新されたかどうかをCloudFrontがオリジンにクエリするまでにオブジェクトをCloudFrontキャッシュに保持する最大期間
Default TTL3600オブジェクトが更新されたかどうかを調べるために CloudFront がオリジンに別のリクエストを送るまでオブジェクトを CloudFront キャッシュに保持するデフォルト期間
Forward CookiesNone(improves Caching)cookie値に基づいてオブジェクトの別バージョンを保存するかどうか。cookie値を考慮する必要はないのでNone。
Query String Forwarding and CachingFirward all, cache based on allクエリ文字列パラメータをオリジンに転送するかどうか。今回は静的サイトではないのでクエリ別にキャッシュしてくれないとトップページしか見れなくなってしまう。
Smooth StreamingNo調査中orz
Restrict Viewer Access (Use Signed URLs or Signed Cookies)No調査中orz
Compress Objects AutomaticallyNo調査中orz
Lambda Function Associations[ ]調査中orz

BehaviorはDefault (*)以外に2つ追加で作成します。
Path Pattern は「*.php」と「/wp-admin/*」です。
「/wp-admin/*」「*.php」のDefault(*)との変更点
Cache Based on Selected Request Headersをallにする
Forward Cookiesをallにする
※Cache Based on Selected Request Headersをallにするとキャッシュをしなくなり、TTLも設定不可能になる。

補足

Default (*)のwhitelistでAuthorization, Hostを設定しておかないと、ベーシック認証がうまくいかなくなりhttpsが設定できなくなる。
Default (*)のAllowed HTTP MethodsはGETとHEADだけでも画像アップなどもできたが、一応POST等も許可しておいた。後で再考するかも。*.phpもGET,HEADだけではダメ、「公開」ができなくなる。
また、Default (*)のForward CookiesをNoneにしてしまうとプレビュー機能が使えなくなるが、キャッシュを優先させる為には仕方ない。
Minimum TTL、Maximum TTL、Default TTLの関係はややこしいので下記サイトを参考にさせていただいた。
https://dev.classmethod.jp/articles/introduction-to-max-ttl-on-cloudfront/
参考サイトの、オリジンにCache-Control max-ageがない場合かつMinimum TTL > 0の場合 が本サーバには当てはまる。
このサイトでは特にヘッダーでキャッシュ期間をいじろうという意図は全くない。
やりたいことは/wp-admin以下と.phpと付くファイルのキャッシュを無しにし管理画面・動的コンテンツはキャッシュさせないこと、それ以外はキャッシュさせる、というシンプルなものだ。
コンテンツも頻繁に更新しないのでttlは全て3600(1時間)とした。
これによりユーザがエッジサーバからデータをとってこれる確率を高め、オリジンも負荷があまりかからなくなるだろう。
何より速度が改善されるはず。

DNS設定

これであとはdiary.hdora.tokyoのAレコード(orCNAME)をCloudFrontのDomain Nameにするだけ。
そうすればCloudFront経由で閲覧できるようになる。
OriginもNLB経由でMaster、Slaveサーバからデータをとってこれるので冗長化される。

前の記事

レプリケーション監視

次の記事

OPcacheを導入する