【2018年度版】弊社メディアのWordPress負荷軽減方法のご紹介
こんにちは。
株式会社divで開発マネージャーとエンジニア採用人事を担当している片岡(@mato_kata)といいます。
すっかり秋になりました。一日毎に寒くなってきて、温泉にでも浸かりたい気分になってきましたね。
さて、今回は弊社メディア「TECH::NOTE」で行った負荷軽減方法についてお話をします。具体的にはWordPressというCMS(コンテンツ管理システム)の負荷軽減方法となります。
なおWordPressの負荷軽減方法は調べるといろいろ出てきますが、以下のようなことに気づきました。
・非エンジニアがAWS上で動くWordPressの負荷軽減方法を調べても、AWSの特性を利用した解決策は出てこないこと。(そもそもAWSの話も出てこない)
・AWSの特性を理解しているエンジニアが調べても、AWSの特性を利用した負荷軽減方法がWordPressにも有効なのかがわからないこと。
そうした事情から、今回は自分たちがやったことをエンジニアブログにまとめました。
TECH::NOTEとは?
「TECH::NOTE」とは、弊社divが運営しているオウンドメディアです。テクノロジー学習やエンジニア転職に役立つ情報を発信しています。編集長の桜口アサミさん(@asami81)の元、月間約100万PVの規模にまで成長しました。
TECH::NOTEはTECH::CAMPと同様にAWSのEC2上にサーバを構築して自社で運用していますが、記事の管理や画面のためにWordPressを使っています。
今回の作業の背景
メディアが成長して認知度が上がったことで、良い記事が多くの人に読まれる時のアクセス数も月毎に増えていきました。
当初はインスタンスサイズを上げることで対応してきましたが、しばらくするとサイズを上げても障害を起こすようになってきました。
この時の構成は(おおよそ)以下の通りでした。データベースはRDS(RDS for MySQL)を利用し、WordPress本体はEC2上で動かしていました。(apache + PHPを利用)
やったこと
こうした問題を解決するために、以下を行いました。
1. ディスクをプロビジョンドIOPSに変更
2. キャッシュサーバの設置
なおWordPressサーバのapacheをnginxに変更したりソフトウェアを追加することも改善につながるのですが、別の懸念点が出るなど影響が小さくないため見送りました。
1. ディスクをプロビジョンドIOPSに変更
EC2を使う時に限った話となりますが、iowaitが発生していたのでディスク(EBS)を「プロビジョンドIOPS」に変更しました。
プロビジョンドIOPSとは、EC2の通常ディスク(SSDディスク)に対する高速化のためのオプション機能です。
これに気づいたきっかけは、MackerelによるTECH::NOTE用EC2のCPUリソースに関するグラフ(以下)を見た時です。
「あれ?障害対応したタイミングって、単純にCPU負荷が高い時じゃなくてiowaitが発生したタイミングと同じじゃない?」
その時のディスクのreads/writesを調べると、readsが頭打ちになっていました。
「このことから、iowaitが発生している原因はディスクの読み込みのようだ。DBは別インスタンスで関係ないから、WordPressの呼び出しが原因だろう。」
こうした仮説に基づいて、プロビジョンドIOPSを導入してディスクの速度を上げることにしました。以下の手順となります。
1. 負荷の低い状態であることを確認します。プロビジョンドIOPSへの変更はサーバを停止する必要はないですが、完了までに時間がかかります。
2. 対象となるEC2のルートデバイスをクリックするとモーダル画面が出てくるので、その中のEBS ID(下線部分)をクリックします。
3. 「アクション」→「ボリュームの変更」をクリックします。
4. 「ボリュームタイプ」を「プロビジョンドIOPS SSD」を選択します。(画像は5の手順のものを参照)
5. Iopsの値を設定します。サイズによって設定可能値は異なるので、適切な値を設定しましょう。またプロビジョンドIOPSは通常ディスクに比べてAWS費用が高くなるため、不必要に値を増やすとムダに費用が増えるので注意します。
6. 右下の「変更」をクリックして反映させます。反映にはしばらく時間がかかるので待ちましょう。
このようにしてプロビジョンドIOPSにしたら、readの頭打ちが消えて以前より安定しました。
しかしこの時は、約18000readというなかなか多いread数だったため、サーバがダウンしてしまいました(線が欠けているところがサーバがダウンしていた時)。
また頻度は減ったとはいえ不安定になることがあったため、次の対策を取ることにしました。
2. キャッシュサーバの設置
次に行ったのは、WordPressサーバ自体のアクセス量を減らすために、WordPressサーバの前面にキャッシュサーバを設置することです。
具体的には、nginxによるリバースproxyによるキャッシュサーバです。
nginxの設定ファイルに以下のような記載をして、キャッシュサーバをにします。なお環境によっては動かないのでご注意ください。(設定ファイルは /etc/nginx/conf.d/proxy.conf などとしておいてください)
proxy_cache_path /var/cache/nginx/static_file_cache levels=1:2 keys_zone=cache_static_file:128m inactive=7d max_size=480m;
proxy_temp_path /var/cache/nginx/temp;
proxy_ignore_headers Cache-Control;
large_client_header_buffers 4 124k;
upstream backend {
server 192.168.0.1;
}
server {
location / {
proxy_pass http://backend;
proxy_read_timeout 150;
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_hide_header Set-Cookie;
proxy_ignore_headers Set-Cookie;
set $do_not_cache 0;
if ( $request_method != GET ) {
set $do_not_cache 1;
}
if ( $http_cookie ~ ^.*(comment_author_|wordpress_logged_in|wp-postpass_).*$ ) {
set $do_not_cache 1;
}
proxy_no_cache $do_not_cache;
proxy_cache_bypass $do_not_cache;
proxy_cache cache_static_file;
proxy_cache_key $scheme$host$uri$args;
proxy_cache_valid 200 10m;
proxy_cache_valid any 1m;
}
}
こうしたキャッシュサーバをおいたことで、WordPressサーバからユーザに送信するデータ量(txBytes)が劇的に減りました。これは、WordPressサーバへの接続数が減っていることを示します。
上記はキャッシュサーバを本番環境に組み込んだ時のWordPressサーバのトラフィック量のグラフです。真ん中付近で、データ送信量が大幅に減っていることが分かりますね。
現在の状態
こうした対策を行い、最終的には以下のような構成にすることでサーバが落ちなくなりました。
しかしそれでもたまに負荷が高くなる時があるので、継続して改善をしていきます。
まとめ
今回の作業の結果、WordPressサーバの負荷を減らすために以下は有効であることがわかりました。
・プロビジョンドIOPSなディスク(EBS)を利用すること
・キャッシュサーバを設置すること
さらに、Mackerelを利用してサーバのトレンドが把握できていたことも重要でした。
負荷軽減策を行う場合、サーバの普段の稼働状態がわからないと大抵は適切な対応ができません。こうした情報がない状態でいきなり対応しようとしても、エンジニアは普通は何も出来ないのです。
しかし監視ツールでサーバのトレンドを継続的に情報取得していたので、今回の作業ではそうした情報がとても役立ちました。
本記事を作成するにあたって、TECH::NOTE編集長アサミさんに感謝いたします。(以下は編集長アサミさんと片岡の珍しい2ショット)
そして現在エンジニア採用中です。サービス内容や教育に興味を持たれた方は是非一度お話ししたいです。Wantedlyで募集しておりますので、応募をお待ちしております!