为大家详细剖析一下memcache

缓存是什么?为什么要使用缓存?

缓存,通过在内存中缓存数据和对象来减少读取数据库的次数,从而提供动态、数据库驱动网站的速度。

缓存工具有哪些?区别在哪里?

缓存工具:Memecached、redis、MongoDB

区别:

性能都比较高:总体来讲,TPS(每秒总事务量)方面redis和memcache差不多,要大于 mongodb;

操作的便利性:

a) memcache数据结构单一

b) redis丰富一些,数据操作方面,redis更好一些,较少的网络IO次数,

c) mongodb支持丰富的数据表达,索引,最类似关系型数据库,支持的查询语言非常丰富;

内存空间的大小和数据量的大小:

a) redis在2.0版本后增加了自己的VM特性,突破物理内存的限制,可以对key value设置过期时间(类似memcache);

b) memcache可以修改最大可用内存,采用LRU算法;

c) mongoDB适合大数据量的存储,依赖操作系统VM做内存管理,吃内存也比较厉害,服务不要和别的服务在一起;

可靠性(持久化):

a) redis支持(快照、AOF):依赖快照进行持久化,aof增强了可靠性的同时,对性能有所影响;

b) memcache不支持,通常用在做缓存,提升性能;

c) MongoDB从1.8版本开始采用binlog方式支持持久化的可靠性

数据一致性(事务支持):

a) Memcache 在并发场景下,用cas保证一致性;

b) redis事务支持比较弱,只能保证事务中的每个操作连续执行

c) mongoDB不支持事务

数据分析:mongoDB内置了数据分析的功能(mapreduce),其他不支持

Memecached详解

Memecached、memecached和memecache的区别:

其中首字母大写的Memcached,指的是Memcached服务器,就是独立运行Memcached的后台服务器,用于存储数据的“数据库”;

而memcached和memcache指的是Memcached的客户端。其中memcache是独立用php实现的,属于老旧的版本。而memcached是基于原生的c的libmemcached的扩展,更加完善,性能更高一些。

Memecached重点启动设置参数

–m:默认分配内存大小为64M,32位操作系统下每个进程最大分配内存为2G,所以如果需要分配更多的内存需要使用64位操作系统,但是这个不会一启动就占用,是随着需要逐步分配给各slab的。;

–I:调整分配page页的大小,默认1M,最小1K,最大128K;

–f:memcached默认情况下下一个slab的最大值为前一个的1.25倍,可通过此参数来设定;

–P:TCP端口设置,默认为11211;

–l(小写L):监听的IP地址,如果为本机可不设置;

–d:以守护进程的方式运行;

–u:指定用户;

–M:禁止LRU策略,内存耗尽时返回错误,而不是删除项;

–c:最大同时连接数,默认为1024;

–t:线程数,默认为4;

e.g. /usr/bin/memcached -m 64 -p 11212 -u nobody -c 2048 -f 1.1 -I 1024 -d -l 10.211.55.9

Memecached内存分配策略

当第一次往memcached存储数据时, memcached会去申请1MB的内存(这1M的内存成为page) , 然后把该块内存分割为多个slab,如果可以存储这个数据的最佳的chunk大小为128B,那么memcached会把刚申请的slab以128B为单位进行分割成8192块. 当这页slab的所有chunk都被用完时,并且继续有数据需要存储在128B的chunk里面时,如果已经申请的内存小于最大可申请内存10MB 时,memcached继续去申请1M内存,继续以128B为单位进行分割再进行存储;如果已经无法继续申请内存,那么mamcached会先根据LRU 算法把队列里面最久没有被使用到的chunk进行释放后,再将该chunk用于存储.

Page为内存分配的最小单位

Memcached的内存分配以page为单位,默认情况下一个page是1M,可以通过-I参数在启动时指定。如果需要申请内存 时,memcached会划分出一个新的page并分配给需要的slab区域。page一旦被分配在重启前不会被回收或者重新分配

Slabs划分数据空间

Memecached存储数据时不是直接将数据存储到page中,而是预先划分为一系列的slab,每个slab至负责存储大于上一个slab同时又小于或等于其本身大小的数据,如slab2只负责存储105~136 byte之间大小的数据,每个slab大小是不一样的,默认下一个slab的最大值为前一个的1.25倍(-f)

Chunk才是存放缓存数据的单位

Memecached将每个slab划分为一系列相等大小的存储空间,这个空间就叫做chuck。Chunk是Memecached的最小存储单元。同时,如果存储数据大小小于chunk的大小,空余的空间将会被闲置,这个是为了防止内存碎片而设计的。例如下图,chunk size是224byte,而存储的数据只有200byte,剩下的24byte将被闲置。

Memcached内存分配策略

综合上面的介绍,memcached的内存分配策略就是:按slab需求分配page,各slab按需使用chunk存储。

这里有几个特点要注意:Memcached分配出去的page不会被回收或者重新分配Memcached申请的内存不会被释放slab空闲的chunk不会借给任何其他slab使用

Memecached的static命令详解

使用Telnet客户端连接Memecached后可以使用static命令

命令

含义说明

stats slabs

显示各个slab的信息,包括chunk的大小、数目、使用情况等

stats items

显示各个slab中item的数目和最老item的年龄(最后一次访问距离现在的秒数)

stats detail [on|off|dump]

设置或者显示详细操作记录;

参数为on,打开详细操作记录;

参数为off,关闭详细操作记录;

参数为dump,显示详细操作记录(每一个键值get、set、hit、del的次数)

stats malloc

打印内存分配信息

stats sizes

打印缓存使用信息

stats reset

重置统计信息

Memecached的分布式算法

当一台Memecached无法满足我们的需求时,我们需要配置多台Memecached服务器,这种用法就叫做Memecached的分布式,但是随之而来的问题是,假设我们有三台服务器A、B、C,需要存一个用户姓名,然后存在了服务器A上,那么当我们要取得时候如何得知我们之前存在哪里了呢?如何解决这个问题就成了Memecached分布式的重点。

通常而言我们有两种方式来实现:

哈希取摸(取余数):

a) 简介:假设我们有3台服务器,我们将存入Memecached中的key通过哈希算法得到一个整数,然后将这个整数与3取摸,那么不管这个整数是多少,结果必然是0,1,2中的一个,那么这样一来就可以解决这个问题。

b) 缺点:当我们服务器的数量发生变化时,依靠上述算法结果将会与未变化之前不同,导致原先我们存入的数据丢失无法获取到。

c) 代码示例:

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

/**

* 普通Hash分布

* 天涯PHP博客

* http://blog.phpha.com

*/

//Hash函数

function mHash($key){

$md5 = substr(md5($key), 0, 8);

$seed = 31;

$hash = 0;

for($i = 0; $i < 8; $i++){

$hash = $hash * $seed + ord($md5{$i});

$i++;

}

return $hash & 0x7FFFFFFF;

}

//假设有2台Memcached服务器

$servers = array(

array('host' => '192.168.1.1', 'port' => 11211),

array('host' => '192.168.1.1', 'port' => 11211)

);

$key = 'MyBlog';

$value = 'http://blog.phpha.com';

$sc = $servers[mHash($key) % 2];

$memcached = new Memcached($sc);

$memcached->set($key, $value);

?>

一致性哈希分布算法,一致性Hash分布算法分4个步骤:

a) 将一个32位整数[0 ~ (2^32-1)]想象成一个环,0 作为开头,(2^32-1) 作为结尾,当然这只是想象。

b) 通过Hash函数把KEY处理成整数。这样就可以在环上找到一个位置与之对应。

c) 把Memcached服务器群映射到环上,使用Hash函数处理服务器对应的IP地址即可。

d) 把数据映射到Memcached服务器上。查找一个KEY对应的Memcached服务器位置的方法如下:从当前KEY的位置,沿着圆环顺时针方向出发,查找位置离得最近的一台Memcached服务器,并将KEY对应的数据保存在此服务器上。

e) 代码示例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

/**

* 一致性Hash分布

* 天涯PHP博客

* http://blog.phpha.com

*/

class FlexiHash{

//服务器列表

private $serverList = array();

//记录是否已经排序

private $isSorted = FALSE;

//添加一台服务器

public function addServer($server){

$hash = $this->mHash($server);

if(!isset($this->serverList[$hash])){

$this->serverList[$hash] = $server;

}

//需要重新排序

$this->isSorted = FALSE;

return TRUE;

}

//移除一台服务器

public function removeServer($server){

$hash = $this->mHash($server);

if(isset($this->serverList[$hash])){

unset($this->serverList[$hash]);

}

//需要重新排序

$this->isSorted = FALSE;

return TRUE;

}

//在当前服务器列表查找合适的服务器

public function lookup($key){

$hash = $this->mHash($key);

//先进行倒序排序操作

if(!$this->isSorted){

krsort($this->serverList, SORT_NUMERIC);

$this->isSorted = TRUE;

}

//圆环上顺时针方向查找当前KEY紧邻的一台服务器

foreach($this->serverList as $pos => $server){

if($hash >= $pos) return $server;

}

//没有找到则返回顺时针方向最后一台服务器

return $this->serverList[count($this->serverList) - 1];

}

//Hash函数

private function mHash($key){

$md5 = substr(md5($key), 0, 8);

$seed = 31;

$hash = 0;

for($i = 0; $i < 8; $i++){

$hash = $hash * $seed + ord($md5{$i});

$i++;

}

return $hash & 0x7FFFFFFF;

}

}

?>

说明:这样一来,当添加或移除某一台服务器时,受影响的数据范围变的更小了。

Memecached的用法

add、set、replace的区别:

a) add用于添加一个要缓存的数据;

b) set用于设置一个指定key的内容,是add和replace的集合;

c) replace用户替换一个指定key的内容,如果key不存在则返回false;

方法

当key存在

当key不存在

add

false

true

replace

替换(true)

false

set

替换(true)

true

flush  用于清除缓存的所有数据;

cas  仅在当前客户端最后一次取值后,该key 对应的值没有被其他客户端修改的情况下, 才能够将值写入

increment和decrement:

a) increment,将元素的值+1,如果元素的值不是数字则按0处理;

b) decrement,将元素的值-1,如果元素的值不是数组则按0处理;

c) 可以通过increment和decrement实现Memecached的队列;

append和prepend:

a) append 向元素后面追加内容;

b) prepend 向元素前面追加内容;

memchache的数据类型_memcache详解相关推荐

  1. MySQL操作之JSON数据类型操作详解

    MySQL操作之JSON数据类型操作详解 这篇文章主要介绍了MySQL操作之JSON数据类型操作详解,内容较为详细,具有收藏价值,需要的朋友可以参考. 概述 mysql自5.7.8版本开始,就支持了j ...

  2. Redis五种基本数据类型底层详解(原理篇)

    Redis五种基本数据类型底层详解 详细介绍Redis用到的数据结构 简单动态字符串 SDS和C字符串的区别 总结 链表 字典 哈希表 字典 哈希算法 解决键冲突 rehash(重点) 渐进式reha ...

  3. mysql varchar类型实例_Mysql实例MySQL数据类型varchar详解

    <Mysql实例MySQL数据类型varchar详解>要点: 本文介绍了Mysql实例MySQL数据类型varchar详解,希望对您有用.如果有疑问,可以联系我们.1.varchar(N) ...

  4. 【Redis】数据类型的详解与使用场景【原创】

    文章目录 Redis数据类型的详解与使用场景 1-1 NoSQL的概述 1. 概述 2. 为什么需要NoSQL 3. NoSQL产品 4. 分类 5. 特点 2-1 Redis的概述 1. 概述 2. ...

  5. C语言 中的 数据类型 超详解

    C语言 中的 数据类型 超详解 一.整型(int.short.long.long long) 1.有符号整型 有符号整型的数据类型通常包括 int.short.long.long long 四种,因为 ...

  6. r语言如何读取matlab数据类型,R语言数据类型深入详解

    R语言用来存储数据的对象包括: 向量, 因子, 数组, 矩阵, 数据框, 时间序列(ts)以及列表 意义介绍 1. 向量(一维数据): 只能存放同一类型的数据 语法: c(data1, data2, ...

  7. mysql中整数数据类型tinyint详解

    文章来源: 学习通http://www.bdgxy.com/ 目录 1.1tinyint类型说明 1.2实践环境说明 1.3加unsigned属性 1.3.1SQL模式开启严格模式 1.3.2SQL模 ...

  8. mysql varchar()_MySQL数据类型varchar详解

    MySQL数据类型varchar详解 更新时间:2014年03月17日 11:10:11   作者: 这篇文章详细介绍了MySQL数据类型varchar,探讨varchar到底能存多长的数据.Inno ...

  9. php 字符串表示,php:字符串(string)数据类型实例详解

    什么是字符串(string)? 字符串就是连续的字符序列,由数字,字母和符号组成.在字符串的每个字符只占用一个字节. 在PHP中,有三种定义字符串的方式,分别是单引号('),双引号(")和定 ...

最新文章

  1. GBDT与XGBoost区别与联系 GBDT近些年来更因为被用于构建搜索排序的机器学习模型而引起广泛的关注
  2. map has no len python3
  3. [python](爬虫)如何使用正确的姿势欣赏知乎的“长得好看是怎样一种体验呢?”问答中的相片...
  4. JavaScript原始类型转换和进制转换
  5. 认仕医生接入云信,医友交流随时随地
  6. 航院 1874 畅通工程续
  7. chrome vue插件_VS Code 前端常用插件推荐
  8. 爬虫-通过正则表达式爬取学校选课网站的课程
  9. 如何评价一个RPC框架的性能
  10. ArcGIS GDB中要素类不可编辑
  11. matlab导出prn文件怎么打开,prn文件介绍及打印方法
  12. Sublime Text for Mac如何支持GBK编码
  13. word文档目录样式如何设置
  14. webshell检测方法归纳
  15. 柜员需要掌握的计算机知识,有多少计算机专业去银行后悔的,可以说说吗?
  16. HQChart实战教程17 -K线沙盘推演
  17. js:两种方法实现键盘按键控制
  18. 辉芒微IO单片机FT60F111-RB
  19. Windows10 重装系统小白教程
  20. 桥接模式 和 享元模式 介绍

热门文章

  1. C#在类型实例化时都干了什么:从一道笔试题说开去
  2. c# String 前面不足位数补零的方法 (转贴)
  3. C++ pair使用案例(一)
  4. C语言课后习题(36)
  5. 数据3分钟丨CSDN 1024程序员节来啦!PostgreSQL 14和openGauss 2.1.0在同一天正式发布。...
  6. 资源放送丨《 MySQL中的索引探究 - 2020云和恩墨大讲堂》PPT视频
  7. 新特性:postgresql的vacuum漫谈
  8. Hadoop 面试,来看这篇就够了
  9. 搞定研发知识管理,你的企业就能跑快一步
  10. 看KubeEdge携手K8S,如何管理中国高速公路上的10万边缘节点