扫盲:php session缓存至memcached中的方法

memcached是一套分布式的快取系统,当初是Danga Interactive为了LiveJournal所发展的,但被许多软件(如MediaWiki)所使用。这是一套开放源代码软件,以BSD license授权协议发布。[1]

memcached仅支持一些非常简单的命令 比如get(获取某个键值) set(用来设定或保存一个缓存);

其本身是缓存服务器,但本身无法决定缓存任何数据,其缓存机制依赖于服务端和客户端两者必不可少(存储是由服务端进行存储,但存储什么是由客户端进行决定的)

因此客户端要自己提供缓存的键名以及时长、标志位、整个数据大小等等

 

例如:只存储hello 但只存储60秒

set key 5 60 hello

并告知服务器端,这样存储过了60秒后,由服务端进行清除数据

但是其工作机制非常独特,其缓存功能是基于Lazy模型的:

只要空间未满则不清理

 

那么问题来了:如果空间过小,而需缓存的内容过大的话,那么导致缓存抖动非常严重,存完即清理其次再去缓存这样会导致命中率下降,而毫无意义

有些时候,有些数据管理不善有可能导致缓存崩溃等

如果memcached崩溃仅导致业务层的影响,最多是速度降低 而不会导致数据层

 

memcached如何实现缓存的

memcached通过内存进行缓存数据,但并不实现持久缓存

 

存数数据的下限:

最小为48字节

最大不能超过1MB

 

但存储的数据大小有可能不一致,比如:

index.html10k

test.jpg34k

 

那memcached如何在内存中管理缓存数据

 

假如我们分别存储不同大小的数据以上为例

很显然只要分配一个足够大的空间就可以了,但是在内存中去找对应的数据我们必须要有对应的缓存对象的边界(起始存储位地址和结束存储位地址)将其当做独立的单位来管理

等其缓存失效了,空间会被腾出,时间久了可能会带来碎片,因为存储的都是非常小的数据单元,按理说如果再想高速利用则会困难,所以在这种机制下memcached的存储数据 查询数据等操作都是非常缓慢的

由此,不停快速基于内存的申请、释放反复操作,这种释放本身也消耗大量的资源和时间

因此我们需要一种高效的机制来解决内存的创建和释放的问题

对于memcached来讲首要必须解决这类内存碎片问题,不然由于内存的碎片导致进程运行的非常缓慢

 

在linux内核中引入了两种机制避免内存碎片

 

1.buddy system    伙伴系统

为了实现整个内存中以页面方式管理内存的时候有足够大的连续内存空间可用的,在物理内存中,事实上内存的管理和分配在内核级别通常以页面方式分配和使用的

通常是4k大小一个页面,buddy就是为了将这些零碎的、空闲的合并成一个连续的大的内存空间,这样就避免了页面之间产生碎片的,因此,其主要目的是为了避免内存外碎片

 

2.slab allocator  slab分配器

实现将存储小于页面单位的非常小的数据内存结构的时候之前事先分配并随时等待有需求的进程或要存储的对象使用,当我们使用之后它也不会自动消毁结构而是随时重复使用

避免内存内部碎片

 

最新版本的memcached使用的是增长因子(growth factor)来明确定义起始点开始依次增长

比如:

我们定义增长因子为其2倍

我们存储一个单位为48bytes,那么会分配其48*2 = 96bytes

如果增长因子为1.1倍

那么48+48*1.1

一旦存储空间满了,则会清理,没有存满则不会清理数据

 

memcached也支持分布式缓存基础概念

memcached也支持分布式缓存,但是彼此之间不会通信,但是一个memcached也不会缓存过多数据,如果将来缓存的数据很大的话,那只能使用多台memcached提供服务

假设这么一个场景:

前端的应用服务器很多,这些服务器角色都需要连接至数据库,为了加速数据库的性能,可对其提供memcached服务器,经过一段时间观察,我们的memcached数据库缓存过多,请求量过大一台机器根本扛不住,这时需要对其扩容。

于是我们又加入了一台memcached,但是memcached服务器之间是不能通信的

所以某一应用服务器A 要缓存数据不能只盯一台memcached,所以我们要让其轮流来提供服务,但是对memcached而言它的分布式算法是在应用程序(客户端)中实现的,而不是取决于服务器自身

 

客户端是如何分布式调度服务端

需要一定分布式算法,和调度器

(如果memcached非常多的话,完全可以使用第三方调度器进行调度,比如nginx+持久连接)

 

或一致性哈希算法:

参考:http://blog.csdn.net/kongqz/article/details/6695417

 

总结:

1、在内存中缓存

2、内存要使用slab allocator将其分配成很多slab trunk,每个trunk用来存储一类数据的,而真正存的数据很有可能不会被精确匹配,而我们需要给其找一个最佳的匹配机制就是用来slab trunk来存储 但是难免会浪费内存空间,但是可以让我们内存分配效率非常高

 

 

安装配置memcached服务

Memcached依赖于libeventAPI库,所以首先要安装libevent

[root@testtools]# tar xf libevent-2.0.21-stable.tar.gz 

[root@testtools]# cd libevent-2.0.21-stable

[root@testlibevent-2.0.21-stable]# ./configure --prefix=/usr/local/memcached--with-libevent=/usr/local/libevent

[root@testlibevent-2.0.21-stable]# make && make install

安装memcached

[root@testtools]#cd memcached-1.4.15

[root@testmemcached-1.4.15]# ./configure --prefix=/usr/local/memcached--with-libevent=/usr/local/libevent && make && make install

 

启动memcached

启动之前我们先来看一下memcahced关键的几个参数

关键参数说明

[root@node1bin]# ./memcached -h

-p 监听tcp协议的监听端口

-T 监听UDP协议id监听端口默认都是11211 

-s 如果只在本地通信那么可以将其监听在某个套接字上,比如mysql.scok 能够利用共享内存方式进行通信的

-c 最大并发连接数

-l 监听的地址,如果服务器有多块网卡,那么用-l来指定监听的某个网卡上

-d 以一个服务方式运行

-r 设定最大内核大小限制

-u 以某个用户身份运行

-m  以兆为单位指定memcached最大内存可用空间

-t 用于处理入站请求最大的线程数,仅在memcached编译时开启了支持线程才有效,而linux对线程支持是非常有限的,所以不用关心了

-f 设定slab定义预先分配内存空间大小固定的块时使用的增长因子

-n 最小的存储单位是多大,默认是48字节,单位是字节

-P 指定pid文件

-L 视图使用最多的内存空间

-S 启用SSL认证功能

启动memcached

这里先放在前台运行,并观察其增长因子,如下所示:

[root@testbin]# /usr/local/memcached/bin/memcached -m 128 -n 20 -f 1.25 -vv -u nobody

slabclass1: chunksize72 perslab14563

slabclass2: chunksize96 perslab 10922

slabclass3: chunksize120 perslab 8738

slabclass4: chunksize 152 perslab 6898

slabclass5: chunksize192 perslab5461

slabclass6: chunk size240 perslab4369

slabclass7: chunk size304 perslab3449

#################中间略#################

slabclass40: chunk size493552 perslab2

slabclass41: chunk size616944 perslab1

slabclass42: chunk size771184 perslab1

slabclass43: chunksize1048576perslab1

<26server listening (auto-negotiate)

<27server listening (auto-negotiate)

<28send buffer was 229376, now 268435456

<28server listening (udp)

<29send buffer was 229376, now 268435456

<29server listening (udp)

<28server listening (udp)

<29server listening (udp)

<28server listening (udp)

<29server listening (udp)

<28server listening (udp)

<29server listening (udp)

chunk size 表示最小为72 以1.25倍的方式增加

slab class 表示分配给Slab之后根据slab的大小切分成chunk,chunk用于缓存记录,特定大小的chunk组称为slab class

perslab 表示一共有多少个空闲空间可用

 

结束进程,将增长因子换种方式增长,并观察效果

[root@testbin]# /usr/local/memcached/bin/memcached -m 128 -n 20 -f 1.1 -vv -u nobody

slabclass1: chunksize72perslab14563

slabclass2:chunk size80 perslab13107

slabclass3:chunk size88 perslab11915

slabclass4: chunksize96perslab10922

slabclass5: chunk size112 perslab9362

slabclass6: chunk size128 perslab8192

###################中间略#################

slabclass95: chunk size750904 perslab1

slabclass96: chunk size826000 perslab1

slabclass97: chunk size908600 perslab1

slab class98chunk size1048576 perslab1

以上,我们很明确对比出其差别

 

由此接下来我们就将其放在后台运行,加入-d参数

[root@testbin]# /usr/local/memcached/bin/memcached -m 128 -n 20 -f 1.1-u nobody -d

查看监听端口

[root@testbin]#netstat -lntup | grep memcache

tcp00 0.0.0.0:112110.0.0.0:*LISTEN9464/memcached

tcp00 :::11211:::*LISTEN9464/memcached

udp00 0.0.0.0:112110.0.0.0:*9464/memcached

udp00 :::11211:::*9464/memcached

 

连接memcahced

[root@testbin]# telnet 127.0.0.1 11211

使用add命令为memcahced新建键

格式:

addkeyname flag  timeout  datasize

例如:

addmykey 0 10 12
Hello world!

<30add mykey 0 10 12
hello

<30add mykey 0 10 12
hello

 

让php支持memcached

[root@testtools]# tar xf memcache-2.2.6.tgz

[root@test tools]# cd memcache-2.2.6

[root@testmemcache-2.2.6]# /usr/local/php/bin/phpize

Configuringfor:

PHP ApiVersion:20100412

ZendModule Api No:20100525

ZendExtension Api No:220100525

[root@testmemcache-2.2.6]# ./configure --with-php-config=/usr/local/php/bin/php-config--enable-memcache

[root@testmemcache-2.2.6]# make && make install

编译成功后,可以看到有如下反馈信息,将其路径记下

Installingshared extensions:/usr/local/php/lib/php/extensions/no-debug-non-zts-20100525/

查看模块是否存在

[root@testmemcache-2.2.6]#ls/usr/local/php/lib/php/extensions/no-debug-non-zts-20100525/

memcache.so

将其模块写入至php.d/目录下

[root@testmemcache-2.2.6]# echo'extension=/usr/local/php/lib/php/extensions/no-debug-non-zts-20100525/memcache.so'>/etc/php.d/memcache.ini

重启fastcgi

[root@testmemcache-2.2.6]# /etc/init.d/php-fpm restart

访问phpinfo,并查看是否有memcache模块扩展,如下所示:

wKiom1NvQFbzGoI5AAGeblkTK6E176.jpg

 

对memcached功能进行测试

建立php测试页面,内容如下:

[root@node1htdocs]# vim test.php

 

<?php
$mem = new Memcache;

;创建memcache对象连接其11211端口 ,如果能连接则说明可以访问memcache
$mem->connect("127.0.0.1", 11211)  or die("Could notconnect"); 

 

;如果服务能连接上,则显示其版本号是多少
$version = $mem->getVersion();
echo "Server's version: ".$version."<br/>\n";

;并且创建key名称为hellokey 内容为hello world 期限为600秒,这里没有长度,其会自动判断长度
$mem->set('hellokey', 'Hello World', 0, 600) or die("Failed to savedata at the memcached server");
echo "Store data in the cache (data will expire in 600seconds)<br/>\n";

$get_result = $mem->get('hellokey');
echo "$get_result is from memcached server.";    

?>

访问测试:

wKioL1NvQETAHriaAAC0cd5vZuc179.jpg

连接memcahced ,可以看到,我们保存的键值与上一致

[root@testhtdocs]#telnet 127.0.0.1 11211

Trying127.0.0.1...

Connectedto 127.0.0.1.

Escapecharacter is '^]'.

get hellokey

VALUEhellokey 0 11

HelloWorld

END

由此可见,我们的php可以使用memcache了

 

将php的session会话信息保存至memcached当中

编辑php.ini配置文件

找到session相关参数

session.save_handler= files     #默认是使用文件保存session的

更改为:

session.save_handler= memcache

session.save_path="tcp://127.0.0.1:11211?persistent=1&weight=1&timeout=1&retry_interval=15"

如果memcahced使用的是公网服务器的话最好使用其公网地址

保存退出并重启服务

[root@testhtdocs]# /etc/init.d/php-fpm restart

Gracefullyshutting down php-fpm . done

Startingphp-fpmdone

创建测试页setsession.php

[root@testhtdocs]# cat setsession.php

<?php

session_start();

if(!isset($_SESSION['test'])) {

$_SESSION['test'] = time();

}

print$_SESSION['test'];

print"<br><br>";

print"Session ID: " . session_id();

?>

 

新建php页面showsess.php,获取当前用户的会话ID:

[root@testhtdocs]# cat showsess.php

<?php

session_start();

$memcache_obj= new Memcache;

$memcache_obj->connect('127.0.0.1',11211);

$mysess=session_id();

var_dump($memcache_obj->get($mysess));

$memcache_obj->close();

?>

而后找一其他主机,使用负载均衡轮询到不同的主机上,可以发现无论刷新至哪个页面 其用户的session是一样的

访问setsession.php

wKioL1NvQGGDh61cAACaddedWVg504.jpg

1399775256         #为获取时间
Session ID: 9a0itlgjlurghq83ibvmol5pc7     #为session的id号

 

获取session

wKiom1NvQKvTZZ99AACHnmI4r1g629.jpg

可以看到其时间是与上面setsession是一样的

 

总结

这样一来比php将session保存在本地效率要快很多,如果以后要使用多台memcached的话至于开发程序能否实现负载均衡,到底是使用取余的算法还是使用一致性哈希的算法完全要看开发人员的决定了

感谢各位。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/461335.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

beginner3

<!-- 生成验证码 --> <action name"rand" class"mainAction" method"rand"> <result type"stream"> //默认返回为nameSUCCESS <param name"contentType">image/jpe…

通过stream去重_stream去重

引言Spring Boot 2.0最近去了GA&#xff0c;所以我决定写我关于Spring的第一篇文章很长一段时间引言Spring Boot 2.0最近去了GA&#xff0c;所以我决定写我关于Spring的第一篇文章很长一段时间。自发布以来&#xff0c;我一直在看到越来越多的Spring WebFlux以​​及如何使用它…

文件IO——获取文件属性

以下内容源于朱有鹏嵌入式课程的学习整理与整理&#xff0c;如有侵权请告知删除。 前言 文件属性&#xff0c;包括文件的名字、创建时间、文件类型、文件权限等等内容。 本文讲述了以下内容&#xff1a; &#xff08;1&#xff09;文件类型有哪些&#xff1b; &#xff08;2&am…

使用juniversalchardet做字符编码识别

为什么80%的码农都做不了架构师&#xff1f;>>> 在抓取网站的页面的时候最烦人的一件事情之一就是识别原站点的编码&#xff0c;通常来说只有GBK&#xff08;GB2312&#xff09;和UTF8两种&#xff0c;不过依旧需要读取大量Http头信息来识别&#xff0c;有些网站则…

淘宝开放API,很不错

http://api.taobao.com/myresources/standardSdk.htm?spm0.0.0.0.YeOZMs# 转载于:https://www.cnblogs.com/tandychao/archive/2013/03/01/2938561.html

短线操作总结

今日操作很失败&#xff0c;到嘴的肉都跑了&#xff01;首先是昨日上午买入的保险股&#xff0c;下午领涨&#xff0c;由于是T1的缘故&#xff0c;只能在今天卖&#xff0c;没想到今日保险股全线熄火&#xff0c;走了一波过山车&#xff0c;至尾盘微利&#xff1b;其次是昨天下…

新人报道,写的东西还请大神们多指导!也希望能让和我一样的同事少走弯路。...

大家好&#xff01;我刚工作&#xff0c;经验还很有限&#xff0c;写的东西都是自己在工作过程中遇到的问题&#xff0c;花了很多时间来解决之后的一些总结&#xff0c;可能比较浅显也比较简单&#xff0c;有什么不足的地方还请大家指正&#xff0c;有好的方法也欢迎大家留言&a…

如何用word制作英语答题卡_英语考试答题卡(word 版)

西宁联想教育培训学校西宁联想教育培训学校第1页共1页****学校****考试模拟试卷英语卷(答题卡)(时间&#xff1a;120分钟&#xff0c;满分&#xff1a;120分)姓名&#xff1a;_______________学校&#xff1a;___________________准考证号&#xff1a;________________________…

获取系统信息1——linux系统中的时间

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 一、关于时间的概念 1、GMT时间 GMT是格林尼治时间&#xff0c;即格林尼治地区的当地时间。用格林尼治的当地时间作为全球国际时间&#xff0c;用以描述全球性的事件的时间&#xff0c;方便大家记忆…

hystrix 单独使用_使用Hystrix对Dubbo消费者提供线程隔离保护

在dubbo中对于消费者的保护提供了actives进行并发控制保护&#xff0c;但是功能相对薄弱&#xff0c;下面我们探讨下如何使用Netflix提供的服务容错组件Hystrix对dubo消费者提供线程隔离保护为什么需要Hystrix?在大中型分布式系统中&#xff0c;通常我们需要依赖很多dubbo服务…

二分查找(Binary Search)

1.递归实现 int binarySearchRecursive(int a[],int low,int high,int key){if(low>high)return -(low1);int midlow(high-low)/2;if(key<a[mid])return binarySearchRecursive(a,low,mid-1,key);else if(key > a[mid])return binarySearchRecursive(a,mid1,high,key)…

判断一个字符串是否为回文-链队(新建,进队,出队),链栈(新建,进栈,出栈)...

回文&#xff1a;字符对称排列的字符串&#xff0c;例如ABCBA 思路&#xff1a;根据队&#xff1a;先进先出和栈: 先进后出的原则&#xff0c;进行比较出队和出栈的字符是否相等。如果相等&#xff0c;则为回文。 创建控制台应用程序。 1 #region 字符节点类 2 …

字符设备驱动基础5——驱动如何操控硬件

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 补充内容&#xff1a;字符设备驱动高级篇5——静态映射表、动态映射结构体方式操作寄存器 前言 上节字符设备驱动基础4——读写接口的操作实践中&#xff0c;驱动源代码中的test_chrdev_open()、te…

Android----使用代码 建立gprs 闹钟 连接

Android&#xff1a;实用代码&#xff08;开启启动、建立GPRS连接、闹钟等&#xff09; 分类&#xff1a; Android2012-04-21 18:06312人阅读评论(0)收藏举报androidactionstringservice手机j2me1&#xff1a;查看是否有存储卡插入String statusEnvironment.getExternalStorage…

句法依存分析_复旦大学邱锡鹏教授:词法、句法分析研究进展综述

本文为第十六届自然语言处理青年学者研讨会 YSSNLP2019 报告《词法、句法分析研究进展综述》的简要文字整理&#xff0c;本报告主要回顾词法、句法领域的最新研究进展。 关于报告人&#xff1a;邱锡鹏&#xff0c;复旦大学计算机科学技术学院副教授&#xff0c;博士生导师。于复…

【struts2】Struts2的运行流程

1&#xff09;前提条件 在讲解流程之前&#xff0c;假设我们已经建立了的一个名为strutsDeepen的web工程&#xff0c;该工程仅仅实现了简单的用户登陆与欢迎界面。具体的实现为&#xff1a; 在web.xml中配置了Struts2的过滤器写了一个Action类&#xff0c;名称为loginAction在s…

获取系统信息2——linux中使用随机数

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 一、随机数和伪随机数 随机数是随机出现&#xff0c;没有任何规律的一组数列。真正的完全随机的数列是不存在的&#xff0c;只是一种理想情况。我们一般只能通过一些算法得到一个伪随机数序列。平时…

11. 类对象简介

11. 类对象简介1.1 类是一个模板&#xff0c;是一种类型&#xff0c;“物以类聚”1.2 对象是类的一个具体实现1.3例如&#xff1a;汽车模型和生产出来的汽车猫和我家的那只猫1.4 实例人骑车public class Test3{public static void main(String[] args){Person p new Person();…

python 建筑计算_制图小技巧:巧用Python和ELK瞬间完成总图建筑名称标注

哎呦&#xff0c;又到了每周一次的制图教室啦。经过前面两次制图教程的分享&#xff0c;相信大家对于白模填色和写实渲染这两种表达方式肯定有了较好的掌握。那么今天我们就转战制图技巧篇&#xff0c;和童鞋们聊一下总平面图中的建筑名称标注问题。对于总平面图&#xff0c;各…

在MacOSX上重新安装Python (10.8) python 自然语言处理的前戏

因为想学python自然语言处理就想在mac上重新配置一下python。 在网上找了很久才找到两篇有用的教程http://765i.cn/%E5%9C%A8macosx%E4%B8%8A%E9%87%8D%E6%96%B0%E5%AE%89%E8%A3%85python-10-8/ http://woodpecker.org.cn/diveintopython3/installing-python.html 第一篇文章基…