缓存 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 中配置账号密码。

解决方案

  1. 在老版本的 php memcached 扩展中无法支持,需要升级 php memcached 扩展至2.2.0版本,示例代码如下:

    1. wget http://pecl.php.net/get/memcached-2.2.0.tgz
    2. tar zxvf memcached-2.2.0.tgz
    3. cd memcached-2.2.0
    4. phpize
    5. ./configure --with-libmemcached-dir=/usr/local/libmemcached --enable-memcached-sasl
    6. make
    7. make install
  2. 找到刚升级 memcached.so,stat 命令确定下是否更新(注意下 modify 时间)。

  3. 修改 php.ini 配置。

    1. session段:找到[Session]段落,修改存储引擎为:

      1. session.save_handler = memcached**(注意是带d扩展)**

      修改存储地址,即 Memcache 访问地址为:

      1. session.save_path = "be6b6b8221cc11e4.m.cnhzalicm10pub001.ocs.aliyuncs.com:11211"(注意带d扩展,则前面不用加tcp://,不带d的扩展需要加)

      修改缓存到 memcached 的 key 的时间:

      1. session.gc_maxlifetime = 1440(单位是秒,强烈建议必须设置一个合理时间,以保证 OCS 始终只缓存热点数据)
    2. memcached 段:在 php.ini 的全局段,建一个单独段落[memcached],然后在空白地方加入下面配置:

      1. [memcached]
      2. memcached.use_sasl = On
      3. memcached.sess_binary = On
      4. memcached.sess_sasl_username = "your_ocs_name"
      5. memcached.sess_sasl_password = "your_ocs_password"
      6. memcached.sess_locking = Off

安装步骤完结。上述关于 memcached 段和 Session 段其他有用参数参考链接如下:

http://php.net/manual/en/memcached.configuration.php

http://php.net/manual/en/session.configuration.php

接下来是测试是否生效。

测试

写测试代码如下 session.php:

  1. <?php
  2. session_start();
  3. $sn = session_id();
  4. echo "session id:".$sn."\n";
  5. $_SESSION["ocs_key"]="session_value";
  6. echo "session:".$_SESSION["ocs_key"]."\n";
  7. ?>

输出如下:

  1. session id:ttrct9coa2q62r2sodlq4qf376
  2. session:session_value

通过测试代码 get.php 从 Memcache 获取刚才 session.php 写入的 session 数据。

  1. <?php
  2. $memc = new Memcached();
  3. $memc->setOption(Memcached::OPT_COMPRESSION, false);
  4. $memc->setOption(Memcached::OPT_BINARY_PROTOCOL, true);
  5. $memc->addServer("be6b6b8221cc11e4.m.cnhzalicm10pub001.ocs.aliyuncs.com", 11211);
  6. $memc->setSaslAuthData("your_ocs_name", "your_ocs_password");
  7. echo $memc->get("memc.sess.key.ttrct9coa2q62r2sodlq4qf376");
  8. /*注意这里的key是有前缀的,由php.ini中memcached.sess_prefix字段决定,默认值为"memc.sess.key."。然后再拼接上面打出来的sessionid“ttrct9coa2q62r2sodlq4qf376”即可。*/
  9. ?>

该代码输出如下:

  1. ocs_key|s:13:"session_value";

即 PHP SESSION 已经成功写入 Memcache。