缓存 PHP session 变量
背景介绍
用户在利用 PHP 搭建网站时,会把一些信息存放在 $_SESSION 全局变量里,可以很方便的存取。在 PHP 的 ini 配置文件里面提供了 [Session] 相关配置,可以支持将信息存到文件或 memcached 服务器里面。由配置项 session.save_handler = memcached 决定。大多数场景,该 session 数据并不需要持久化,且为了提升网站性能,会选择将 session 信息缓存到 memcached 里面。
问题
云数据库 Memcache 版和自建的 memcached 都实现了标准 memcached 协议,用户一方面为了减少服务器内存的占用,一方面减少对 memcached 的维护,希望将 session 的存储从自建的 memcached 迁移到云数据库 Memcache 版上面,且不希望改写代码,切换过程中遇到了问题,因此有了这篇文章,希望能帮到大家。
云数据库 Memcache 版和自建的 memcached 最重要的区别就是“账号密码鉴权”:
云数据库 Memcache 版:分布式集群统一对外提供服务,实现了负载均衡且无单点故障,用户可自由动态弹性调整配置且无需重启服务。既然是对外提供服务,就有相应的安全机制,如白名单、流控、账号密码鉴权。
自建 memcached:因为大多数用户自建 memcached 是不需要设置账号密码的,跟云数据库 Memcache 版比就少了 SASL 鉴权流程。那么用户将 session 的存储从自建的 memcached 迁移到云数据库 Memcache 上面,就需要在 php.ini 中配置账号密码。
解决方案
在老版本的 php memcached 扩展中无法支持,需要升级 php memcached 扩展至2.2.0版本,示例代码如下:
wget http://pecl.php.net/get/memcached-2.2.0.tgz
tar zxvf memcached-2.2.0.tgz
cd memcached-2.2.0
phpize
./configure --with-libmemcached-dir=/usr/local/libmemcached --enable-memcached-sasl
make
make install
找到刚升级 memcached.so,
stat
命令确定下是否更新(注意下 modify 时间)。修改 php.ini 配置。
session段:找到[Session]段落,修改存储引擎为:
session.save_handler = memcached**(注意是带d扩展)**
修改存储地址,即 Memcache 访问地址为:
session.save_path = "be6b6b8221cc11e4.m.cnhzalicm10pub001.ocs.aliyuncs.com:11211"(注意带d扩展,则前面不用加tcp://,不带d的扩展需要加)
修改缓存到 memcached 的 key 的时间:
session.gc_maxlifetime = 1440(单位是秒,强烈建议必须设置一个合理时间,以保证 OCS 始终只缓存热点数据)
memcached 段:在 php.ini 的全局段,建一个单独段落[memcached],然后在空白地方加入下面配置:
[memcached]
memcached.use_sasl = On
memcached.sess_binary = On
memcached.sess_sasl_username = "your_ocs_name"
memcached.sess_sasl_password = "your_ocs_password"
memcached.sess_locking = Off
安装步骤完结。上述关于 memcached 段和 Session 段其他有用参数参考链接如下:
http://php.net/manual/en/memcached.configuration.php
http://php.net/manual/en/session.configuration.php
接下来是测试是否生效。
测试
写测试代码如下 session.php:
<?php
session_start();
$sn = session_id();
echo "session id:".$sn."\n";
$_SESSION["ocs_key"]="session_value";
echo "session:".$_SESSION["ocs_key"]."\n";
?>
输出如下:
session id:ttrct9coa2q62r2sodlq4qf376
session:session_value
通过测试代码 get.php 从 Memcache 获取刚才 session.php 写入的 session 数据。
<?php
$memc = new Memcached();
$memc->setOption(Memcached::OPT_COMPRESSION, false);
$memc->setOption(Memcached::OPT_BINARY_PROTOCOL, true);
$memc->addServer("be6b6b8221cc11e4.m.cnhzalicm10pub001.ocs.aliyuncs.com", 11211);
$memc->setSaslAuthData("your_ocs_name", "your_ocs_password");
echo $memc->get("memc.sess.key.ttrct9coa2q62r2sodlq4qf376");
/*注意这里的key是有前缀的,由php.ini中memcached.sess_prefix字段决定,默认值为"memc.sess.key."。然后再拼接上面打出来的sessionid“ttrct9coa2q62r2sodlq4qf376”即可。*/
?>
该代码输出如下:
ocs_key|s:13:"session_value";
即 PHP SESSION 已经成功写入 Memcache。