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 来解析并保存 ...
随机推荐
- Chrome插件: 网站收藏
在工作中我们会收藏很多网址.以前一直都是用的chrome里面的收藏夹.后面觉得一点都不方便.看一下Chrome插件开发挺容易入手的所以自己写了一个Chrome插件. 基于:Angularjs + ...
- 四校联考 tree3
我们考虑计算红色点与非红色点的对数. 我们用f[i][j]表示i的子树中有j个红色点的概率,将i所有子树合并. 接着我们对于每一个状态,枚举i是红色还是非红色算概率. 同时我们可以求出i和i子树内一个 ...
- nginx下目录浏览及其验证功能配置记录
工作中常常有写不能有网页下载东西的需求,在Apache下搭建完成后直接导入文件即可达到下载/显示文件的效果;而Nginx的目录列表功能默认是关闭的,如果需要打开Nginx的目录列表功能,需要手动配置, ...
- CWMP开源代码研究4——认证流程
TR069 Http Digest 认证流程 一 流程及流程图 1.1盒端主动发起Http Digest认证流程 盒端CPE ...
- 吉特仓储管系统(开源WMS)--分享两月如何做到10W+的项目
在此文开篇之处先特别申明,此文在有些人的眼中会有广告的嫌疑,但是本人不想将其作为一个广告宣传的文章,在此提到软件内容部分请大家予以谅解和包含,作为时间不算短的程序员给大家分享一些自己开发吉特仓储管理软 ...
- 跟我从零基础学习Unity3D开发--初识U3D
首先声明,我也是才开始学,把自己学的记录下来也供一些想要学习的朋友参考,一起努力.希望大家能给我指点一下.切莫喷我. 什么是Unity3d呢? 百度百科------Unity是由Unity Techn ...
- Internet网
Internet网是世界上最大的基于IP的网络.它是世界上所有计算机使用IP相互对话的一个无组织的集合.Internet上每台计算机都至少有一个IP地址来标识该计算机. 节点与主机 连接到Intern ...
- Coding 及 git 的工程使用方法
在过去的两周,同学们除了在学习 C 语言之外,还在学习如何利用 git 将自己的代码上传到 coding 中.也有大量的同学,成功的上传了代码.但是,实际上大部分同学的用法都不合理.这里,以一 ...
- Django 1.9 Post 时候出现 CSRF token missing or incorrect 错误
get 的时候没有问题,只有在post的时候出现出现这个错误 在方法中加入 @csrf_exempt
- jeecg小吐槽续——自己折腾修改在线开发功能中“默认值”的使用
-- 原来设置了"默认值"的字段,新建表单时不会出现在表单上,要保存后才能在列表页面出现,而且第二次编辑时,设置了"默认值"的字段再也不能改成空值! -- 要修 ...