Memcached 小探

Why use Memcached ?

随着互联网发展, 日益增长的互联网用户已经业务扩展需求, 传统关系数据库 (如Mysql) 开始出现瓶颈:

1) 对数据库高并发读写。

2)海量数据的处理。

对于Mysql来说, 作为一个关系型数据库本来就是一个庞然大物, 其处理过程非常复杂和耗时, 如sql解释, 事务处理等。当单张表出现数据量大于千万的时候, 无论如何都很难再通过自身的性能(如建立索引)去优化数据查询。 使用Nosql缓存(如本文提到的Memcached,当然还有Redis等)能够很好的解决这个问题。大多数Web应用的瓶颈在数据库访问 


Features of Memcached 

Memcached有如下特点:

1) 基于libevent 的事件处理 (所以在安装前要确保libevent依赖库已经安装)

2) 追求速度和高性能, 储存数据与内存中。所以需要注意储存的对象非永久, 服务停止后, 数据丢失。

3) 支持分布式, 但服务器端互相不通信, 需要依赖客户端算法实现。


Memcached : Distributed

上文已经提到, Memcached服务器支持分布式, 但是其分布式的算法是有客户端实现的。已 PHP 的 memcached 客户端为例,它内置的分布式算法有两种, 一种是简单通俗的取模运算或者说余数分步法,Hash(Key) % m ,m 为已经有的Memcached服务器数量,这也是默认采用的一种算法。 但去取模算法有一个明显的弊端就是,在增删节点的时候, 会导致数据重新分布,命中率会严重下降。


除了取模运算, 另外一种算法叫做一致性哈希算法 (Consistent Hashing)。它原理是将一个32位整数想象成一个已0作为环头,2的32次方-1为环尾的一个圆环。首先将服务器节点通过Hash以后投射到环中

$server1 = myHash("192.168.3.135");
$server2 = myHash("192.168.3.136");

然后再讲需要存取的Key用同样的Hash算法投射到环中。


$key1= myHash("aaa");
$key2 = myHash("bbb");

这样我们把数据的key和服务器都映射到同一个环上(一个想象的圆环)。沿着圆环顺时针方向的key出发,直到遇到同一个服务器为止,然后把数据保存到该服务器节点上。一致性哈希算法可以有效的避免在增删减点时的数据重新分布,保证了命中率。


在php memcached客户端开启的方法如下:


   
    setOption(Memcached::OPT_DISTRIBUTION, Memcached::DISTRIBUTION_CONSISTENT);

/* 
 * 开启或关闭兼容的libketama类行为。当开启此选项后,元素key的hash算法将会被设置
 * 为md5并且分布算法将会 采用带有权重的一致性hash分布。
 * 这一点非常有用因为其他基于libketama的客户端(比如python,urby)在同样 的服务
 * 端配置下可以透明的访问key。
 *
 */
$mc -> setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true);

$mc->addServer("192.168.3.135", 11211);
$mc->addServer("192.168.3.136", 11211);

?>

谈到这里, 可能有人会问究竟如何将Key (大部分时间是String 形式存在)或者服务器节点跟32位整型数据 (上面想象的圆环)联系起来? 这就是上面代码块中我们用到的myHash算法函数,在一致性哈希分布式算法中我们通常用的哈希算法是DJBX33A算法。

DJBX33A算法,也就是time33算法(学院里有专门条目介绍了),是APR默认哈希算法,php, apache, perl, bsddb也都使用time33哈希。对于33这个数,DJB注释中是说,1到256之间的所有奇数,都能达到一个可接受的哈希分布,平均分布大概是86%。而其中33,17,31,63,127,129这几个数在面对大量的哈希运算时有一个更大的优势,就是这些数字能将乘法用位运算配合加减法替换,这样运算速度会更高。gcc编译器开启优化后会自动将乘法转换为位运算。 

分享下我用PHP实现的time33算法


   
   

Some Highlights

Memcached有如下注意点:

1) 存储key的长度有限制,php和C的最大长度都是250.

2) 最大存储 Value 的大小限制为1M,这由slab页大小1M限制 (修改源码可以打破这个限制)

3) 在服务器集群中,要实现memcached之间的数据拷贝需要借助第三方插件来支持(i.e. Magent)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值