• PHP如何将session保存到memcached中?如何分布式保存PHP session


    session_set_save_handler无关的memcached保存session的方法

    在memcached服务器上

    1)下载memcached

    #wget http://memcached.googlecode.com/files/memcached-1.4.15.tar.gz

    2)由于memcached依赖libevent所以需要先安装libevent库,这里直接yum安装

    #yum install *libevent*

    3)安装memcached

    #./configure --prefix=/usr/local/memcached
    #make
    #make install

    4)启动memcached

    #/usr/local/memcached/bin/memcached -d -m 4096 -p 11211 -u root
    -d daemon ?-p port -u ?user -m memory

    在web server服务器上

    5)在web server上安装php的memcache模块

    #/usr/local/php/bin/pecl install memcache

    Enable memcache session handler support? [yes] : yes(这里选择yes)

    6)在php.ini中加入如下内容:

    extension=/usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/memcache.so

    7)修改php.ini中的session.save_handler及session.save_path为如下内容:

    session.save_handler = memcache
    session.save_path = "tcp://memcached服务器ip:11211"

    亦可在PHP程序中

    ini_set('session.save_handler', 'memcache');
    ini_set('session.save_path', 'tcp://memcached服务器ip:11211');

    注意:这种使用memcached保存session的方式与session_set_save_handler无关


    安装完memcached之后

    在php.ini中

    将session.save_handler 修改为memcache,并修改save_path指向memcached的地址和端口即可

    session.save_handler = memcache
    session.save_path = tcp://127.0.0.1:11211

    memcache的PECL这个扩展非常强大,可以支持failover以及分布存储。

    使用方法很简单,只需要在session.save_path的参数列表中,使用逗号分隔各个memcached服务器,如:

    session.save_path = "tcp://172.16.8.81:11211,tcp://172.16.8.82:11211,tcp://172.16.8.83:11211"

    则保存的session会经过hash之后保存到各个memcached服务器中,而hash的算法memcache支持两种,crc32以及fnv:

    memcache.hash_function= {crc32,fnv}

    文档中很少有提到fnv算法的,据说其散列要比crc32更好,但是我通过以下小小的程序实验之后,发现仍旧是crc32的散列算法分布的更加平均。

    <?php
    ini_set("memcache.hash_function", "crc32");
    $memcache = new Memcache;
    $memcache1 = new Memcache;
    $memcache2 = new Memcache;
    $memcache->addServer('localhost', 11211);
    $memcache->addServer('localhost', 11212);
    $memcache->flush();
    $memcache1->connect('localhost', 11211);
    $memcache2->connect('localhost', 11212);
    $fp1 = fopen("mem1.txt", "w");
    $fp2 = fopen("mem2.txt", "w");
    for ($i = 0; $i < 1000; $i++)
    {
    	$memcache->set($i, $i, 0, 1000);
    	fwrite($fp1, $memcache1->get($i) . " ");
    	fwrite($fp2, $memcache2->get($i) . " ");
    }
    fclose($fp1);
    fclose($fp2);

    接着我就session的保存进行了测试

    我开了3个memcached进程进行测试

    <?php
    ini_set("memcache.hash_function", "fnv");
    ini_set("error_reporting", "E_CORE_ERROR");
    $memcache1 = new Memcache;
    $memcache1->connect('localhost', 11211);
    $memcache1->flush();
    $memcache2 = new Memcache;
    $memcache2->connect('localhost', 11212);
    $memcache2->flush();
    $memcache3 = new Memcache;
    $memcache3->connect('localhost', 11213);
    $memcache3->flush();
    $fp1 = fopen('mem1.txt', 'w');
    $fp2 = fopen('mem2.txt', 'w');
    $fp3 = fopen('mem3.txt', 'w');
    for ($i = 0; $i < 1000; $i++)
    {
    	session_start();
    	$ssid = session_id();
    	echo $ssid;
    	session_register("id");
    	$_SESSION["id"] = $ssid;
    	session_write_close();
    	fwrite($fp1, $memcache1->get($ssid) . ' ');
    	fwrite($fp2, $memcache2->get($ssid) . ' ');
    	fwrite($fp3, $memcache3->get($ssid) . ' ');
    	//session_destroy();
    }
    fclose($fp1);
    fclose($fp2);
    fclose($fp3);

    比较奇怪的是 memcached2一般都会不被选中,

    而1,3的内容是一致的。可能是为了failover,

    而当我把1,3关闭后,2中将会出现内容,说明memcached2是正常工作的。

    而不论我的散列算法使用crc32还是fnv,这种现象都存在,

    最后我发现:这个测试程序存在问题。

    因为在session_write_close之后,整个程序的session都是唯一的了。

    也就是虽然循环了这么多次,里面包含了session_destroy调用,但是返回的session id都是同样的。

    这就导致了两个文件中的内容一致而另一个文件中没有内容,

    基于此点,

    我只能分次调用脚本,脚本修改如下:

    <?php
    ini_set("memcache.hash_strategy", "consistent");
    ini_set("memcache.hash_function", "crc32");
    ini_set("error_reporting", "E_CORE_ERROR");
    ini_set("memcache.allow_failover", "0");
    $memcache1 = new Memcache;
    $memcache1->connect('localhost', 10001);
    $memcache1->flush();
    $memcache2 = new Memcache;
    $memcache2->connect('localhost', 10002);
    $memcache2->flush();
    $memcache3 = new Memcache;
    $memcache3->connect('localhost', 10003);
    $memcache3->flush();
    $fp1 = fopen("mem1.txt", "a+");
    $fp2 = fopen("mem2.txt", "a+");
    $fp3 = fopen("mem3.txt", "a+");
    session_start();
    $ssid = session_id();
    echo $ssid . "
    ";
    session_register("id");
    $_SESSION["id"] = $ssid;
    //session_destroy();
    session_write_close();
    fwrite($fp1, $memcache1->get($ssid) . " ");
    fwrite($fp2, $memcache2->get($ssid) . " ");
    fwrite($fp3, $memcache3->get($ssid) . " ");
    session_destroy();
    fclose($fp1);
    fclose($fp2);
    fclose($fp3);

    然后再shell中重复运行多次,返回的ID不同了。

    再打开mem*.txt文件查看,

    发现3个文件中,每个session会保存在其中两个文件,然后分布不同。

    这证明了使用memcache来保存session,一个是做到了failover,第二会按照session id来做hash分布保存。

    【51CTO博文】扫盲:php session缓存至memcached中的方法

    CSDNPHP + Memcache 实现多服务器session共享

    延伸阅读利用session_set_save_handler()函数将session保存到MySQL数据库中

    Memcache学习总结.pdf

  • 相关阅读:
    OSGi for C/C++
    Tizen NPPlugin开发
    Trove4j
    [Tizen]某些目录下存放的东西
    OpenMobile's Application Compatibility Layer (ACL)
    params
    页面无法访问
    websevice 服务前台和后台
    SQL 创建存储过程
    UpdatePanel
  • 原文地址:https://www.cnblogs.com/52php/p/5675297.html
Copyright © 2020-2023  润新知