memcached初探

      一般的web应用,我们直接从数据库取数据.但是随着数据的增多,访问量的增大,数据库的响应变慢,网站延迟等现象就会出现.此刻是memcached大显身手的时候了,memcached是高性能的分布式内存缓存服务器。通过它把数据缓存起来,从而减少对数据库的访问次数,以提高Web应用的响应速度、提高可扩展性。

    这次主要对memcached的基本特性加以了解,以便在以后的项目中更好的利用它.

    1. memcached大体认识

        Memcached是一个基于存储键/值对的hashmap。其守护进程(daemon )是用C写的,但是 客户端 可以用任何语言来编写,并通过memcached协议与守护进程通信。但是它并不提供冗余(例如,复制其hashmap条目);当某个服务器S停止运行或崩溃了,所有存放在S上的键/值对都将丢失。

   2. memcached的存储机制

      最近的memcached默认情况下采用了名为Slab Allocator的机制分配、管理内存。在该机制出现以前,内存的分配是通过对所有记录简单地进行malloc和free来进行的。但是,这种方式会导致内存碎片,加重操作系统内存管理器的负担,最坏的情况下,会导致操作系统比memcached进程本身还慢。Slab Allocator就是为解决该问题而诞生的。

Slab Allocation的原理相当简单。将分配的内存分割成各种尺寸的块(chunk),并把尺寸相同的块分成组(chunk的集合)如下图:
   

 

而且,slab allocator还有重复使用已分配的内存的目的。也就是说,分配到的内存不会释放,而是重复利用。

memcached根据收到的数据的大小,选择最适合数据大小的slab。memcached中保存着slab内空闲chunk的列表,根据该列表选择chunk,然后将数据缓存于其中。如下图:



Slab Allocator解决了当初的内存碎片问题,但新的机制也给memcached带来了新的问题。
这个问题就是,由于分配的是特定长度的内存,因此无法有效利用分配的内存。例如,将100字节的数据缓存到128字节的chunk中,剩余的28字节就浪费了。如下图:



如果预先知道客户端发送的数据的公用大小,或者仅缓存大小相同的数据的情况下,只要使用适合数据大小的组的列表,就可以减少浪费。所以,我们需要根据我们要存储的内容,来调节缓存块的大小。这个块的大小 memcached 有个默认值。
memcached在启动时指定Growth Factor因子(通过-f选项),就可以在某种程度上控制slab之间的差异。默认值为1.25。
让我们用以前的设置,以verbose模式启动memcached试试看:
$ memcached -f 2 -vv
下面是启动后的verbose输出:
slab class 1: chunk size 128 perslab 8192
slab class 2: chunk size 256 perslab 4096
slab class 3: chunk size 512 perslab 2048
slab class 4: chunk size 1024 perslab 1024
slab class 5: chunk size 2048 perslab 512
slab class 6: chunk size 4096 perslab 256
slab class 7: chunk size 8192 perslab 128
slab class 8: chunk size 16384 perslab 64
slab class 9: chunk size 32768 perslab 32
slab class 10: chunk size 65536 perslab 16
slab class 11: chunk size 131072 perslab 8
slab class 12: chunk size 262144 perslab 4
slab class 13: chunk size 524288 perslab 2
可见,从128字节的组开始,组的大小依次增大为原来的2倍。这样设置的问题是,slab之间的差别比较大,有些情况下就相当浪费内存。 因此,为尽量减少内存浪费,两年前追加了 growth factor 这个选项。
来看看现在的默认设置(f=1.25)时的输出
slab class 2: chunk size 112 perslab 9362
slab class 3: chunk size 144 perslab 7281
slab class 4: chunk size 184 perslab 5698
slab class 5: chunk size 232 perslab 4519

3. memcached 删除机制
      memcached是缓存,所以数据不会永久保存在服务器上,但数据不会真正从memcached中消失,memcached不会释放已分配的内存。记录超时后,客户端就无法再看见该记录(invisible,透明),其存储空间即可重复使用。
memcached内部不会监视记录是否过期,而是在get时查看记录的时间戳,检查记录是否过期。这种技术被称为lazy(惰性)expiration。因此,memcached不会 在过期监视上耗费CPU时间

memcached会优先使用已超时的记录的空间,但即使如此,也会发生追加新记录时空间不足的情况,此时就要使用名为Least Recently Used(LRU)机制来分配空间。顾名思义,这是删除“最近最少使用”的记录的机制。因此,当memcached的内存空间不足时),就从最近未被使用的记录中搜索,并将其空间分配给新的记录。
不过,有些情况下LRU机制反倒会造成麻烦。memcached启动时通过“M”参数可以禁止LRU,如下所示:
memcached -M -m 1024

启动时必须注意的是,小写的“m”选项是用来指定最大内存大小的。不指定具体数值则使用默认值64MB。
指定“M”参数启动后,内存用尽时memcached会返回错误。话说回来,memcached毕竟不是存储器,而是缓存,所以 推荐使用LRU 。不过还是要看具体怎么来使用 memcached 了。

4. memcached分布式机制
   memcached虽然称为“分布式”缓存服务器,但服务器端并没有“分布式”功能。服务器端仅包括内存存储功,其实现非常简单。至于memcached的 分布式,则是完全由客户端程序库实现的. memcached的分布式方法一般有
   1.根据余数计算使用哪台机器
      简单来说,就是“根据服务器台数的余数进行分散”。求得键的整数哈希值,再除以服务器台数,根据其余数来选择服务器。余数计算的方法简单,数据的分散性也相当优秀,但也有其缺点。那就是当添加或移除服务器时,缓存重组的代价相当巨大。添加服务器后,余数就会产生巨变,这样就无法获取与保存时相同的服务器,从而影响缓存的命中率
   2.一致性hash算法
       首先求出memcached服务器(节点)的哈希值,并将其配置到0~232 的圆(continuum)上。然后用同样的方法求出存储数据的键的哈希值,并映射到圆上。然后从数据映射到的位置开始顺时针查找,将数据保存到找到的第一个服务器上。如果超过232 仍然找不到服务器,就会保存到第一台memcached服务器上
  

 

       一致性hash算法最大限度地抑制了键的重新分布。而且,有的一致性hash算法的实现方法还采用了虚拟节点的思想。使用一般的hash函数的话,服务器的映射地点的分布非常不均匀。因此,使用虚拟节点的思想,为每个物理节点(服务器)在continuum上分配100~200个点。这样就能抑制分布不均匀,最大限度地减小服务器增减时的缓存重新分布

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值