パフォーマンス系モジュールを導入して Drupal を100倍高速化する

CMSにはWordPress、MovableType、concrete5など比較的ライトに扱えるのでデザイナや編集者向けの側面がありますが、Drupalはそれよりも汎用性に優れるために大規模サイト構築に利用されるプログラマ向けのCMSと言えます。

そんなDrupalですが汎用性が追求される反面、とにかく多機能で巨大で重たくなるというジレンマもあります。

Drupalのジレンマを払拭するために、パフォーマンス向上させるモジュール群をピックアップしました。
実装を工夫するだけでは限界があるので、ぜひ積極的にこれらのモジュールを導入しましょう。

なお、対象をDrupalモジュールに限定しているために、OPCache、nginxなどのミドルウェアは一覧から割愛していますが、Drupalとアプリレベルで連携可能なものは含めています。
Drupal7（一部Drupal8対応） + PHP5.6　or　PHP7.xの環境を前提としています。

#ユーザーキャッシュ（KVS）、Drupalキャッシュ系

##<a href="https://www.drupal.org/project/memcache">Memcache API and Integration（memcache）</a>
memcachedのユーザーキャッシュ（KVS）を利用することができ、モジュールを有効化しただけでオブジェクトのキャッシュが行われ、キャッシュのヒット率を表示できるので視覚的に効果を確認できる。

![Memcache.png](https://qiita-image-store.s3.amazonaws.com/0/39468/ca206c19-2327-1d68-e246-6c69b07102ec.png)


APCモジュールのユーザーキャッシュ（KVS）の方が高速と言われているが、このMemcacheモジュールには大きなアドバンテージがある。
それは Memcache API を利用してカスタムでキャッシュロジックを実装することができるので、実装次第ではあらゆるエンティティをキャッシュ化することが可能になる。

もうひとつの使い処としては、大きなキャッシュデータを扱いたいときに memcached をウェブサーバとは別のマシンに分散させることでメモリを負荷軽減したいときも効果的だ。

インストール数 31,510
ダウンロード数 733,824
オススメ度 ★★★★☆


##<a href="https://www.drupal.org/project/memcache_storage">Memcache Storage（memcache_storage）</a>

Drupal標準キャッシュはデータベースで管理されているためにキャッシュを有効化しているにも関わらず大幅な速度向上が見込めないが、memcache_storageを有効化しておくだけで全てのキャッシュ格納先を Memcached へ移すことができる。
そのためデータベース性能がボトルネックになっている場合は高速化が期待できる。

インストール数 2,557
ダウンロード数 23,473
オススメ度 ★★★☆☆


##<a href="https://www.drupal.org/project/authcache">Authenticated User Page Caching（authcache）</a>
匿名ユーザー向けページ（静的ページ）と、認証ユーザー向けページ（動的ページ）の両方をキャッシュできる。

![Authcache.png](https://qiita-image-store.s3.amazonaws.com/0/39468/f54c3521-e6df-97da-b3a9-79bf62521213.png)


ただし、有効化しただけでは管理画面の高速化などがされる訳ではなく、各動的ページごとに設定する必要がある。
ただし、すべての動的ページが対象なわけではなく、以下のエンティティが連携可能。

■authcacheと連携可能なエンティティ・モジュール群
block, panels, comment, field, forum, menu, node, page manager, poll, views, varnish storage, voting

例えば、Panelsペインのキャッシュ設定は、デフォルトだと「No caching」「Simple cache」の2つのキャッシュタイプが用意されており、「Simple cache」を選択するとキャッシュ期間、キャッシュ精度（パラメータごと、コンテキストごと）が指定可能になる。

![authcache02.png](https://qiita-image-store.s3.amazonaws.com/0/39468/a09663f3-7d27-731b-df9f-29da18cc0014.png)

authcacheが有効化されているとPanelsペインのキャッシュ設定からキャッシュタイプ「Authcache」が選択可能になり、キャッシュ精度として、キャッシュ期間、ユーザーごと、URLごとを指定可能になり、これらの組み合わせにより動的ページもキャッシュ化できるという理屈だ。 

合わせてVarnishキャッシュ「ESI」に対応するかどうかの選択も可能になる。
Varnishキャッシュ「ESI」を選択していると、そのPanelsペインは Varnishのキャッシュ対象になる。
つまり、Panelsで設計した動的ページがVarnishのキャッシュに載せられることになる。

![authcache03.png](https://qiita-image-store.s3.amazonaws.com/0/39468/f54e0276-8866-9408-3ac7-0a69a6461c6d.png)


注意点としては、設定を誤ってしまうと、例えばマイページ上に他人の情報が表示されてしまったりなど、よくありがちな？キャッシュ制御不備による情報漏洩が起こりかねないので、そのシステムの仕様を詳しく理解している人が設定する必要がある。

インストール数 3,080
ダウンロード数 59,483
オススメ度 ★★★★★

##<a href="https://www.drupal.org/project/expire">Cache Expiration（expire）</a>
Varnishなどのプロキシキャッシュや、Drupal内部キャッシュなどのあらゆるキャッシュの有効期限が切れたときに発動するフックを提供する。
また、ユーザーが特定の操作をしたときに自動的にキャッシュクリアを動作させるための設定も可能。

![CacheExpiration02.png](https://qiita-image-store.s3.amazonaws.com/0/39468/b5b1328e-a5cd-f439-ad13-28c08b6425be.png)


これによって、意図せずにキャッシュが残り続ける危険を回避することができる。

インストール数 26,940
ダウンロード数 148,591
オススメ度 ★★★★★

##<a href="https://www.drupal.org/project/filecache">File Cache（filecache）</a>
APCやMemcachedなどと違ってサーバセットアップ不要な汎用性に優れたキャッシュシステム。

ただし、キャッシュデータはファイル管理されるために低速。

インストール数 2,406
ダウンロード数 15,417
オススメ度 ★★☆☆☆

##<a href="https://www.drupal.org/project/apc">APC（apc）</a>
Drupal標準キャッシュのバックエンドとしてAPC／APCuのユーザーキャッシュ（KVS）の機能を利用する。
APCモジュール有効化のためには、PHP拡張のAPCまたはAPCuをインストールしておく必要がある。

現在、APCのサポートはPHP5.5まで、APCuは 〜PHP5.5、PHP7.0〜 になっている。（PHP7.0以降の場合はAPCu bata版が対応している）

なのでPHP5.6環境下でユーザーキャッシュ（KVS）を利用したければ memcache を利用することになる。
（ちなみにPHP5.5まで利用できていたAPCのオペコードキャッシュはPHP5.6以降では非対応なのでOPCacheを導入すること）

インストール数 5,071
ダウンロード数 77,835
オススメ度 ★★☆☆☆

##<a href="https://www.drupal.org/project/redis">Redis（redis）</a>
レプリケーション対応のキャッシュシステム「Redis」と連携ができる。
Memcache同様にメモリ上でユーザーキャッシュ（KVS）を管理するため高速であり、ウェブサーバが複数台の場合はAPCuやmemcached（※）より効率がよいと言われている。
※ただしrepcachedをインストールすればmemcachedをレプリケーション化できる。

インストール数 4,964
ダウンロード数 65,910
オススメ度 ★★★☆☆

##<a href="https://www.drupal.org/project/boost">Boost（boost）</a>
共用サーバでDrupalを稼働させている場合、特別なミドルウエアをセットアップすることなく匿名ユーザー向けページ（静的ページ）をキャッシュして高速化させることができるベストな選択肢となる。

使い方は、Drupal標準のキャッシュを無効化しつつ、その代わりにBoostモジュールを有効化すればOK。

![Boost.png](https://qiita-image-store.s3.amazonaws.com/0/39468/8bfbfeb5-4798-ecac-211c-6d0265aa076d.png)


Authcacheと併用すれば認証ユーザー向けの動的ページもキャッシュできる。
（最新版Authcacheとの併用時に正常動作できないとの報告あり）

ほかにも以下モジュールと組み合わせればキャッシュがより効果的に行われる。
 * <a href="https://www.drupal.org/project/boost">Boost Crawler（boost_crawler）</a> ※Boost同梱のサブモジュール
 * <a href="https://www.drupal.org/project/expire">Cache Expiration（expire）</a>
 * <a href="https://www.drupal.org/project/fast_404">Fast 404（fast_404）</a>
 * <a href="https://www.drupal.org/project/globalredirect">Global Redirect（globalredirect）</a>
 * <a href="https://www.drupal.org/project/httprl">HTTP Parallel Request & Threading Library（httprl）</a>

ただ、専用サーバを利用していてプログラムのインストールなどが許される状況で、かつメモリ搭載量に余裕があるならば、よりハイパフォーマンスな Varnish の導入が推奨される。

インストール数 33,448
ダウンロード数 252,085
オススメ度 ★★★★☆


#Javascript・CSS圧縮系

##<a href="https://www.drupal.org/project/advagg">Advanced CSS/JS Aggregation（advagg）</a>
テーマ高速化のための高機能なCSS/JSファイルのキャッシュモジュール。
Drupal標準のCSS/JSファイルのキャッシュと比較して圧縮（スペースと改行除去）とファイル集約（Aggregation）やgzip圧縮の有無など、高度な設定が可能。
Drupalキャッシュとnginxのgzip圧縮との組み合わせでファイルエンコーディングが壊れてCSSが崩れるという報告があるので、それを防止する意味でも当モジュールであらかじめgzip圧縮をしておくと安心だ。

さらにDNSプロフェッチを利用してCSS/JSファイルの読み込み時間を短縮化してくれる。

インストール数 22,348
ダウンロード数 309,910
オススメ度 ★★★★★

#CDN・プロキシ系

##<a href="https://www.drupal.org/project/varnish">Varnish HTTP Accelerator Integration（varnish）</a>
高速リバースプロキシシステム「Varnish」との連携モジュール。 このモジュール単体では匿名ユーザー向けページ（静的ページ）のみがVarnishキャッシュ「ESI」へ対応する。

![Varnish.png](https://qiita-image-store.s3.amazonaws.com/0/39468/aacda8f7-39f4-f38e-4a64-3babbde2e571.png)

Authcacheモジュールとの併用により、認証ユーザー向けページ（動的ページ）もVarnishキャッシュ「ESI」ができるようになるため、Authcacheモジュールとセットで有効化されることが多い。

インストール数 17,903
ダウンロード数 332,426
オススメ度 ★★★★★

##<a href="https://www.drupal.org/project/fastly">Fastly（fastly）</a>
Varnish利用を前提としたCDNサービス「Fastly」と連携を可能にするモジュール。

Fastlyモジュールによって、超高速リアルタイムパージ（※）の恩恵に加えて、キャッシュロジックのカスタマイズが可能であり、動的コンテンツもCDNキャッシュに載せることができる。
※150ms内にキャッシュされたコンテンツを削除する機能

そのため、CDNサービスにありがちなサイトの更新情報がなかなか反映されないなどのトラブルが起こりにくい。

Drupal8リリースパーティでも紹介されたそうで、Drupal連携としてはまだ実績（※）は少ないが、とても期待されていると言える。
※Twitter社やGitHub社が採用しており世間での大規模システムでの実績は十分にある。

FastlyはDrupal高速化の施策の中ではとても期待できるが、このリストの中では唯一有料のために導入への敷居が高く、期待を込めてオススメ度を星5つにしたかったが、ひとまず星4つとした。

インストール数 194
ダウンロード数 2,800
オススメ度 ★★★★☆

##<a href="https://www.drupal.org/project/purge">Purge（purge）</a>
AkamaiやCloudFlareなどのCDNを利用している場合に、明示的にCDN側へキャッシュ更新を伝えてくれる。これにより長時間に渡って古いCDNキャッシュが残ることを防ぐことができる。
同様の機能をもつモジュールに<a href="https://www.drupal.org/project/akamai">Akama（akamai）</a>、<a href="https://www.drupal.org/project/cloudflare">CloudFlare（cloudflare）</a>、<a href="https://www.drupal.org/project/acquia_purge">Acquia Purge（acquia_purge）</a>などが存在する。

インストール数 2,455
ダウンロード数 32,133
オススメ度 ★★★☆☆


#まとめ
以上、Drupalのパフォーマンス向上のためにキャッシュモジュール周りを色々と調べてみました。

専用サーバでプログラム構成を自由に触れる環境ならば、「fastly」+「varnish」 + 「authcache」+「advagg」+「memcache」+「expire」の組み合わせが最もパフォーマンスが出せる組み合わせかと思います。

カスタムページを設置するときには、menuフックでパス定義する形でモジュール上で実装するものいいですが、Panelsで設計しておけばキャッシュモジュール群の恩恵を受けることができるのは大きなメリットと感じました。

また、Viewsで設計したページは、大量のテーブルをJOINすることになりオーバーヘッドが増えてしまって許容できないほどに処理が遅くなることがありますが、キャッシュモジュール群を利用すれば解消できるケースも増えると思われます。

一方、共用サーバやプログラム構成のカスタマイズが制限される環境ならば、「boost」+「filecache」+「advagg」+「expire」の組み合わせがサーバ環境に依存せずにそこそこのパフォーマンスが引き出せるのではないかと思います。