一、产生背景

今天咱不去长篇大论特别详细地讲解consistent hash,我争取用最轻松的方式告诉你consistent hash算法是什么,如果需要深入,Google一下~。

举个栗子吧:

比如有 N 个 cache 服务器,需要将一个object 映射到 N 个 cache 上,我们可以用类似下面的方法计算 object 的 hash 值,然后均匀的映射到到 N 个 cache 上:

hash(object)%N

比如object是“hello”,hash(object)是100,N为3,100%3=1,这个数据会被存到第1个cache上(0、1、2三个cache)。这样就能解决一堆数据放到N个cache上的问题。

现在有个突发情况,0、1、2三个cache中1损坏了!

怎么办呢,cache 1上的数据首先需要迁移,可用cache数量变为2,这个时候我们需要重新计算所有数据的hash值,上面的公式变成了这样:

hash(object)%(N-1)

这次重新计算意味着每一份数据hash之后的结果几乎都变了!也就是意味着在cache系统中会发生大规模cache失效,数据访问会直接冲击cache后面的服务器,好玩了,崩了。

咋个办呢,consistent hash出现了!

二、算法原理

  consistent hash简单的说,就是要在cache数量变化时,能够尽可能小的改变已存在 key 映射关系,也就是增加一个cache或者减少一个cache服务器,对已经存在的缓存数据不要产生大影响。怎么做到呢,,,

  我们先想象一条链子,第一个格子是0,最后一个格子是2^32-1,这条链子就是一个地址空间为2^32的hash值空间,现在将链子首位相连,组成一个ring,就像下面这样(这里画图太麻烦了,下面的环环相关的图来自互联网,侵删吧):

  然后考虑我们由object1~object4这样四个数据,通过hash算法后映射到这个ring上【类似这样:hash(object1)=key1】

  这里应该很好理解,4个数据得到4个key,接下来我们要将cache服务器也映射到这个ring上,假设由3个cache服务器,分别是cache A、cache B、cache C,然后用hash算法:hash(cache A)=key A,将3个cache服务器丢到这个ring上,就可用得到如下结果(计算cache服务器的hash值时可以用其ip等信息):

  然后顺着这个ring,收集object数据,遇到cache的时候就丢进去,这样就可以将数据和cache对应起来,于是我们可以得到如下结果:

object1:Cache A

object4:Cache B

object2/object3: Cache C

  ok,这样就完成了数据映射,然后我们考虑一下前面普通hash算法遇到的cache服务器数量变化的情况,看一下ring hash是否解决了这个问题。

  假设cache B掉线

  这个时候可以发现只有原先映射到Cache B上的object4收到了影响,需要转移到Cache C上。

  如果增加一个Cache结点呢?假设增加一个Cache D:

  这个时候只需要将object2转移到Cache D上,其他的没有变化。是不是很神奇?

  这里可能大家会意识到一个问题,当cache服务器数量少的时候,这个算法很容易导致数据分布不均匀,所以ring hash中还有一个虚拟节点的概念,前面只剩下cache A和cache C的例子中A上有1个数据,而C中存了3个,我们将cache(假设用ip值表示)加上一个编号,然后进行hash运算,得到更多的虚拟cache结点:

hash("192.168.0.1#1")

hash("192.168.0.1#2")

hash("192.168.0.2#1")

hash("192.168.0.2#2")

  类似上面这样,一个cache服务器就对应了2个hash值,这样我们再丢到ring上就会得到如下结果:

  这时候object1就会落在Cache A2上,object2会落在Cache A1上,物理上其实A1和A2都是cache A,通过这种方式直观看我们将原先的1、3分布变成了2、2分布(A上1个数据C上3个数据变成A上2个数据B上2个数据)

  引入“虚拟节点”后,映射关系就从 { 对象 -> 节点 } 转换到了 { 对象 -> 虚拟节点 },于是乎这个算法的平衡性就更好了。

  ok,一致性hash算法的原理就介绍到这里,下面可以看groupcahce中的consistent hash如何实现了。

三、groupcache中的consistent hash

  终于要看代码了!!!

  源码主要就如下几个package,今天我们看一下第一个package:【package consistenthash】的内容

  从上图我们可以看到,这里只需要关注consistenthash.go这源码文件,里面有2个类型:Hash和Map,1个函数New,Map类型有4个不可导出的属性以继3个绑定的方法。

下面一个个看吧~

  1、类型Hash(需要记得Hash是一个函数类型哦)。

  2、Map类型(Map类型的第一个属性就是上面的Hash类型变量hash,replicas属性表示的是副本数,还记得上面我们提到的为了解决平衡性问题而引入的虚拟节点的概念吗?这些虚拟节点这是这里描述的副本数)。

  3、New()函数(这个函数明显就是用来获取上面的Map类型变量实例的,初始化副本数、hash函数、hashMap表,hashMap表的key是一个表示cache服务器或者副本的hash值,value为一个具体的cache服务器,这样就完成了Cache A、Cache A1、Cache A2等副本全部映射到Cache A的功能。

  4、IsEmpty()函数(这个函数就没啥可讲的了,非空判断)

  5、Add()函数(将缓存服务器加到Map中,比如Cache A、Cache B作为keys,如果副本数指定的是2,那么Map中存的数据是Cache A#1、Cache A#2、Cache B#1、Cache B#2的hash结果)

  6、Get()函数(这个函数相对复杂一点,比如有一个数据:name="张三"这条数据需要存,这时候通过这个函数选择一个cache服务器,返回的string类型可以是服务器ip,比如:"192.168.0.1",从而调用者能够将name="张三"存到"192.168.0.1"上)

  ok,讲完了,今天的内容有点多,可能需要多花点时间消化一下~

  下一讲我们介绍groupcachepb这个package,当然不可避免地要介绍一下Protocol Buffers了,行,今天就讲到这里!

consistent hash(一致性哈希算法)的更多相关文章

  1. hash环/consistent hashing一致性哈希算法

        一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法,设计目标是为了解决因特网中的热点(Hot spot)问题,初衷和CARP十分类似.一致性哈希修正了CARP使用的 ...

  2. 一致性哈希算法(consistent hashing)(转)

    原文链接:每天进步一点点——五分钟理解一致性哈希算法(consistent hashing)  一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法,设计目标是为了解决因特网 ...

  3. 一致性哈希算法学习及JAVA代码实现分析

    1,对于待存储的海量数据,如何将它们分配到各个机器中去?---数据分片与路由 当数据量很大时,通过改善单机硬件资源的纵向扩充方式来存储数据变得越来越不适用,而通过增加机器数目来获得水平横向扩展的方式则 ...

  4. _00013 一致性哈希算法 Consistent Hashing 新的讨论,并出现相应的解决

    笔者博文:妳那伊抹微笑 博客地址:http://blog.csdn.net/u012185296 个性签名:世界上最遥远的距离不是天涯,也不是海角,而是我站在妳的面前.妳却感觉不到我的存在 技术方向: ...

  5. 一致性哈希算法(Consistent Hashing Algorithm)

    一致性哈希算法(Consistent Hashing Algorithm) 浅谈一致性Hash原理及应用   在讲一致性Hash之前我们先来讨论一个问题. 问题:现在有亿级用户,每日产生千万级订单,如 ...

  6. 一致性哈希算法(Consistent Hashing) .

    应用场景 这里我先描述一个极其简单的业务场景:用4台Cache服务器缓存所有Object. 那么我将如何把一个Object映射至对应的Cache服务器呢?最简单的方法设置缓存规则:object.has ...

  7. 转 白话解析:一致性哈希算法 consistent hashing

    摘要: 本文首先以一个经典的分布式缓存的应用场景为铺垫,在了解了这个应用场景之后,生动而又不失风趣地介绍了一致性哈希算法,同时也明确给出了一致性哈希算法的优点.存在的问题及其解决办法. 声明与致谢: ...

  8. 分布式_理论_08_Consistent Hash(一致性哈希算法)

    一.前言 五.参考资料 1.分布式理论(八)—— Consistent Hash(一致性哈希算法)

  9. 一致性哈希算法(consistent hashing)PHP实现

    一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法,设计目标是为了解决因特网中的热点(Hot spot)问题,初衷和CARP十分类似.一致性哈希修正了CARP使用的简单哈希 ...

随机推荐

  1. 我的 FPGA 学习历程(10)—— 实验:数码管驱动

    根据黑金 AX301 手册,数码管位选信号命名为 SEL[5:0],其中 SEL[5] 对应最左边的数码管,而SEL[0] 对应最右边数码管:作为约定,在下面的描述中我们对应的称之为数码管 5 和数码 ...

  2. input标签实现小数点后两位保留小数

    短短一行代码就可以实现 <input type="number" min="0" max="100" step="0.01& ...

  3. IIS 设置

    解决办法:1. 1).通过webconfig中增加模拟,加入管理员权限, <identity impersonate="true" userName="系统管理员& ...

  4. SpringBoot几种定时任务的实现方式

    定时任务实现的几种方式: Timer:这是java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务.使用这种方式可以让你的程序按照某一个频度执行, ...

  5. node01

    ---恢复内容开始--- 1.node初体验 安装完成node,写好相应的js代码后,在cmd中node 文件名即可完成编译执行过程. 2.尝试使用node搭建一个简单服务器 //引入http模块 c ...

  6. django+javascrpt+python实现私有云盘代码

    丁丁:由于篇幅有限,这里暂时只展示python后端代码,前端js代码后面上传,有需要的也可以留言私信我. 1.view.py 使用用户.部门.公司等相关账号的创建,已经个人,部门账号的冻结,删除,相关 ...

  7. [LeetCode] Find And Replace in String 在字符串中查找和替换

    To some string S, we will perform some replacement operations that replace groups of letters with ne ...

  8. 判断js中的数据类型的几种方法

    判断js中的数据类型有一下几种方法:typeof.instanceof. constructor. prototype. $.type()/jquery.type(),接下来主要比较一下这几种方法的异 ...

  9. Windows下SQLMAP的安装图解

    第一步:BurpSuite扫描工具安装 //来源:http://www.mamicode.com/info-detail-563355.html Burp Suite 是用于渗透测试web 应用程序的 ...

  10. python 中间件

    中间件一.什么是中间件 中间件是一个用来处理Django的请求和响应的框架级别的钩子.它是一个轻量.低级别的插件系统,用于在全局范围内改变Django 的输入和输出.每个中间件组件都负责做一些特定的功 ...