トラストバンクふるさとチョイス事業本部SREの香西(かさい)です。
先月末に「読むふるさとチョイス」というオウンドメディアをリリースしました!
本記事ではこのオウンドメディアをEC2+EFS+RDS+ElastiCacheでAutoScalingなWordPressシステムとして構築したので、このシステムをProduction Ready*1にしていくまでの道のりをご紹介したいと思います!
要件
まず要件ですが、今回開発を外部制作会社へ発注していたこともあり、以下のような制約がありました。
デプロイをWordPressのプラグインで行い、SFTP経由でのファイル更新するという要件があることで、Gitでソースを管理してCI/CDでデプロイ、ということが難しくなってしまい、プロジェクトから冗長構成でスケールできるようにしてほしいという要件も出てきました。
WordPressは基本的に冗長構成を考慮したアーキテクチャになっていないので冗長化するの大変なんですよね。。。
マスターサーバーを別にしてlsyncd
で同期するとか、共有が必要なディレクトリをNFS上に置いたり、画像データをS3に置いたりと色々なやり方はあるもののベストプラクティス的なものは存在せず、デプロイでも悩むことになることも多く、WordPressをスケーラブルでイケてるシステムにするために涙ぐましい努力をしているエンジニア諸氏の屍の上に我々は立っていると言っても過言ではないのです。(過言やろ)
今回はデプロイ部分については制約があり、あまり工夫が出来ないので、どのようにデプロイ要件を満たしつつスケーラブルなインフラにしていけるかを考えていこうと思います。
システム構成
デプロイ
EFS+TransferFamilyの組み合わせで前述のデプロイはWordPressプラグインで行う&SFTP経由でファイルの更新ができるという要件をクリアしていきたいと思います。
Amazon Elastic File System (EFS)はAWSが提供するフルマネージドなNFSストレージです。
WordPressのプラグインでのデプロイをする&SFTP経由でもファイルを更新したいという要件があるので、EFSを使ってどのサーバーからのアクセスして、プラグイン経由でのデプロイをしても問題ないようにします。
ちなみにEFSでスループットモードをバーストモードにしている場合、クレジットが尽きるぐらいのスループットがあると完全に死ぬことになるのでご注意ください。
そして、クレジット枯渇を回避するためにプロビジョニングモードにするととてもお高いのご注意ください・・・(ツライ
AWS Transfer FamilyはAWSが提供するSFTP、FTPS、FTP プロトコルを使用してS3やEFSとデータ転送できるようにするフルマネージドサービスです。
今回のSFTP経由でファイル更新の要件をこのTransferFamilyで実装していきます。
可用性&冗長性
次に、ALB+EC2+AutoScaling+RDSで冗長構成でスケールできるの要件をクリアしていきます。
また、RDS部分のスケールにはWordPressのプラグインであるHyperDBを利用します。
これでWordPressのプログラムファイル群をすべてEFS上に置いて、各EC2サーバーからNFSマウントする形にし、スケールしてどのサーバーにアクセスしても問題がないようになりました。
構成図
全体のシステム構成は図としてはこんな感じになります。
しかし、このままではとても遅くて使い物にならないので様々なキャッシュ機構を活用してスピードアップを図っていきます。
キャッシュ戦略
というわけで以下キャッシュ機構を導入していきます。
PHP (OPcache)
PHP処理の高速化を実現する代表的な方法の一つにバイトコード(オペコード)をキャッシュする、所謂PHPアクセラレータを利用する方法があり、 そのPHPアクセラレータ機能を提供するのがOPcacheです。
OPcacheの導入方法は環境毎に異なるので割愛しますが、以下のようにopcache.enable => On => On
となっていればOPcacheは有効になっています。
$ php -i | grep opcache Additional .ini files parsed => /etc/php.d/10-opcache.ini, opcache.blacklist_filename => /etc/php.d/opcache*.blacklist => /etc/php.d/opcache*.blacklist opcache.consistency_checks => 0 => 0 opcache.dups_fix => Off => Off opcache.enable => On => On opcache.enable_cli => On => On opcache.enable_file_override => Off => Off opcache.error_log => no value => no value opcache.file_cache => no value => no value opcache.file_cache_consistency_checks => On => On opcache.file_cache_only => Off => Off opcache.file_update_protection => 2 => 2 opcache.force_restart_timeout => 180 => 180 opcache.huge_code_pages => Off => Off opcache.interned_strings_buffer => 8 => 8 opcache.lockfile_path => /tmp => /tmp opcache.log_verbosity_level => 1 => 1 opcache.max_accelerated_files => 10000 => 10000 opcache.max_file_size => 0 => 0 opcache.max_wasted_percentage => 5 => 5 opcache.memory_consumption => 128 => 128 opcache.opt_debug_level => 0 => 0 opcache.optimization_level => 0x7FFEBFFF => 0x7FFEBFFF opcache.preferred_memory_model => no value => no value opcache.preload => no value => no value opcache.preload_user => no value => no value opcache.protect_memory => Off => Off opcache.restrict_api => no value => no value opcache.revalidate_freq => 2 => 2 opcache.revalidate_path => Off => Off opcache.save_comments => On => On opcache.use_cwd => On => On opcache.validate_permission => Off => Off opcache.validate_root => Off => Off opcache.validate_timestamps => On => On
細かいチューニングは環境毎に異なるため割愛しますが、一般的に推奨される設定について興味がある方は以下を参考にしてみてください。 まぁ、ほぼデフォルトで推奨設定になっていますがw
Redis(ElastiCache)
オブジェクトキャッシュとPHPセッションの保存先にRedisを利用するため、ElastiCacheでRedisを構築します。
オブジェクトキャッシュ
オブジェクトキャッシュには以下のWordPressプラグインを利用します。
このプラグインを利用することによりWordPressのオブジェクトキャッシュにより生成された値をキャッシュすることができ、同じオブジェクトに対して2回クエリを実行せずに、キャッシュされたオブジェクトを再利用できるので、DBの負荷を軽減し、ウェブサイトの応答時間を短縮させることができます。
設定としてはwp-config.php
に以下のようにエンドポイントを指定してあげるだけです。
define('WP_REDIS_HOST', '{Redisエンドポイント}'); define('WP_REDIS_MAXTTL', 3600);
PHPセッション
AutoScaling環境となるため、PHPセッションをRedisに保存&共有できるようにして可能性を高めたいのでphp-redis
を利用します。
インストール方法については各環境毎に異なるため割愛しますが、基本的な設定としてはphp.ini
に以下設定を入れるだけです。
session.save_handler = redis session.save_path = "tcp://{Redisエンドポイント}:6379"
CDN(Cloudflare)
最後に弊社ではCDNにCloudflareを利用しているのでCloudflareのチューニングをしていきます。
キャッシュレベルはスタンダードのまま、以下の機能を有効化しました。
機能 | 概要 |
---|---|
Mirage | 画像の読み込みを高速化 |
Polish | 画像のメタデータ除去&最適化によりダウンロード速度を改善させる |
Rocket Loader | Time to First Paint (TTFP)、Time to First Contentful Paint (TTFCP)、Time to First Meaningful Paint (TTFMP)、Document Loadのパフォーマンス向上 |
Auto Minify | HTML/CSS/JavaScriptのサイズ縮小による転送量削減 |
詳細な説明は公式に委ねますが、基本的には上記設定を有効化するチューニングのみを実施しました。
Lighthouseの結果
前述のキャッシュ関連の設定を実装した状態でのLighthouseの結果は以下のようになりました。
サーバーの台数を増やすことでスループットが伸びることも確認できたのでこれでProduction ReadyなWordPressシステムと言えるようになったのではないでしょうか!???
おわりに
今回EFSを使ったWordPressシステムを構築してみて、EFSはWordPressで冗長構成を取りたい場合には中々良い選択肢になり得るのかなと思いました。
以前は遅くて使いにくいイメージがありましたが、読み取りスループットが3倍になるアップデートもありCDNありきではありますが、Production ReadyなWordPressシステムのアーキテクチャの選択肢としては悪くないのではと現在は思っております。
そしてまた大きなアップデートがあったのでこれはもうEFSっきゃないっしょという状況ですね。
本記事がProduction ReadyなWordPressシステム構築に挑戦しているエンジニア諸氏の参考になってくれると嬉しいです。
そんな弊社トラストバンクでは様々な職種で絶賛採用中なので気になった方は是非お気軽にご連絡くださいー!