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 class98: chunk 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模块扩展,如下所示:

对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.";    
?>

访问测试:

连接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

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

获取session

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

总结

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

感谢各位。

扫盲:php session缓存至memcached中的方法相关推荐

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

    memcached是一套分布式的快取系统,当初是DangaInteractive为了LiveJournal所发展的,但被许多软件(如MediaWiki)所使用.这是一套开放源代码软件,以BSDlice ...

  2. html5 session 缓存,关于HTML5中的sessionStorage的会话级缓存使用

    sessionStorage作为HTML5的Web Storage的两种存储方式之一. 用于本地存储一个会话(session)中的数据,这些数据只有在同一个会话中的页面才能访问并且当会话结束后数据会被 ...

  3. 分布式缓存之memcached以及LAMP的搭建

    1.memcached简介 Memcached 是一个自由开源的,高性能,分布式内存对象缓存系统. Memcached 是以 LiveJournal 旗下 Danga Interactive 公司的 ...

  4. Linux分布式缓存系统——memcached+LAMP环境搭建+监控

    概述 memcached简介 Memcached是一个开源.高性能.分布式内存对象缓存系统. Memcached是一种基于内存的key-value存储,用来存储小块的任意数据(字符串.对象),这些数据 ...

  5. 将tomcat的session信息通过memcached实现共享

    为什么80%的码农都做不了架构师?>>>    1.先学大拿来点介绍 MSM(memcached-session-manager)支持tomcat6和tomcat7 ,利用Value ...

  6. 分布式缓存系统Memcached简介与实践(.NET memcached client library)

    原文:分布式缓存系统Memcached简介与实践(.NET memcached client library) 缘起: 在数据驱动的web开发中,经常要重复从数据库中取出相同的数据,这种重复极大的增加 ...

  7. 大型网站架构系列:缓存在分布式系统中的应用(二)

    缓存是分布式系统中的重要组件,主要解决高并发,大数据场景下,热点数据访问的性能问题.提供高性能的数据快速访问. 本文是缓存在分布式应用第二篇文章,介绍分布式缓存,Memcache,Redis,本地缓存 ...

  8. 分布式缓存系统 Memcached CAS协议

    Memcached在1.2.4版本后新增了CAS(Check and Set)协议,主要用于并发控制:memcached中同一个item同时被多个线程(多个客户端)更改的并发问题.CAS协议最本质的东 ...

  9. mybatis 创建session, 缓存, 执行SQL

    案例代码, 上一个博客已经分析了 SqlSessionFactory 的 build , 本文内容部分知识基于上篇的文章 mybatis 的初始化, build 这节我们分析, 开启session, ...

最新文章

  1. 自己服务器上部署APP应用(安卓和IOS版),下载页面的代码,以及IOS的xxx.plist文件的建立
  2. [问题解决] File /struts-tags not found
  3. 如何打造园本特色_立足城市特色 打造赛事品牌——年轻成马如何走向国际化...
  4. Matrix Studio LeetCode 刷题指南
  5. SpringCloud微服务:基于Nacos组件,整合Dubbo框架
  6. PPDet:减少Anchor-free目标检测中的标签噪声,小目标检测提升明显
  7. 软件复杂度与分而治之
  8. android 标题栏 fragment,切换Fragment 并更换标题栏
  9. 95-862-040-源码-runtime-blob-BlobStore
  10. idea 15 license server
  11. git的安装和简单使用
  12. qtp11安装及入门
  13. 9. 2019美赛论文提交注意事项
  14. WhereHows前后端配置文件
  15. IEC104规约学习笔记
  16. python点到直线的距离_点到直线距离公式的几种推导
  17. mysql 回归分析_统计科学之多元回归分析
  18. 传热学相关的无量纲数的物理意义
  19. 0_13_QGIS纠正矢量数据
  20. Java word转pdf Linux/windows跨平台 格式完美(利用命令行调用libreoffice)

热门文章

  1. 根据当前docker容器生成镜像提交到远端服务器
  2. pytorch学习 训练一个分类器(五)
  3. python外卷(10)--取整
  4. 简单了解linux,linux简单了解
  5. uninitialized_copy测试代码示例
  6. 不能干一辈子开发???
  7. JM8.5中的7种宏块模式问题 - zhoujunming的专栏 - CSDN博客
  8. VUE项目中 获得多个复选框 checkbox 选中的值(jquery)+ 解决 Uncaught TypeError: Cannot read property ‘push‘ of undefine
  9. VUE:兄弟组件间传参
  10. VSCode 多开、环境对比