consistent hash(一致性哈希算法)
一、产生背景
今天咱不去长篇大论特别详细地讲解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(一致性哈希算法)的更多相关文章
- hash环/consistent hashing一致性哈希算法
一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法,设计目标是为了解决因特网中的热点(Hot spot)问题,初衷和CARP十分类似.一致性哈希修正了CARP使用的 ...
- 一致性哈希算法(consistent hashing)(转)
原文链接:每天进步一点点——五分钟理解一致性哈希算法(consistent hashing) 一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法,设计目标是为了解决因特网 ...
- 一致性哈希算法学习及JAVA代码实现分析
1,对于待存储的海量数据,如何将它们分配到各个机器中去?---数据分片与路由 当数据量很大时,通过改善单机硬件资源的纵向扩充方式来存储数据变得越来越不适用,而通过增加机器数目来获得水平横向扩展的方式则 ...
- _00013 一致性哈希算法 Consistent Hashing 新的讨论,并出现相应的解决
笔者博文:妳那伊抹微笑 博客地址:http://blog.csdn.net/u012185296 个性签名:世界上最遥远的距离不是天涯,也不是海角,而是我站在妳的面前.妳却感觉不到我的存在 技术方向: ...
- 一致性哈希算法(Consistent Hashing Algorithm)
一致性哈希算法(Consistent Hashing Algorithm) 浅谈一致性Hash原理及应用 在讲一致性Hash之前我们先来讨论一个问题. 问题:现在有亿级用户,每日产生千万级订单,如 ...
- 一致性哈希算法(Consistent Hashing) .
应用场景 这里我先描述一个极其简单的业务场景:用4台Cache服务器缓存所有Object. 那么我将如何把一个Object映射至对应的Cache服务器呢?最简单的方法设置缓存规则:object.has ...
- 转 白话解析:一致性哈希算法 consistent hashing
摘要: 本文首先以一个经典的分布式缓存的应用场景为铺垫,在了解了这个应用场景之后,生动而又不失风趣地介绍了一致性哈希算法,同时也明确给出了一致性哈希算法的优点.存在的问题及其解决办法. 声明与致谢: ...
- 分布式_理论_08_Consistent Hash(一致性哈希算法)
一.前言 五.参考资料 1.分布式理论(八)—— Consistent Hash(一致性哈希算法)
- 一致性哈希算法(consistent hashing)PHP实现
一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法,设计目标是为了解决因特网中的热点(Hot spot)问题,初衷和CARP十分类似.一致性哈希修正了CARP使用的简单哈希 ...
随机推荐
- DWM1000 自动应答代码实现与实例
这一节继续继承之前帧过滤部分,首先补充一下关于帧过滤部分,如果将目标地址设置为0xFFFF,则同一个网络(物理频道与PANID 都相同),所有节点都应该收到这条信息,这个信息为广播信息,0xFFFF为 ...
- Vue中scoped css和css module比较
scoped css 官方文档 scoped css可以直接在能跑起来的vue项目中使用. 使用方法: <style scoped> h1 { color: #f00; } </st ...
- (转)protein 数据库
最早关注蛋白质互作网络,是在来GDMC第一年的时候,中间停了半年看互作-各种算法,网络分析停滞不前,没想到搞到最后,还是和网络碰到了一起,我总是会潜意识走近给自己第一印象不错的object,包括人.用 ...
- Unknown return value type [java.lang.Boolean]] with root cause
添加@responsebody 为什么呢 ? 因为在进行ajax传输的时候 我已指定传输的类型为 json数据类型 要是不加的话 它只是Boolean类型 而不是json类型
- HTTP Status 500 - Request processing failed; nested exception is org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)
今天整合ssm框架 时 遇到的问题 困扰我好长时间 原因就是 mapper文件 没有被加载进来 但是 为什么没有被加载进来呢 因为中间的配置文件出了一些问题 网上大多数说法是 在pom ...
- css常用命名
常用的CSS命名 头:header 内容:content/container 尾:footer 导航:nav 侧栏:sidebar 栏目:column 页面外围控制整体佈局宽度:wrapper 左右中 ...
- create-react-app创建的项目中registerServiceWorker.js文件的作用
使用React官方的脚手架工具create-react-app创建的项目,目录中会存在registerServiceWorker.js这个文件,这个文件的作用是什么呢? 这个文件可以使用也可以不使用, ...
- Foxmail6.5 ERR LOGIN FAIL 重新输入口令
这几天 Foxmail 6.5 收邮件不正常,一直报告ERR LOGIN FAIL,要求重新输入口令. 但输入正确的口令也无法收邮件. 反复折腾,最后发现如下设置即可: 邮箱账户设置 --> 邮 ...
- 实现CSS隐藏滚动条并可以滚动内容
隐藏滚动条的同时还需要支持滚动,我们经常在前端开发中遇到这种情况,最容易想到的是加一个iscroll插件,但其实现在CSS也可以实现这个功能,我已经在很多地方使用了,下面一起看看这三种方法. 方法1: ...
- [Swift]LeetCode542. 01 矩阵 | 01 Matrix
Given a matrix consists of 0 and 1, find the distance of the nearest 0 for each cell. The distance b ...