-shared-img-thumb-PAK57_ichigonocake_TP_V

CakePHPとキャッシュのいろいろについて

  • このエントリーをはてなブックマークに追加
  • Evernoteに保存

はじめまして。リスペクトの山内です。
昨年度プログラマとして新卒で入社し、ようやくプログラマ歴二年目に突入したところです。

さて、今回ブログを初めて書くにあたり、キャッシュについて取り上げてみようと思います。
データベースに無駄なリクエストを送らないようにしたりして処理を高速化する便利機能ですが、プログラミング初心者だと、なかなか処理速度にまで目が行かず、キャッシュにじっくり触る機会も少ないのではないでしょうか。

かくいう自分もそんなプログラミング初心者の一人なので、初心者脱却を目指してキャッシュについて調べてみました。

以下、概要です。

本記事は

  • CakePHPでのCacheクラスの使い方
  • CakePHPで使用できるキャッシュシステムの導入方法

について取り上げます。

今回の環境

  • CentOS 6.7
  • Apache 2.2.15
  • PHP 5.5.28
  • CakePHP 2.8.3

CakePHPのCacheクラスについて

キャッシュは主に、データベースなど外部のリソースから何度も同じデータを読み込みたいときに利用されます。
キャッシュの種類によってしくみは様々ですが、何度も利用することがわかっているデータをあらかじめキャッシュしておくことで、二度目以降のデータの呼び出しを高速化します。

CakePHPにはCacheクラスがあります。

このCacheクラスのなにがいいかというと、設定さえちゃんとしておけば、様々なキャッシュシステムを一貫した作法で使うことができるという点です。Cacheクラスを使えば、異なるキャッシュエンジンを使用したいときも容易に交換できます。

Cacheクラスの使い方

Cacheクラスは実際に使用する前に設定を行います。

Cache::config(‘test’, array(
    ‘engine’ => ‘File’,
    ‘duration’ => ‘+1 hours’,
    ‘prefix’ => ‘test_cake_’,
));

config()メソッドでこのようにすると、testという名前の設定が作られます。主な設定項目の内容は以下のとおりです。ここでは全キャッシュエンジン共通の設定項目を紹介します。

設定項目 概要 デフォルト
engine 使用するキャッシュエンジン
duration キャッシュの有効期限 3600
probability キャッシュクリアの確率 100
prefix キーのプレフィックス ‘cake_’
group キャッシュのグループ array()

その他設定項目はキャッシュエンジンによって様々なので、それぞれの項を参照してください。
また、Cacheクラスの主なメソッドは以下のようになっています。

Cache::write(‘key’, ‘value’, ‘test’);

testという名前の設定を使い、keyというキーでvalueという値をキャッシュします。

Cache::read(‘key’, ‘test’);

testという名前の設定を使い、keyというキーにキャッシュされた値を取得します。

Cache::delete(‘key’, ‘test’);

testという名前の設定から、keyというキーのキャッシュを削除します。

この他にもCacheクラスには様々なメソッドがあります。詳しくは公式のAPIを参照してください。

キャッシュエンジン

CakePHPはv.2.8.3現在、7つの組み込みのキャッシュエンジンを用意しています。

  • FileCache
  • ApcCache
  • Wincache
  • XcacheEngine
  • MemcacheEngine
  • MemcachedEngine
  • RedisEngine

(ちなみに最新のv3.*系ではMemcacheEngineがなくなり、すべてfalseを返すNullEngineが新たに追加されているようです。)
それぞれのキャッシュエンジンについて、導入方法から見ていきましょう。

キャッシュエンジンについて

FileCache

FileCacheは、ローカルファイルを使用するシンプルなキャッシュです。

CakePHP2.3以降はデフォルトのキャッシュエンジンになっており、CakePHPのコア内部でもFileCacheは使用されています。
なのでキャッシュが機能していれば、app/tmp/cacheなどにもキャッシュファイルが格納されています。

FileCacheのいいところは、何よりもそのシンプルさにあります。
ローカルファイルを作成してそこにデータを保存するだけなので、それほど高速なキャッシュではありませんが、それでもいちいち無駄にデータベースを叩くよりよっぽど高速ですし、他のキャッシュエンジンと違いPHP拡張などを導入する手間がありません。

求める処理速度にそこまで切羽詰まったものがなければ、まずはお手軽にFileCacheを導入してみてはいかがでしょうか。

Cache::config()で設定する、FileCacheの主な設定項目とデフォルト値は以下のとおりです。

設定項目 概要 デフォルト
engine ‘File’
path キャッシュファイルを保存するパスを指定します。 CACHE
lock flock()でファイルへの書き込みをロックします。 true
serialize シリアライズされたデータをキャッシュします。 true
mask 生成したキャッシュファイルのパーミッション 0664

ApcCache

PHPのAPC(Alternative PHP Cache)拡張を利用したキャッシュです。CakePHP2.0から2.2までは、APC拡張が利用可能であればこちらがデフォルトのキャッシュとして利用されていました。

APCはもともとPHPの中間コードをキャッシュするPHPアクセラレータです。
PHPはプログラムが呼ばれる度に中間コードにコンパイルされてから実行されますが、その中間コードをキャッシュしておくことで高速化をはかります(オペコードキャッシュ)。

CakePHPのApcEngineではAPCのオペコードキャッシュ機能ではなく、ユーザーキャッシュ機能を使用するためのapc_store()apc_fetch()というAPC関数を利用して変数をキャッシュするしくみを提供しているようです。

しかしこのAPC拡張、実はPHP5.5以降では使用することができません。

APCはオペコードキャッシュ機能、ユーザーキャッシュ機能を提供するPHPアクセラレータとして使われていましたが、PHP5.5への対応版が出ないままメンテナンスが止まってしまい、使われなくなりました。
現在ではAPCのユーザーキャッシュ機能のみを提供するAPCuと、オペコードキャッシュ機能を提供するZend OPcacheで同様の機能を使用することができます。
(参考:https://www.devside.net/wamp-server/installing-apc-for-php-5-5

ということで、PHP5.5以降の方々はあきらめて次の項に進みましょう。
APCが利用できる方はひとまずインストールです。
yumから簡単にインストールできます。

yum install php-pecl-apc

インストールが完了したらApacheを再起動するとapcが使えるようになります。
また、/etc/php.d/apc.iniあたりでメモリ容量などの設定ができます。APCの実行時設定を確認してみてください。

あとはCacheクラスで設定をしてしまえば、他のキャッシュエンジンと同様に使うことができます。簡単ですね。

設定項目は以下のとおりです。

設定項目 概要 デフォルト
engine ‘Apc’

余談ですが、前述のとおりAPC拡張はオペコードキャッシュ機能も持っているので、APC拡張を導入すればCacheクラスを利用せずとも多少PHPが高速化するようです。これは儲けものですね。

WinCache

こちらはPHPのWinCache拡張を利用したキャッシュです。
WinCacheはAPC同様、PHPの中間コードをキャッシュすることで高速化を図るしくみで、WindowsおよびWindowsサーバ上でのPHPアプリケーションの動作速度を向上させます。

Windows向けのキャッシュエンジンのようなので、ここでは割愛します。

XcacheEngine

PHPのXcacheを利用したキャッシュエンジンです。
XcacheはAPCと同じくPHPの中間コードをキャッシュしてPHP全体を高速化するPHPアクセラレータです。

PHP5.5以上をremiリポジトリで入れていた場合は、remi-php55リポジトリとかにあるようなのでyumでインストールできます。

yum --enablerepo=remi,remi-php55 install php-xcache xcache-admin

これで導入完了です。

それ以外の場合でもXCache公式からtar.gz形式でダウンロードし、手動でインストールすることも可能です。

wget https://xcache.lighttpd.net/pub/Releases/3.1.0/xcache-3.1.0.tar.gz
tar xvfz xcache-3.1.0.tar.gz
cd xcache-3.1.0
phpize
./configure --enable-xcache
make
make install
php -v

でPHPのバージョンを確認すると、一緒に

Zend Engine v2.5.0, Copyright (c) 1998-2015 Zend Technologies
    with XCache v3.1.1, Copyright (c) 2005-2014, by mOo
    with Xdebug v2.3.3, Copyright (c) 2002-2015, by Derick Rethans
    with XCache Optimizer v3.1.1, Copyright (c) 2005-2014, by mOo

こんなのが表示されているはずです。最後にApacheの再起動を忘れずに!

主な設定項目は以下のようになっています。

設定項目 概要 デフォルト
engine ‘Xcache’
PHP_AUTH_USER xcache.admin.userで設定したユーザー名 ‘user’
PHP_AUTH_PW xcache.admin.passで設定したパスワード ‘password’

MemcacheEngine / MemcachedEngine

PHPのMemcache及びMemcached拡張を利用したキャッシュエンジンです。名前はほぼ同じなのですが、これらは別物なので注意しましょう。
MemcachedEngineはv2.5から追加され、それに伴ってMemcacheEngineが非推奨になっているので、使うのであればMemcachedEngineの方を使用してください。ここでもMemcachedEngineについてのみ解説します。

Memcachedは分散型メモリオブジェクトキャッシュシステムと呼ばれており、PHPでもMemcachedクラスとして実装されています。APCなどのキャッシュシステムと違って、memcachedサーバを別に立て、そのサーバのメモリにキャッシュして負荷を減らすということもできます。

それでは実際にMemcachedを導入してみましょう。複雑なので、

  • memcachedの導入
  • libmemcachedの導入
  • php-pecl-memcachedの導入

の3ステップに分けて説明します。

memcachedの導入

まずは大元、memcachedの導入です。
memcachedはyumからインストールできます。

また、memcachedはlibeventというパッケージを使用するので、こちらもあらかじめyumでインストールしておきましょう。

yum install libevent libevent-devel memcached

インストールが終わったらmemcachedを起動してみましょう。
ちなみに、root権限で実行しようとすると以下の様なエラーが出ます。

can't run as root without the -u switch

言われたとおり、あらかじめ適当なユーザーにしておくか、-uオプションでユーザー名を指定して実行してください。

memcached -d -m 64 -p 11211

なにも問題がなければこれでmemcachedが起動されます。

ちなみに、memcachedの起動オプションは

  • -p: memcachedが利用するTCPのポート。デフォルトは11211
  • -d: デーモンとしてバックグラウンドで起動。
  • -m: 最大のメモリサイズ。デフォルトは64MB

みたいな感じです。起動オプションについてはこちらが詳しいので目を通してみてください。

libmemcachedの導入

memcachedを導入しただけでは、PHPからmemcachedを使用することはできません。
そのために、libmemcachedとphp-pecl-memcachedをインストールしましょう。

まずlibmemcachedですが、これはmemcachedのクライアントライブラリです。
libmemcacheというライブラリもあるので間違えないようにしてください。

wget https://launchpad.net/libmemcached/1.0/1.0.18/+download/libmemcached-1.0.18.tar.gz
tar xvf libmemcached-1.0.18.tar.gz
cd libmemcached-1.0.18
./configure
make
make install

libmemcached公式(英語)にあるのでよさげなものを選んできてください。基本的には最新のもので良いかと思います。

また、configureが途中で失敗する場合は、Cコンパイラがインストールされていない可能性があります。あらかじめ

yum install gcc gcc-c++

などしてコンパイラをインストールしておくようにしてください。

php-pecl-memcachedの導入

最後にphp-pecl-memcachedの導入です。
php-pecl-memcachedはPHPでMemcachedクラスを利用できるようにするためのPECL拡張です。CakePHPのMemcachedEngineでは、内部的にこのMemcachedクラスを使用しています。

yum --enablerepo=remi,remi-php55 install php-pecl-memcached

PHPをremiリポジトリ経由でyumインストールした場合はこれでインストールができます。
/etc/php.d/の中に設定ファイルz-memcached.iniが作成されているのを確認してください。

設定項目 概要 デフォルト
engine ‘Memcached’
servers memcachedサーバのアドレス、もしくはその配列 127.0.0.1
compress キャッシュの中身を圧縮するかどうか false
persistent 持続的接続にしたい場合はtrueを指定する false
login null
password null
serialize シリアライズエンジンを指定する。php/json/igbinary php
options memcachedクライアントのその他オプション array()

設定項目はこんな感じです。’servers’でサーバを複数設定できるのがポイントですね。

ちなみに、memcachedはデフォルトでは1MB以上の大きさのキャッシュを保存することができません。ですが、memcachedの起動時に-lオプションをつけて起動すると最大キャッシュサイズを変更することができます。なぜかキャッシュができていないことがあったら確認してみてください。

RedisEngine

Redisとは、メモリ上にキーとデータを保存するデータベースです。保存したい値と対応した任意のキーをペアで保存する、Key-Valueストア(KVS)を構築します。

Redisには、

  • 保存する値に文字列以外のデータ型を使用できる
  • メモリ上で動作するのと同時に、データをディスクに書き込んで永続化させる
  • 他のコンピュータに複製を作る「レプリケーション」という負荷分散の方法

など、Memcachedよりも豊富な機能が提供されています。
Redisについてより詳しいところは、redisドキュメント日本語訳などを参考にしてみてください。

RedisもまたMemcachedと同様に、PECL拡張を利用してPHPから使用できるようにしなければなりません。

redisはyumコマンドからインストールすることができますが、デフォルトのリポジトリにはないので、epelリポジトリからインストールしましょう。

yum --enablerepo=epel install redis

インストールができたらredis-serverコマンドでRedisを起動することができます。

redis-server /etc/redis.conf

ここで注意です。

上記コマンドは、設定ファイル/etc/redis.confの設定でRedisを起動するコマンドなのですが、
/etc/redis.confのデフォルトの設定ではローカルホストからしか接続できないようになっています(bind 127.0.0.1のところ)。
別サーバからRedisを使用したい場合はコメントアウトするなどして対応しましょう。

CakePHPのRedisEngineでは、PHPからRedisを扱うためのphpredis拡張を使用しています。こちらもepelリポジトリにあるはずなので、あわせてインストールしましょう。

yum --enablerepo=epel install php-pecl-redis

インストールまで終わったら/etc/php.d/の中にredis.iniという設定ファイルが作成されているのが確認できるかと思います。

ちなみに主な設定項目はこんな感じ。

設定項目 概要 デフォルト
engine ‘Redis’
server サーバーを指定します。 127.0.0.1
database 使用するデータベースの番号 0
port 使用するポート番号 6379
password false
timeout タイムアウトの秒数。0は無制限 0
persistent 持続的接続にしたい場合はtrueを指定する true
unix_socket UNIXソケットファイルのパス false

まとめ

それではまとめです。

ひとくちにキャッシュと言っても奥が深く、CakePHPからも多くのキャッシュエンジンを利用できます。

キャッシュエンジンの選び方はアプリケーションの規模などにより最適なものは異なり、サービスの規模が大きくなれば求められるキャッシュも変わってきます。
そんなときに、CakePHPのCacheクラスを利用しておけば簡単にキャッシュエンジンを付け替えることができるのです。

今までキャッシュを使ったことがないという人も、これを機にキャッシュデビューしてみてはいかがでしょうか。

以上、リスペクトの山内からでした。

  • このエントリーをはてなブックマークに追加
  • Evernoteに保存