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 . "\n";
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中的方法
【CSDN】PHP + Memcache 实现多服务器session共享
延伸阅读:利用session_set_save_handler()函数将session保存到MySQL数据库中
PHP如何将session保存到memcached中?如何分布式保存PHP session的更多相关文章
- Flask实战第43天:把图片验证码和短信验证码保存到memcached中
前面我们已经获取到图片验证码和短信验证码,但是我们还没有把它们保存起来.同样的,我们和之前的邮箱验证码一样,保存到memcached中 编辑commom.vews.py .. from utils i ...
- Asp.net Session 保存到MySql中
一 网站项目引入"mysql.web.dll" 二 web.config配置中添加mysql数据库连接字符串 <connectionStrings> <remov ...
- 利用session_set_save_handler()函数将session保存到MySQL数据库中
PHP保存session默认的是采用的文件的方式来保存的,这仅仅在文件的空间开销很小的windows上是可以采用的,但是如果我们采用uinx或者是liux上的文件系统的时候,这样的文件系统的文件空间开 ...
- php session保存到memcache或者memcached中
本教程叫你如何将php 的session存储在 memcached中,参考了好多网页,发现错误百出,最后自己还是测试成功了,现在将结果结果分享. 1-)系统环境 : elastix2.4 (cento ...
- ffmpeg从AVFrame取出yuv数据到保存到char*中
ffmpeg从AVFrame取出yuv数据到保存到char*中 很多人一直不知道怎么利用ffmpeg从AVFrame取出yuv数据到保存到char*中,下面代码将yuv420p和yuv422p的数 ...
- [redis] session 保存到 redis 简单实现
参考资料: [session保存到redis简单实现]http://blog.csdn.net/ppt0501/article/details/46700221 [Redis学习]http://blo ...
- 将数字n转换为字符串并保存到s中
将数字n转换为字符串并保存到s中 参考 C程序设计语言 #include <stdio.h> #include <string.h> //reverse函数: 倒置字符串s中各 ...
- Android把图片保存到SQLite中
1.bitmap保存到SQLite 中 数据格式:Blob db.execSQL("Create table " + TABLE_NAME + "( _id INTEGE ...
- c# 抓取和解析网页,并将table数据保存到datatable中(其他格式也可以,自己去修改)
使用HtmlAgilityPack 基础请参考这篇博客:https://www.cnblogs.com/fishyues/p/10232822.html 下面是根据抓取的页面string 来解析并保存 ...
随机推荐
- WinCE项目应用汇总
虚拟仪器(VI) RM905a+医用放射性核素活度计 RM905a+活度计远程检定方法研究 车载导航
- POJ1190生日蛋糕[DFS 剪枝]
生日蛋糕 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 18236 Accepted: 6497 Description ...
- java中的大数BigInteger
compareTo比较大小 equals比较是否相等 ,不能用== while(cin.hasNext())//等价于!=EOF n=cin.nextBigInteger();//读入一个大整数 Sy ...
- bzoj 1606: [Usaco2008 Dec]Hay For Sale 购买干草
Description 约翰遭受了重大的损失:蟑螂吃掉了他所有的干草,留下一群饥饿的牛.他乘着容量为C(1≤C≤50000)个单位的马车,去顿因家买一些干草. 顿因有H(1≤H≤5000)包 ...
- knockoutJS学习笔记08:表单域绑定
前面的绑定都是用在基本标签上,这章主要讲表单域标签的绑定. 一.value 绑定 绑定标签:input text.textarea. <p>用户名:<input type=" ...
- Mongodb学习笔记一(Mongodb环境配置)
Mongodb学习 说明: MongoDB由databases组成,database由collections组成,collection由documents组成,document由fileds组成.Mo ...
- Splay
#include <cstdio> #include <iostream> using namespace std; *1e5;//nil表示不存在的节点 ][],flag[] ...
- 延迟容忍网络(Delay-tolerant networking)
标签: 网络networking存储工作network路由器 2012-03-24 10:01 3702人阅读 评论(0) 收藏 举报 分类: 计算机网络(12) 版权声明:本文为博主原创文章,对文章 ...
- 【Ckediter】
- 1125Sending data
-- Sending data具体干什么The thread IS processing ROWS FOR a SELECT statement AND also IS sending DATA TO ...