使用memcached来管理PHP会话的事项
与默认的文件基础的会话管理相比,
它可以在多个WEB服务器之间共享会话,虽然现在可能有点晚了,
但是我觉得这样可以让我更幸福,所以我想试试看。
顺便提一下,我使用的是Nginx+FastCGI环境。
引导
安装
假设已经安装了PHP。
我们将使用memcached作为PHP的模块。虽然也有一个叫做memcache(非常相似)的东西,但根据志愿者的比较,目前这个更快。由于正在进行开发竞赛,所以不能确定未来会怎样。
# yum install memcached php-pecl-memcached
启动
# chkconfig memcached on
# service memcached start
更改PHP配置
如果你想要在脚本中进行更改,可以跳过这一步骤。
通过更改配置文件,可以避免对应用程序进行修改,并且其他开发人员可以无需关注地使用memcached。(虽然在切换时可能会丢失一次会话)
将保存会话到文件的配置注释掉,并添加使用memcached的配置。
# vi /etc/php.ini
; session.save_handler = files // コメントアウト
; session.save_path = "/var/lib/php/session" // コメントアウト
# vi /etc/php.d/memcached.ini
session.save_handler = memcached // コメントアウトをはずす
session.save_path = "localhost:11211" // 追記
如果增加了WEB服务器,则需要用逗号分隔进行追加:
session.save_path = “localhost:11211,otherserver.com:11211″。
顺便提一下,我的环境是使用php-fpm,所以关于memcache.ini的部分和步骤是不同的。
# vi /etc/php-fpm.d/www.conf
; php_value[session.save_handler] = files //コメントアウト
; php_value[session.save_path] = /var/lib/php/session //コメントアウト
php_value[session.save_handler] = memcached //追記
php_value[session.save_path] = "localhost:11211" //追記
# service php-fpm reload
这将以默认方式将会话管理设置为memcached。
使用PHP设置memcached的配置。
如果未进行上述默认设置,则可以通过脚本进行以下设置更改。
$session_save_path = 'localhost:11211';
if (ini_set('session.save_handler', 'memcached') && ini_set('session.save_path', $session_save_path)){
session_start();
}
确认
您可以通过与 memcached 同时安装的 memcached-tool 工具来查看当前的缓存数据。
# memcached-tool localhost:11211 dump
此外,您也可以监视/var/lib/php/session/目录,或停止memcached,并观察其行为以确认其是否正常工作。
如果它没有正常工作,您可以检查PHP错误日志是否在会话开始时生成。
打开端口
在进行负载均衡时,需要将用于memcached的11211端口开放给其他WEB服务器。
实用篇
修改缓存大小
默认情况下,memcached的缓存空间将保留64MB。如果在服务运营中此大小不足时,我们需要更改此大小。首先,我们需要确认当前的设置方法。
只需上传一个文件,就能像APC一样在GUI中显示缓存状态的工具也已经发布了,类似memcache.php stats和apc.php。
这里是源代码。只需要从”here is the the source code.”的部分进行下载,然后根据服务器调整以下部分的内容并上传即可,非常简便。
define('ADMIN_USERNAME','memcached'); // Admin Username
define('ADMIN_PASSWORD','password'); // Admin Password
$MEMCACHE_SERVERS[] = 'mymemcache-server1:11211';
如果不想特地做这么麻烦的事情,请按照以下方式,您可以通过telnet进行确认。
# telnet localhost 11211
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
stats // これを入力します
quit // これで終了します
然后将输出当前的操作状态。
limit_maxbytes部分是当前的缓存大小。以字节为单位表示。
要更改设置,
# vi /etc/sysconfig/memcached
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="64" //ここを変更します(MB)
OPTIONS=""
# service memcached restart
修改有效期
如果使用了memcached,是否不会因为垃圾回收而不断增长呢?
也许有这样的疑问,但是不必担心,这个问题会在memcached的有效期限内得到管理。
这个有效期限在会话中使用php.ini的session.gc_maxlifetime来设置。
默认值是1440秒(24分钟)。
尽管我还没有进行验证,但我认为普通的垃圾回收方式是每100次访问调用一次,而memcached可能没有这个问题?所以可能稍微短一些。
如果想要进行更改,请在session_start之前按以下方式进行设置。
ini_set('session.gc_maxlifetime', 3600);
除了会话管理之外的用途
我觉得除了会话管理,还有想使用memcached的时候!使用set()方法进行值的缓存,用get()方法来获取。
$m = new Memcached();
$m->addServer('localhost', 11211);
$m->set('foo','var',60); // 60秒からfooというキーでvarという値をキャッシュします
var_dump($m->get('foo'));
$m->add('hoge','fuga',60); // set同様に値をキャッシュします
$m->add('hoge','piyo',60); // addは同一キーが存在する場合失敗するので次のvar_dumpではfugaのままです
var_dump($m->get('hoge'));
$m->flush(); // 全てのキャッシュデータを削除します
var_dump($m->get('foo')); // 削除されているためFALSEが返ります
add()和set()的功能相似,但是如果缓存中已经存在相同的键,则add()操作会失败。
现在有一个问题。假如执行flush(),那么连会话都会消失。
因此,我还会写一个处理只删除除会话以外的缓存的方法。
通过getAllKeys()获取所有键,判断是否有与会话数据相关的前缀,如果没有则进行删除操作。如文档所述,前缀应为’memc.sess.key.’,我们会使用前缀匹配来进行判断。
$m = new Memcached();
$cachekeys = $m->getAllKeys();
foreach ($cachekeys as $key) {
$prefix = 'memc.sess.key.';
if (strpos($key, $prefix, 0) !== 0) {
$m->delete($key);
}
}
所以,如果要同时使用memcached来管理会话和其他数据,最好注意给键添加前缀。