zuntan02のはてなブログ

備忘録的なものです。時々職場の技術者ブログにも転記してますが、メインはこちらで。

【AWS】Wordpress冗長化をALBとEFSだけでやってみたら遅すぎて無理だったけどCloudFrontとOPcacheでなんとかなったログ

【概要】

EFSが東京に来た時、Wordpress冗長化の決定打では!?とか思ってたんだけど、事例が全然出てこない。遅い…遅い…という怨嗟の声は聞こえたりするので実際にどれくらい遅いのかやってみたら画像が「ぱら・・・ぱら・・ぱ・・・(止まる」みたいな感じでホントに遅かった。CloudFrontで静的ファイルをキャッシュしてみたけど、WordpressだとまずPHPそのものの処理が重い。
対策として静的ファイルをCloudFrontで、phpはOPCacheでさばくことでEBS単体の時と遜色ない性能となった。

【参考】

https://hacknote.jp/archives/38521/
ランダムリードがEBS汎用SSDで18MB/sのところ、EFSは108 KB/sとのこと。なるほどそんな感じだった。

https://postd.cc/wordpress-on-aws-smooth-and-pain-free/
EFSとOPcacheとCloudFrontを利用した解決。これがおそらく現状の正答。

【OPcache有無での差異テスト】

1)全部EBS+CloudFrontで画像およびcss/jsをキャッシュ
2)EFSにWordpress全部入り+CloudFrontで画像およびcss/jsをキャッシュ
3)EFSにWordpress全部入り+CloudFrontで画像およびcss/jsをキャッシュ、にPHPをOPcacheでキャッシュを追加

種別 PageSpeed InsightsのTTFB(※)値
1)EBS+CF 0.18s
2)EFS+CF 7.46s
3)EFS+CF+OPcache 0.33s

※TTFB:Time To First Byte、最初の1バイトが到着するまでの時間

という訳で、WordpressをEFSに全部突っ込んで冗長化しても性能が……という向きにはOPcache+CloudFrontで。

構築メモ

【参考】
https://www.sodo-shed.com/archives/12629
→東京リージョンで使えるようになったAmazon EFSを使って手軽なWordPress冗長化

https://docs.aws.amazon.com/ja_jp/efs/latest/ug/mount-fs-auto-mount-onreboot.html
Amazon EFS ファイルシステムの自動マウント

https://hacknote.jp/archives/38406/
→キャッシュヒット率を上げつつ管理画面に影響を出さない

1) EFS用のSecurityGroupを作成する
[EC2]-[セキュリティグループ]-[セキュリティグループの作成]
→VPCからのアクセスのみすべて許可
2) EFSを作成する
[EFS]-[ファイルシステム]-[ファイルシステムの作成]
ステップ 1: ファイルシステムアクセスの設定
→VPCとマウントターゲットを指定

ステップ 2: オプション設定の構成
パフォーマンスモードの選択:汎用
スループットモードの選択:バースト★
暗号化の有効化:チェック無し

★注意★
BackWPupでデイリーバックアップしてたらEFSのバーストクレジットが枯渇してベースライン(50KB/秒)になって499多発を招いたので、環境作ってからしばらくはCloudWatchのBurstCreditBalanceを見守ることをお勧めします!以下のようにバランスしていない場合場合は諦めてプロビジョンドスループット(10MB/秒で$76)とかにしましょう。自戒を込めて……
f:id:zuntan02:20181229104437p:plain

3)マウント
# マウントポイント作成
mkdir /srv/hoge

# マウント実行
mount -t efs <EFSのファイルシステムID>:/ /srv/hoge

# 再起動後のマウント対応
vi /etc/fstab
# 以下を追記
------------------------------
<EFSのファイルシステムID>:/ /srv/hoge efs defaults,_netdev 0 0
------------------------------

上記のマウントポイントにWordpressを配置、インストールします(通常の作業なので省略)

4)OPCache導入と有効化(以下はnginxの例)
yum -y install php-opcache
systemctl restart php-fpm
systemctl restart nginx
5)CloudFrontで静的ファイル(画像/js/css)キャッシュ対応
[CloudFront]-[Behaviors]-[Create Behavior]

# 以下のパスパターンについてキャッシュを有効化
Path Pattern:*.jpg
Path Pattern:*.png
Path Pattern:*.css
Path Pattern:*.js

# Behavior設定
Origin:ELB
Viewer Protocol Policy:Redirect HTTP to HTTPS
Allowed HTTP Methods:[GET, HEAD]
Cache Based on Selected Request Headers:Whitelist

Whitelist Headers
=====
Authorization	# 管理画面にベーシック認証を入れる時などに必要です。
CloudFront-Forwarded-Proto	# Origin側へプロトコルを通知します。
Host	# Origin側へアクセス先ホスト名を通知します。
=====

Object Caching:Customize
	Minimum TTL:0
	Maximum TTL:31536000	デフォルト1年 ※要調整
	Default TTL:86400		デフォルト1日 ※要調整

Forward Cookies:Whitelist

Whitelist Cookies:(管理画面では画像キャッシュさせない)
	wordpress_logged_in*
	wp-settings*

Query String Forwarding and Caching:None(Improves Caching)

以下デフォルトのままで[Create]
6)CloudFrontで残りのファイルはキャッシュしない対応(Behaviorルールの下端)
[Behaviors]-[Create Behavior]

パスパターン:Defaultについてキャッシュを無効化(TTLを0にするパス、条件を追加)
Path Pattern:Default (*)

# Behavior設定
Origin:ELB
Viewer Protocol Policy:HTTP and HTTPS
Allowed HTTP Methods:[GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE]
Cache Based on Selected Request Headers:Whitelist

Whitelist Headers
=====
Authorization
CloudFront-Forwarded-Proto
Host
=====

Object Caching:Customize
	Minimum TTL:0
	Maximum TTL:0
	Default TTL:0

Forward Cookies:All
Query String Forwarding and Caching:Forward all, cache based on all

以下デフォルトのままで[Create]

f:id:zuntan02:20181211194820p:plain

※その他簡単な検証
丁度Wordpressの4→5化の時期だったので、この構成でWPを4→5に上げたが、特に問題なく終了した。