こんにちは。スタジオウミの新田です。

1年以上前にDrupal Meetup Tokyoにお邪魔した際にキャッシュのことが話題にあがり、「Drupalのキャッシュって一体何種類あるんだろう?」と疑問に思いました。当時は右も左もわからない初心者だったのでドキュメント読んでも欲しい答えが見つからず、放置してたのですが、今回時間があったので改めて調べてみました。同じ疑問を持つ方々の参考になれば幸いです。

Drupalのキャッシュとは?

キャッシュとは、一度使用したデータを取り出しやすいかたちで保存しておくことを指します。キャッシュを使用することで二回目以降に同じ計算をする必要がなくなり、プログラムの高速化に役立ちます。

キャッシュとは

Drupalを動かす際にサーバーサイドで考慮すべきキャッシュとしては主に以下のようなものがあります。

  • HTTPサーバーのキャッシュ(リバースプロキシ): Varnishなど
  • メモリーのキャッシュ: Memcachedなど
  • PHPのキャッシュ: PHP7ではOpcacheがデフォルトで有効化されています
  • Drupal自体のキャッシュ: Drupal内の処理で発生するデータをCache APIを通じてデータベースに保存します

今回は4つ目の「Drupal自体のキャッシュ」について説明していきます。

Caching Overview

Drupal 8で実装されているキャッシュの種類

Drupal 8にはあらかじめさまざまな種類のキャッシュが実装されています。Drupal 8の標準インストールで使える主なキャッシュの種類(「ビン」と呼びます)は以下になります。

  • Bootstrap: 登録されているフックやルート、テーマの情報。多くのリクエストで必要とされ、内容が変わることはほとんどない。
  • Discovery:登録されているプラグインやviews_data、YAMLファイル(libraries.ymlなどの)の情報。
  • Entity: ロードしたエンティティの情報。
  • Config: 構成ファイルの情報。
  • Menu: メニューのツリー構造やリンク先などの情報。
  • Data: パスなどのコンテクストで異なる情報。
  • Page: ページのHTTPレスポンスやメタ情報。
  • Dynamic Page Cache: コンテクストにより表示が異なるページのHTTPレスポンスやメタ情報。
  • Render: ブロックやページのレンダリングのマークアップやメタ情報。

というわけでいきなりタイトルの答えですが、Drupal 8のキャッシュは標準インストールで約10種類あることになります。 この他にコントリビュートモジュールをインストールすると新しいビンが追加されることがあります。それぞれのキャッシュはcache_[BIN_NAME]というテーブルに保存されているので興味のある方は覗いてみてください。

Concept: Cache

困ったらとりあえずキャッシュクリア

このようにDrupal 8ではキャッシュが多いため、開発中にキャッシュとファイルやDBで不整合が起きてバグのように見える現象が起きることがよくあります。初心者の方はエラーに遭遇したり、「変更が反映されていない」と感じることがあったら、とりあえず「キャッシュクリア」で全キャッシュを削除しましょう。

キャッシュクリアは管理画面(/admin/config/development/performance)かdrush crで行うことができます。

また、PageとDynamic Page Cacheのキャッシュは無効化できるので、開発中はそうするのがおすすめです。

開発中の Drupal 8 のキャッシュを無効にする

ちなみに、キャッシュクリア以外では、以下のような条件でキャッシュが削除されます。

  • キャッシュの寿命が切れた: キャッシュの寿命が設定されている場合は、その期限が過ぎるとキャッシュが削除されます。
  • キャッシュが依存する情報が変更された: 例えばノードのビューはノードに依存しているので、ノードが変更されるとビューを更新するため古いキャッシュは削除されます。ちなみにこの場合のノードのように、キャッシュが依存する情報を「キャッシュタグ」といい、キャッシュ作成時に指定されている必要があります。

キャッシュが効くはずの箇所でキャッシュクリアしてないのに情報が更新されていたら、上記のいずれかの条件が満たされていたと考えることができます。

ちなみに私はcron時にキャッシュクリアもされてそうなイメージを持ってたのですが、今回調べてみてそれは勘違いだということがわかりました...。

キャッシュの種類が多いことのデメリット

Drupalが他のCMSに比べて高速な理由の一つにきめ細かいキャッシュが挙げられることが多いのですが、キャッシュの種類が多いと以下のようなデメリットもあるようです。

  • キャッシュが増えすぎてDBを圧迫する
  • 条件が細かすぎて、作成されても二度と使われないキャッシュが存在する
  • 初回ロード時にキャッシュ作成のためデータベースへの書き込みが発生してロード時間が長くなる

1つ目の問題については、Drupal 8.4からsettings.phpでキャッシュの最大件数を指定できるようになりました。例えばRenderビンのキャッシュを最大1000件にしたい場合は、以下のように書きます。

$settings['database_cache_max_rows']['bins']['render'] = 1000;

これによりcron時に1000件を超えるキャッシュは削除されるようになります。ちなみにデフォルトでは全てのビンが最大5000件になっています。

Database cache bins are now fixed size — no more unlimited growth

2つ目と3つ目についてはこれからの課題になりそうです。

まとめ

今回のまとめです。

  • Drupal 8には標準インストールで約10種類のキャッシュがある
  • 開発時はフロントエンド関係のキャッシュはオフにして、困ったときはとりあえずキャッシュクリアがおすすめ。キャッシュクリア以外でキャッシュが削除される条件にはキャッシュの寿命とキャッシュタグがあるので知っておくと便利。
  • きめ細かいキャッシュが高速化に役立っている反面デメリットもあり。最大キャッシュ数はsettings.phpから設定できる

Drupalは知れば知るほどよくできてるな〜と思うことが多いのですが、キャッシュもここまで何重にも仕込まれてるとはびっくりしました。ちなみにCache APIを使えば簡単にカスタムキャッシュを追加することも可能なので、興味のある方は試してみてくださいね。


共に働く新しい仲間を
募集しています

スタジオ・ウミは「Drupal」に特化したサービスを提供する Drupal のエキスパートチーム。
フルリモート&フレックス制だから、働く場所を選ばず時間の使い方も自由です。
そんなワークライフバランスの整った環境で、当ブログに書かれているような
様々な技術を共に学びながら、Drupalサイト開発に携わってみたい方を募集しています。
まずはお話だけでも大歓迎!ぜひお気軽にご連絡ください。