Memcached是一套高性能的、分布式内存对象缓存系统。它由C写成,以Key/Value的方式将数据储存在内存中。

一、Memcached特性

Memcached作为高速运行的分布式缓存服务器,具有以下特点:

1、协议简单

Memcached的服务器客户端通信使用简单的文本协议,而不是笨重复杂的XML等格式。因此,通过telnet 也能在memcached上保存数据、取得数据;

2、基于libevent的事件处理

Libevent是个程序库,它将Linux的epoll、BSD类操作系统的kqueue等事件处理功能 封装成统一的接口。即使对服务器的连接数增加,也能发挥O(1)的性能。 memcached使用这个libevent库,因此能在Linux、BSD、Solaris等操作系统上发挥其高性能;

3、内置内存存储方式

Memcached中保存的数据都存储在Memcached内置的内存存储空间中。 由于数据仅存在于内存中,因此重启memcached、重启操作系统会导致全部数据消失。 另外,内容容量达到指定值(启动时可以通过-m参数配置)之后,就基于LRU(Least Recently Used)算法自动删除不使用的缓存,不用担心,这个功能是可以配置的:Memcached启动时通过"-M"参数可以禁止LRU。不过,Memcached本身是为缓存而设计的,建议开启LRU.另外,Memcached本身是为缓存而设计的服务器,因此并没有过多考虑数据的永久性问题;

4、Memcached不互相通信的分布式

Memcached尽管是“分布式”缓存服务器,但服务器端并没有分布式功能,各个Memcached不会互相通信以共享信息。Memcached的分布式是完全由客户端程序库实现的,这种分布式是Memcached的最大特点。通过这种方式,Memcached Server之间的数据不需要同步,也就不需要互相通信了。

二、Memcached的适用场景

适用memcached的业务场景:

1)如果网站包含了访问量很大的动态网页,因而数据库的负载将会很高。由于大部分数据库请求都是读操作,那么memcached可以显著地减小数据库负载。    
2)如果数据库服务器的负载比较低但CPU使用率很高,这时可以缓存计算好的结果( computed objects )和渲染后的网页模板(enderred templates)。    
3)利用memcached可以缓存session数据 、临时数据以减少对他们的数据库写操作。         
4)缓存一些很小但是被频繁访问的文件,图片这种大点儿的文件就由CDN(内容分发网络)来处理了;

不适用memcached的业务场景:

1)缓存对象的大小大于1MB,Memcached本身就不是为了处理庞大的多媒体(large media)和巨大的二进制块(streaming huge blobs)而设计的;                
2)key的长度大于250字符;                
3)虚拟主机不让运行memcached服务。 如果应用本身托管在低端的虚拟私有服务器上,像vmware, xen这类虚拟化技术并不适合运行memcached。Memcached需要接管和控制大块的内存,如果memcached管理的内存被OS或 hypervisor交换出去,memcached的性能将大打折扣。    
4)应用运行在不安全的环境中。Memcached为提供任何安全策略,仅仅通过telnet就可以访问到memcached。如果应用运行在共享的系统上,需要着重考虑安全问题。    
5)业务本身需要的是持久化数据或者说需要的应该是database。

三、Memcached的内存管理

Memcached有一个很有特色的内存管理方式,为了提高效率,它使用预申请和分组的方式管理内存空间,而并不是每次需要写入数据的时候去malloc,删除数据的时候free一个指针。Memcached使用slab->chunk的组织方式管理内存。

注:1.1和1.2的slabs.c中的slab空间划分算法有一些不同

Slab可以理解为一个内存块,一个slab是memcached一次申请内存的最小单位,在memcached中,一个slab的大小默认为1048576字节(1MB),所以memcached都是整MB的使用内存。每一个slab被划分为若干个chunk,每个chunk里保存一个item,每个item同时包含了item结构体、key和value(注意在memcached中的value是只有字符串的)。slab按照自己的id分别组成链表,这些链表又按id挂在一个slabclass数组上,整个结构看起来有点像二维数组。slabclass的长度在1.1中是21,在1.2中是200。

使用slabs来管理内存,内存被分成大小不等的slabs chunks(先分成大小相等的slabs,然后每个slab被分成大小相等的chunks,不同slab的chunk大小是不相等的)。chunk的大小依次从一个最小数开始,按某个因子增长,直到达到最大的可能值。

如果最小值为400B,最大值为1MB,因子是1.20,各个slab的chunk的大小依次是:slab1-400B slab2-480B slab3-576B.....

slab中chunk越大,它和前面的slab之间的间隙就越大。因此,最大值越大,内存利用率越低。Memcached必须为每个slab预先分配内存,因此如果设置了较小的因子和较大的最大值,会需要更多的内存。

关于Memcached的介绍可以参考:http://www.cnblogs.com/sunniest/p/4437806.html

http://www.cnblogs.com/rollenholt/p/3381429.html

四、Memcached的内存算法

在开始之前,有必要先了解几个基本概念:

1、slab class:在memcached中,对元素的管理是以slab为单元进行管理的。每个slab class对应一个或多个空间大小相同的chunk,如下图所示:

图一  slab class逻辑结构图

2、chunk:存放元素的最小单元。用户数据item(key、value等)最终会保存在chunk中。memcached会根据元素大小将其放到合适的slab class中。每一个slab class中的chunk空间大小是一样的,所以元素存放进来后,chunk可能会有部分空间剩余。参考下图二、下图三。

图二  元素存入memcached会寻找最合适的slab class

3、page:大小固定为1MB。当slab class空间不足时,就会申请page,并将page按chunk的大小进行切割。

图三 元素放入chunk时可能会有空间浪费

启动memcached时,以-m指定大小的内存将会用于数据的存放。默认情况下,这些内存会被分隔成1M的page。每个page在必要时分配给slab class,然后根据slab class里chunk的大小,将page分隔成chunk。一旦一个page被赋给一个slab class后,它将不会再被移动。因为内存空间有限,如果在slab class 3中使用了较多的page,那么在slab class 4中就只能使用较少的page。可以这么认为,memcached是一个有很多更小的相互独立的缓存系统,每一个更小的缓存系统实际上就是slab class。每个slab class都有它自己的统计信息以及自己的LRU。

在启动memcached时,指定-vv参数,可以在启动日志中查看每个slab class的chunk大小。

在slab class 1中,每个chunk大小为80字节,每个页面包含13107个chunk(或item)。这两个数相乘,应该最近接1个page的大小(默认是1MB)。

当存储元素时,它们将被放到最合适的slab class中。例如,50字节的元素(包含key、value等信息)将被存放到slab class 1中的chunk,根据之前的说明,此chunk中将会有30字节的空间浪费。如果存放数据总共有90字节,将被存放到slab class 2中,此时会有14字节的空间浪费。

启动时,通过设置参数-f,可以设置每个slab class下chunk的空间增长率。

另外,memcached因为一些其他功能也会使用内存空间。例如:用来查找元素的hash table;连接时也会使用一些缓存。当然,这些功能只会占用很少一部分内存空间。

内存什么时候被回收

与redis不同的是,memcached不会主动回收内存。

如果获取了一个已失效的元素,memcached将会释放内存。后续再将新的元素存放进来时,将会重用此内存(前提是新元素也是要存放在同一slab class中)。由于LRU,元素将被踢出以让给新的元素,或发现有过期的元素,它们的内存将被重用。

五、Memcached的缓存策略

Memcached的缓存策略是LRU+到期失效策略。当你在Memcached内存存储数据项时,你有可能会指定它的缓存的失效时间,默认为永久。当Memcached服务器用完分配的内存时,失效的数据被首先替换,然后也是最近未使用的数据。在LRU中,Memcached使用的是一种Lazy Expiration策略,自己不会监控存入的key/value对是否过期,而是在获取key值时查看记录的时间戳,检查key/value对空间是否过期,这样可减轻服务器的负载。mcached

六、Memcached的分布式算法

当向Memcached集群存入/取出key/value时,memcached客户端程序根据一定的算法计算存入哪台服务器,然后再把key/value值存到此服务器中,也就是说,存取数据分二步走,第一步:选择服务器;第二步:存取数据.

假设memcached服务器有node1~node3三台, 应用程序要保存键名为"tokyo","kanagawa","chiba","saitama","gunma" 的数据.

图1 分布式简介:准备

首先向memcached中添加"tokyo"。将"tokyo"传给客户端程序库后, 客户端实现的算法就会根据"键"来决定保存数据的memcached服务器。服务器选定后,即命令它保存"tokyo"及其值。

同样,"kanagawa","chiba","saitama","gunma"都是先选择服务器再保存。

接下来获取保存的数据。获取时也要将要获取的键“tokyo”传递给函数库.函数库通过与数据保存时相同的算法,根据"键"选择服务器.使用的算法相同,就能选中与保存时相同的服务器,然后发送get命令.只要数据没有因为某些原因被删除,就能获得保存的值。

这样,将不同的键保存到不同的服务器上,就实现了memcached的分布式。 memcached服务器增多后,键就会分散,即使一台memcached服务器发生故障无法连接,也不会影响其他的缓存,系统依然能继续运行。

缓存系统中应用比较多的是余数计算分散和一致性 HASH 计算分散。

余数计算法:余数计算分散法简单来说,就是 "根据服务器台数的余数进行分散 " 。

1、求得传入键的整数哈希值( int hashCode );

2、使用计算出的 hashCode 除以服务器台数 (N) 取余数( C=hashCode % N );

3、在 N 台服务器中选择序号为 C 的服务器

余数计算的方法简单,数据的分散性也相当优秀,但也有其缺点。 那就是当添加或移除服务器时,缓存重组的代价相当巨大。 添加服务器后,余数就会产生巨变,这样就无法获取与保存时相同的服务器,从而影响缓存的命中率。

散列算法:在一个大的数据范围内的构建一个虚拟的环,首( 0 )尾(Integer.MAXVALUE )相接的圆环,然后通过某种 HASH算法增加虚拟节点的方式( 1 个实体节点可以虚拟 N个虚拟阶段,如 160 , 200 , 1000 等)让节点更为均匀的分别在环上。 KEY 请求的时候,也通过相同的某种HASH 算法 计算出 HASH 值,然后在在到环上定位同向最接近的虚拟节点,最后通过虚拟节点与实体节点的对应关系找到服务的实体节点。

散列算法请参见:http://blog.csdn.net/sparkliang/article/details/5279393

Memcached原理的更多相关文章

  1. Memcached原理与应用

    Memcached原理与应用 标签: linux 笔者Q:972581034 交流群:605799367.有任何疑问可与笔者或加群交流 1.Memcached是什么 高性能 支持高并发 分布式内存缓存 ...

  2. Memcached原理分析

    Memcached的内存管理方式 Memcached采用了名为Slab Allocation的机制分配,管理内存. Slab Allocation的原理相当简单.将分配的内存分割成各种尺寸的块(chu ...

  3. memcached原理全面剖析

    memcached会预先分配内存,memcached分配内存方式称之为allocator, 首先,这里有3个概念: 1 slab 2 page 3 chunk 一般来说一个memcahced进程会预先 ...

  4. memcached原理及介绍

    memcached是一种缓存技术,在存储在内存中(高性能分布式内存缓存服务器).目的 : 提速.(传统的都是把数据保存在关系型数据库管理系统既RDBMS,客户端请求时会从RDBS中读取数据并在浏览器中 ...

  5. 详解MemCached原理

    memcached是一个高性能的分布式内存缓存服务器,memcached在Linux上可以通过yum命令安装,这样方便很多,在生产环境下建议用Linux系统,memcached使用libevent这个 ...

  6. Memcached原理深度分析详解

    Memcached是 danga.com(运营LiveJournal的技术团队)开发的一套分布式内存对象缓存系统,用于在动态系统中减少数据库负载,提升性能.关于这个东 西,相信很多人都用过,本文意在通 ...

  7. Memcached 原理

    memcached  是以一个守护进程的方式运行于一个服务器和多个服务器之间的,等待接受客户端的连接操作,客户端可以有各种语言编写.(例如PHP). php 在客户端与服务器建立连接以后,接下来的事情 ...

  8. 高性能的分布式内存对象缓存系统Memcached

    Memcached概述   什么是Memcached? 先看看下面几个概念: Memory:内存存储,不言而喻,速度快,对于内存的要求高,不指出的话所缓存的内容非持久化.对于CPU要求很低,所以常常采 ...

  9. windows下Memcached 架设及java应用

    1  Memcached 介绍   Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提供动态.数据 ...

随机推荐

  1. Web.config配置文件详解(新手必看)

    花了点时间整理了一下ASP.NET Web.config配置文件的基本使用方法.很适合新手参看,由于Web.config在使用很灵活,可以自定义一些节点.所以这里只介绍一些比较常用的节点. <? ...

  2. linux c/c++ GDB教程详解(转)

    http://www.gnu.org/manual/ http://www.gnu.org/software/gdb/documentation/ http://sourceware.org/gdb/ ...

  3. 谈谈分布式事务之一:SOA需要怎样的事务控制方式

    在一个基于SOA架构的分布式系统体系中,服务(Service)成为了基本的功能提供单元,无论与业务流程无关的基础功能,还是具体的业务逻辑, 均实现在相应的服务之中.服务对外提供统一的接口,服务之间采用 ...

  4. c#打印机设置,取得打印机列表及相应打印机的所有纸张格式

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  5. HDU-5391 Zball in Tina Town

    (n-1)!/n 就是如果n为素数,就等于n-1else为0. 求素数表: Zball in Tina Town Time Limit: 3000/1500 MS (Java/Others) Memo ...

  6. 【转】小解DCT与DFT

    这学期当本科生数字图像处理的助教老师,为使学生更好地理解DCF和DFT之间的关系给出三题,大家可以思考一下,看一下自己对这些最简单的变换是否真正理解. 1.求解序列f(n)=[2,3,3,4,4,3, ...

  7. [九度OJ]1431.Sort(寻找前m大数并排序)

    原题链接:http://ac.jobdu.com/problem.php?pid=1431 题目描述: 给你n个整数,请按从大到小的顺序输出其中前m大的数. 输入: 每组测试数据有两行,第一行有两个数 ...

  8. 常用oracle查询总结

    --查询表空间使用情况 SELECT UPPER(F.TABLESPACE_NAME) "表空间名", D.TOT_GROOTTE_MB "表空间大小(M)", ...

  9. cygwin设置中文

    cygwin\home\username\.bashrc # 让ls和dir命令显示中文和颜色 alias ls='ls --show-control-chars --color' alias dir ...

  10. java 访问权限控制

    java提供四种访问权限: public > protected > 包访问权限(无关键词) > private 包:库单元 对于包访问权限,一个包内的都可以访问. 在eclipse ...