Memcache学习笔记

很久之前的学习笔记了,发不出晒晒,别发霉 了。

内容不免有当时 认识错误的情况,还请各位亲,批评指正

Memcache 学习笔记

学习环境 CentOS-6.4-i386

libevent-2.0.21-stable.tar.gz memcached-1.4.15 memcache-2.2.7

彻底弄明白 memcached 和 memchache 的区别

memcached 是缓存服务端,也是memcache 项目名称

memcache 是最初的PHP一个扩展,来操作 memcached服务端的

而memcache的升级版 也叫 memcached (功能更全面,更加高效,支持sasl认证),也是用来操作memcached服务端的。

现在 在PHP上操作 阿里云的OCS 也是用的memcached扩展来操作的。

】 这一段【】之前认识有误,现在以更正

Memcached 介绍:

自由&开放源码, 高性能 ,分布式的内存对象缓存系统

由 livejounal 旗下的 danga 公司开发的老牌 nosql 应用.

Memcached 安装过程:

 

因为memcached 依赖于 libevent 库,因此需要先安装 libevent.

分别到 libevent.org 和 memcached.org 下载最新的 stable 版本(稳定版).

 

首先编译安装libevent

 

解压libevent到当前目录

 

进入libevent解压后的目录

配置 libevent安装目录为/usr/local/libevent

编译 make && make install 安装

 

开始安装memecached

 

解压memcahced

进入解压之后的memcached目录

配置memecache安装目录 以及制定libevent安装目录

开始编译 安装 make&&make install

注意: 在虚拟机下练习编译,一个容易碰到的问题—虚拟机的时间不对,

导致的 gcc 编译过程中,检测时间通不过,一直处于编译过程.

解决:

Da#te -s ‘yyyy-mm-dd hh:mm:ss’

# clock -w

# 把时间写入 cmos

如果编译过程出现错误,一般是由于缺少相关库导致。

 

启动memcache

-m 分配给memcache 使用的最大内存。-p 端口 -u用户名 nobody -vv输出信息到控制台

我们发现 memcached 已经启动,并把信息输出到控制台..

 

通过 memcached -h 查看帮助信息

/usr/local/memcache/bin/memcached -m 64 -p 11211 -u nobody -d 后台运行memcached

连接memcached

 

memcached 客户端与服务器端的通信比较简单,使用的基于文本的协议,而不是二进制协议.

(http 协议也是这样), 因此我们通过 telnet 即可与 memcached 作交互.

 

 

打开本地电脑上的cmd

输入192.168.2.100 11211 (虚拟机ip地址)如果无法链接请查看虚拟机防火墙

 

增:

add 往内存增加一行新记录

语法: add key flag expire length 回车

key

给值起一个独特的名字

flag 标志,要求为一个正整数

expire 有效期

length 缓存的长度(字节为单位)

flag 的意义:

memcached 基本文本协议,传输的东西,理解成字符串来存储.

想:让你存一个 php 对象,和一个 php 数组,怎么办?

答:序列化成字符串,往出取的时候,自然还要反序列化成 对象/数组/json 格式等等.

这时候, flag 的意义就体现出来了.比如, 1 就是字符串, 2 反转成数组3,反序列化对象

expire 的意义:

设置缓存的有效期,有 3 种格式

1:设置秒数, 从设定开始数,第 n 秒后失效.

2:时间戳, 到指定的时间戳后失效.

比如在团购网站,缓存的某团到中午 12:00 失效. add key 0 1379209999 6

3: 设为 0. 不自动失效.

注: 有种误会,设为 0,永久有效.错误的.

1:编译 memcached 时,指定一个最长常量,默认是 30 天.

所以,即使设为 0,30 天后也会失效.

2:可能等不到 30 天,就会被新数据挤出去.

 

delete 删除

delete key

[time

seconds]

删除指定的 key. 如加可选参数 time,则指删除 key,并在删除 key 后的 time 秒内,不允许

get,add,replace 操作此 key.

replace 替换

replace key flag expire length

参数和 add 完全一样,不单独写

get 查询

get key

返回 key 的值

set 是设置和修改值

参数和 add ,replace 一样,但功能不一样.

如下比较:

用 add 时, key 不存在,才能建立此键值.

但对于已经存在的键,可以用 replace 进行替换/更改

repalce,key 存在时,才能修改此键值,下图,data 不存在,则没改成功.

而 set 想当于有 add replace 两者的功能.

set key flag expire leng 时

如果服务器无此键 —-> 增加的效果

如果服务器有此键 —-> 修改的效果.

zhang是已经存在,而 date 原本不存在. set 都可以成功设置他们.

如下图的演示

注意:如果replace set 已经存在的值 当此值有效期为0(用不自动失效) 如果修改其有效期可能导致改键-值立即失效

如图

Add zhang 1 0 5

Zhang

过10秒之后执行

Replace zhang 1 10 5

hahaa

incr ,decr 命令:增加/减少值的大小

语法:

incr/decr key num

Key 键名

Num 每次增加/减少多少 要为整数

整数测试

小数测试/字符串测试

应用场景——秒杀功能,

一个人下单,要牵涉数据库读取,写入订单,更改库存,及事务要求, 对于传统型数据库来说,

压力是巨大的.

可以利用 memcached 的 incr/decr 功能, 在内存存储 count 库存量, 秒杀 1000 台

每人抢单主要在内存操作,速度非常快,

抢到 count<=1000 的号人,得一个订单号,再去另一个页面慢慢支付

 

统计命令: stats

把 memcached 当前的运行信息统计出来

Stats

缓存有一个重要的概念: 命中率.

命中率是指: (查询到数据的次数/查询总数)*100%

如上, 18/(18+7) 的命中率.

flush_all 清空所有的存储对象

并不是删除说有的items 只是把所有的items 标记为expired 因此这是memcache依旧占用着内存

Stats reset 清空统计数据

Stats malloc 显示内存分配数据

 

内存的碎片化

如果用 c 语言直接 malloc,free 来向操作系统申请和释放内存时,

在不断的申请和释放过程中,形成了一些很小的内存片断,无法再利用.

这种空闲,但无法利用内存的现象,—称为内存的碎片化.

Memcache用slab allocator(死拉博 埃雷科特) 缓解内存碎片化

memcached 用 slab allocator 机制来管理内存.

slab allocator 原理: 预告把内存划分成数个 slab class 仓库.(每个 slab class 大小 1M)

各仓库,切分成不同尺寸的小块(chunk).需要存内容时,判断内容的大小,为其选取合理的仓库.

系统如何选择合适的 chunk?

memcached 根据收到的数据的大小, 选择最适合数据大小的 chunk 组(slab class)。

memcached 中保存着 slab class 内空闲 chunk 的列表, 根据该列表选择空的 chunk, 然后将数据缓存于其中。

如果有 100byte 的内容要存,但 122 大小的仓库中的 chunk 满了

并不会寻找更大的,如 144 的仓库来存储,

而是把 122 仓库的旧数据踢掉! 详见过期与删除机制

固定大小 chunk 带来的内存浪费

由于 slab allocator 机制中, 分配的 chunk 的大小是”固定”的, 因此, 对于特定的 item,可能造

成内存空间的浪费.

比如, 将 100 字节的数据缓存到 122 字节的 chunk 中, 剩余的 22 字节就浪费了对于 chunk 空间的浪费问题,无法彻底解决,只能缓解该问题.开发者可以对网站中缓存中的 item 的长度进行统计,并制定合理的 slab class 中的 chunk 的大小.可惜的是,我们目前还不能自定义 chunk 的大小,但可以通过参数来调整各 slab class 中 chunk大小的增长速度. 即增长因子, grow factor! 启动的时候使用 -f 指定。

grow factor 调优

memcached 在启动时可以通过­f 选项指定 Growth Factor 因子, 并在某种程度上控制 slab 之间的差异. 默认值为 1.25. 但是,在该选项出现之前,这个因子曾经固定为 2,称为”powers of 2″策略。我们分别用 grow factor 为 2 和 1.25 来看一看效果:

可见,从 80 字节的组开始,组的大小依次增大为原来的 2 倍

来看看 f=1.25 时的输出:

对比可知, 当 f=2 时, 各 slab 中的 chunk size 增长很快,有些情况下就相当浪费内存.

因此,我们应细心统计缓存的大小,制定合理的增长因子.

注意:

当 f=1.25 时,从输出结果来看,某些相邻的 slab class 的大小比值并非为 1.25,可能会觉得有些计算误差,这些误差是为了保持字节数的对齐而故意设置的.

memcached 的过期数据惰性删除

1: 当某个值过期后,并没有从内存删除, 因此,stats 统计时, curr_item 有其信息

2: 当某个新值去占用他的位置时,当成空 chunk 来占用.

3: 当 get 值时,判断是否过期,如果过期,返回空,并且清空, curr_item 就减少了.

即–这个过期,只是让用户看不到这个数据而已,并没有在过期的瞬间立即从内存删除.

这个称为 lazy expiration, 惰性失效.

好处— 节省了 cpu 时间和检测的成本

 


memcached 此处用的 lru 删除机制.

如果以 122byte 大小的 chunk 举例, 122 的 chunk 都满了, 又有新的值(长度为 120)要加入, 要挤掉谁?memcached 此处用的 lru 删除机制.(操作系统的内存管理,常用 fifo,lru 删除)

lru: least recently used最近最少使用fifo: first in ,first out

原理: 当某个单元被请求时,维护一个计数器,通过计数器来判断最近谁最少被使用.就把谁 t 出.

注: 即使某个 key 是设置的永久有效期,也一样会被踢出来!即–永久数据被踢现象

memcached 中的一些参数限制

key 的长度: 250 字节, (二进制协议支持 65536 个字节)

value 的限制: 1m, 一般都是存储一些文本,如新闻列表等等,这个值足够了.

内存的限制: 32 位下最大设置到 2g.

如果有 30g 数据要缓存,一般也不会单实例装 30g, (不要把鸡蛋装在一个篮子里),

一般建议 开启多个实例(可以在不同的机器,或同台机器上的不同端口)

 

编译 php-memcache 扩展

以后的开发中,动手编译 PHP 的各种扩展是很容易碰到,此以 memcache 扩展编译为例。

PHP 扩展的通用编译流程

1: 到软件的官方(如 memcached)或 pecl.php.net 去寻找扩展源码并下载解压

2: 进入到 path/memcache 目录

3: 根据当前的 php 版本动态的创建扩展的 configure 文件

#/xxx/path/php/bin/phpize \

–with-php-config=/xxx/path/php/bin/php-config

4: ./configure

-with-php-config=/xxx/path/php/bin/php-config

5: make && make install

6:把生成的.so 扩展, 在 php.ini 里引入.

7:重启 apache

如图:本次学习使用memcache-2.2.7.tgz

 

[root@localhost ~]# tar -zxvf memcache-2.2.7.tgz

[root@localhost ~]# cd memcache-2.2.7

[root@localhost memcache-2.2.7]# ls

config9.m4 CREDITS memcache_consistent_hash.c memcache_queue.c memcache_standard_hash.c config.m4 example.php memcache.dsp memcache_queue.h php_memcache.h config.w32 memcache.c memcache.php memcache_session.c README

[root@localhostmemcache-2.2.7]#/usr/local/php/bin/phpize–with-php-config=/usr/local/php/bin/php-config

Configuring for:

PHP Api Version: 20090626

Zend Module Api No: 20090626

Zend Extension Api No: 220090626

[root@localhost memcache-2.2.7]# ls

acinclude.m4 config.guess configure.in ltmain.sh memcache.php missing aclocal.m4 config.h.in config.w32 Makefile.global memcache_queue.c mkinstalldirs autom4te.cache config.m4 CREDITS memcache.c memcache_queue.h php_memcache.h build config.sub example.php memcache_consistent_hash.c memcache_session.c README onfig9.m4 configure
install-sh memcache.dsp memcache_standard_hash.c run-tests.php

 

[root@localhost memcache-2.2.7]# ./configure -with-php-config=/usr/local/php/bin/php-config

Make && make install

 

生成的memcache.so 扩展在

/usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/里面

打开PHP.ini

搜索extensions 找到extension_dir 引入memcache.so

重启阿帕奇

在网站目录新建index,php

<?php

$memcache = new Memcache;

$memcache->connect(‘localhost’, 11211) or die (“Could not connect”);

$version = $memcache->getVersion();

echo “服务端版本信息: “.$version.”<br/>\n”;

 

?>

显示 服务端版本信息: 1.4.15 到此memcache和php整合成功。

 

Memcache实际应用场景

热门商品

利用memecache读取快的特点,来缓存数据库查询结果,缓解数据库压力。

图:

 

 


 






 

 

 

 

 

 

测试使用默认的addserver 分配机制

在同一台虚拟机上开启5个memcache进程。

设置如下


试验一如下:

同等权重的情况下,比较随着memcache的增多down一个memcache 对网站的影响大小

  1. 首先开启两个memcache 用testadd.php写入20 条数据, 然后用testget获取。

    结果如图


  2. 然后down掉一个。再次通过gettest.php获取 如图

    影响率 50%

     

  3. 杀掉全部memcache进程。开启5个。重复上面的过程。结果如图


    Down掉一个之前

    Down掉一个

    5% 可以看出 addserver 机制中down掉一个的影响 会随着memcache的增多 而降低

未经允许不得转载:开心乐窝-乐在其中 » Memcache学习笔记

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏