memcached 是一个”分布式缓存”,然后 memcached 并不像 mongoDB 那 样,允许配置多个节点,且节点之间”自动分配数据”. 就是说--memcached 节点之间,是不互相通信的. 因此,memcached 的分布式,要靠用户去设计算法,把数据分布在多个 memcached 节点中.

2 分布式之取模算法

最容易想到的算法是取模算法,即 N 个节点要,从 0->N-1 编号. key 对 N 取模,余 i,则 key 落在第 i 台服务器上

取模算法对缓存命中率的影响 假设有 8 台服务器, 运行中,突然 down 一台, 则求余的底数变成 7

后果:

一般地,我们从数学上归纳之: 有 N 台服务器, 变为 N-1 台, 每 N*(N-1)个数中, 只有(n-1)个单元,%N, %(N-1)得到相同的结果

所以 命中率在服务器 down 的短期内, 急剧下降至 (N-1)/(N*(N-1)) = 1/(N-1) 所以: 服务器越多, 则 down 机的后果越严重!

3 一致性哈希算法原理

通俗理解一致性哈希: 把各服务器节点映射放在钟表的各个时刻上, 把 key 也映射到钟表的某个时刻上. 该 key 沿钟表顺时针走,碰到的第 1 个节点即为该 key 的存储节点

疑问 1: 时钟上的指针最大才 11 点,如果我有上百个 memcached 节点怎么办?

答: 时钟只是为了便于理解做的比喻,在实际应用中,我们可以在圆环上分布[0,2^32-1]的数字, 这样,全世界的服务器都可以装下了.

疑问 2: 我该如何把”节点名”,”键名”转化成整数?

答: 你可以用现在的函数,如 crc32(). 也可以自己去设计转化规则,但注意转化后的碰撞率要低. 即不同的节点名,转换为相同的整数的概率要低.

一致性哈希对其他节点的影响

通过上图 可以看出,当某个节点 down 后,只影响该节点顺时针之后的 1 个节点,而其他节点 不受影响.因此,

Consistent Hashing 最大限度地抑制了键的重新分布

一致性哈希+虚拟节点对缓存命中率的影响

由图 第一个图中可以看到,理想状态下,

1) 节点在圆环上分配分配均匀,因此承担的任务也平均,但事实上, 一般的 Hash 函数对于节 点在圆环上的映射,并不均匀.

2) 当某个节点 down 后,直接冲击下 1 个节点,对下 1 个节点冲击过大,能否把 down 节点上的 压力平均的分担到所有节点上?

完全可以---引入虚拟节点来达到目标 上图 虚拟节点即----N 个真实节点,把每个真实节点映射成 M 个虚拟节点, 再把 M*N 个虚拟节点,

散列在圆环上. 各真实节点对应的虚拟节点相互交错分布 这样,某真实节点 down 后,则把其影响平均分担到其他所有节点上.

一致性哈希的 PHP 实现

/* 实现一致性哈希分布的核心功能. */

// 需要一个把字符串转成整数的接口

interface hasher {

public function _hash($str);

}

interface distribution {

public function lookup($key);

}

class Consistent implements hasher,distribution {

protected $_nodes = array();

protected $_postion = array();

protected $_mul = 64; //每个节点对应 64 个虚节点

public function _hash($str) {

return sprintf('%u',crc32($str)); // 把字符串转成 32 位符号整数

}

// 核心功能

public function lookup($key) {

$point = $this->_hash($key);

$node = current($this->_postion); //先取圆环上最小的一个节点,当 成结果

foreach($this->_postion as $k=>$v) {

if($point <= $k) {

$node = $v; break;

}

}

reset($this->_postion);

return $node;

}

public function addNode($node) {

if(isset($this->nodes[$node])) {

return;

} for($i=0; $i<$this->_mul; $i++) {

$pos = $this->_hash($node . '-' . $i);

$this->_postion[$pos] = $node; $this->_nodes[$node][] = $pos;

} $this->_sortPos();

} // 循环所有的虚节点,谁的值==指定的真实节点 ,就把他删掉

public function delNode($node) {

if(!isset($this->_nodes[$node])) {

return;

}

foreach($this->_nodes[$node] as $k) {

unset($this->_postion[$k]);

} unset($this->_nodes[$node]);

}

protected function _sortPos() {

ksort($this->_postion,SORT_REGULAR);

}

} // 测试

$con = new Consistent();

$con->addNode('a');

$con->addNode('b');

$con->addNode('c');

$key = 'www.zixue.it';

echo '此 key 落在',$con->lookup($key),'号节点';

以上可以看出

取模哈希算法,简单快速,缺点是在 memcached 节点增加或者删除的时候,原有的缓存数 据将大规模失效,命中率大受影响,如果节点数多,缓存数据多,重建缓存的代价太高。

一致性哈希算法, 最大限度地减小服务器增减时的缓存重新分布。

分布式集群算法 memcached 如何实现分布式?的更多相关文章

  1. memcached整理の分布式集群算法

    memcached如何实现分布式? memcached是一个“分布式内存对象缓存系统”,然而memcached并不像mongodb那样,允许配置多个节点,且节点之间“自动分配数据”,就是说memcac ...

  2. 基于HBase0.98.13搭建HBase HA分布式集群

    在hadoop2.6.0分布式集群上搭建hbase ha分布式集群.搭建hadoop2.6.0分布式集群,请参考“基于hadoop2.6.0搭建5个节点的分布式集群”.下面我们开始啦 1.规划 1.主 ...

  3. Hadoop教程(五)Hadoop分布式集群部署安装

    Hadoop教程(五)Hadoop分布式集群部署安装 1 Hadoop分布式集群部署安装 在hadoop2.0中通常由两个NameNode组成,一个处于active状态,还有一个处于standby状态 ...

  4. kafka系列一:单节点伪分布式集群搭建

    Kafka集群搭建分为单节点的伪分布式集群和多节点的分布式集群两种,首先来看一下单节点伪分布式集群安装.单节点伪分布式集群是指集群由一台ZooKeeper服务器和一台Kafka broker服务器组成 ...

  5. 2020重新出发,NOSQL,MongoDB分布式集群架构

    MongoDB分布式集群架构 看到这里相信你已经掌握了 MongoDB 的大部分基本知识,现在在单机环境下操作 MongoDB 已经不存在问题,但是单机环境只适合学习和开发测试,在实际的生产环境中,M ...

  6. Memcached 分布式集群

    首先解释一下我的标题,用到了 分布式 和 集群两个单词,为什么是集群?解决[相同业务]问题的服务器多个以上就称为集群.这里memcached就是做相同任务的(提供缓存服务)为什么是分布式?虽然针对的是 ...

  7. Redis面试题及分布式集群

    Reference: http://blog.csdn.net/yajlv/article/details/73467865 1. 使用Redis有哪些好处? (1) 速度快,因为数据存在内存中,类似 ...

  8. Redis分布式集群几点说道

    原文地址:http://www.cnblogs.com/verrion/p/redis_structure_type_selection.html  Redis分布式集群几点说道 Redis数据量日益 ...

  9. redis高可用分布式集群

    一,高可用 高可用(High Availability),是当一台服务器停止服务后,对于业务及用户毫无影响. 停止服务的原因可能由于网卡.路由器.机房.CPU负载过高.内存溢出.自然灾害等不可预期的原 ...

随机推荐

  1. Ruby IO类

    更新: 2017/06/23   表格大小全部改为100%                             文件输入输出的File....系列函数的文件名参数是字符串! 更新: 2017/06 ...

  2. bzoj 3875: [Ahoi2014&Jsoi2014]骑士游戏【dp+spfa】

    设f[i]为杀死i的最小代价,显然\( f[i]=min(k[i],s[i]+\sum f[to]) \) 但是这个东西有后效性,所以我们使用spfa来做,具体就是每更新一个f[i],就把能被它更新的 ...

  3. poj 2396 Budget【有上下界的网络流】

    第一步:建立无源汇有上下界的网络模型 每行 i 作为一个点并连边(s, i, Ri, Ri),每列 j 作为一个点并连边(j, t, Cj, Cj),设 Uij, Lij 分别表示第 i 行第 j 列 ...

  4. ES6 我的总结学习

    1 let 和 const let 的作用域与 const 命令相同:只在声明所在的块级作用域内有效.且不存在变量提升 . 1.1 let let 所声明的变量,可以改变. let a = 123 a ...

  5. react hooks 全面转换攻略(三) 全局存储解决方案

    针对 react hooks 的新版本解决方案 一.redux维持原方案 若想要无缝使用原来的 redux,和其配套的中间件 promise,thunk,saga 等等的话 可以使用 redux-re ...

  6. pyinstaller打包.py程序为.exe操作指南

    pyinstaller打包.py程序为.exe操作指南 20190526内容纲要: 1.pyinstaller安装 2.程序封装 3.可执行程序 0 前言 今天第一次试试将一个py程序封装成一个.ex ...

  7. bzoj2333[SCOI2011]棘手的操作 洛谷P3273 [SCOI2011]棘手的操作

    2333? 先记一下吧,这题现在全部都是照着题解做的,因为怎么改都改不出来,只好对着题解改,以后还要再做过 以后再也不用指针了!太恶心了!空指针可不止直接特判那么简单啊,竟然还要因为空指针写奇怪的分类 ...

  8. 题解报告:hdu1219AC Me

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1219 Problem Description Ignatius is doing his homewo ...

  9. AFNetworking2.5使用-转

    来自:http://blog.csdn.net/daiyelang/article/details/38434023 官网下载2.5版本:http://afnetworking.com/ 此文章是基于 ...

  10. ASP.NET URLRewriter重写

    URLRewriter重写是微软官方出的第三方重写插件 下载地址:http://download.csdn.net/detail/ysn1314/5421587 下载后在项目中添加引用,然后再配置文件 ...