10 | 一致哈希算法:如何分群,突破集群的“领导者”限制?
10 | 一致哈希算法:如何分群,突破集群的“领导者”限制?
讲述:于航
时长10:44大小9.82M
使用哈希算法有什么问题?
如何使用一致哈希实现哈希寻址?
内容小结
课堂思考
赞 15
提建议
精选留言(43)
- 指尖以东置顶2020-05-06最近一直在看hash,老师可否讲讲虚拟节点的算法怎么做才能做到均衡,不然加的节点还是可能冷热不均衡的
作者回复: 加一颗星:这个主要是利用算法的随机性,在实际使用中,增加更多的节点,就会均衡了。为了帮助大家更直观的理解,我新增了一个演示程序(https://github.com/hanj4096/hash),来演示虚拟节点的均衡性的。具体效果如下: go run consistent-hash-vnode.go normal mode: node0 79.597960% , node1 87.818782% , node2 132.613261% vnode mode: node0 100.990099% , node1 98.679868% , node2 100.360036%
12 - Michael Tesla2020-03-30老师,我觉得课后题的答案是:数据要同时写入当前集群和下一个集群。某个Raft集群挂掉后,原本路由到这个集群的请求,现在都到下一个Raft集群去了。只要下一个Raft集群保存了上一个集群的数据,即使某个集群挂了,整个系统还能正常提供服务。
作者回复: 加一颗星:),相比“值到节点”的一级映射,可以做两级映射,“值到集群,集群到领导者节点”,通过Raft的节点故障容错能力,来避免数据迁移。在实际系统中,如果不采用具有节点故障容错能力的共识算法,一般不会直接将数据写入到下一个节点,而是会有个备份服务器,当节点故障,切换到备节点时,为了实现强一致性,能读取到最新数据,不仅要做一致性对比和数据迁移,还是实现双读,比较复杂。
18 - Purson2020-03-04老师,consistent-hash.go 和 hash.go 算法希望能分享一下。另外有个问题,虚拟节点还是映射了实际节点,比如一个节点有4个虚拟节点,如果1个实际节点挂了,是不是意味着另外3个相关的虚拟节点挂了,这样一致性hash算法还是会有很多不命中的情况。
作者回复: https://github.com/hanj4096/hash 是的,虚拟节点,是需要映射到实际节点的,实际节点挂了,虚拟节点就没有意义了。
17 - 星期一2020-03-04那TiDB 通过raft实现kv,region 来突破领导者单点问题,老师可以不可以串讲一下:TiDB、kafka、es 等常见分布式中间件 它们各自如何解决分布式的问题。
作者回复: 好,后续做个补充吧。
共 3 条评论16 - Kvicii.Y2020-03-244.当某一个节点故障了,该节点上的数据需要进行迁移吗??感觉只是影响了瞬间的读写,raft选举会很快进行吧,恢复了之后就有正常了,选举期间的读写访问顺延到下一节点这个才需要具体实现吧?
作者回复: 加一颗星:),是的,不需要,领导者选举很快的,在客户端超时重试间隔内,是能恢复的。
7 - hello2020-03-04老师请教下,在环中加入节点以及去掉节点,那存储的数据是如何迁移到其它节点上的?
作者回复: 需要自己开发工具,在迁移过渡状态时,还要考虑多读,数据写入到新节点,但读,需要同时读2个节点,返回最新的数据。
共 3 条评论7 - Sinclairs2020-03-04针对多个 Raft 集群, 需要有一个路由系统, 客户端通过这个路由系统来读写数据.. 1. 客户端写数据时, 根据哈希算法会得到一个值, 这个值可以落到集群A的哈希分片上, 假设集群B是集群A顺时针哈希分片后的下一个分片. 客户端写入数据时, 要保证集群A和集群B同时写入成功 2. 客户端读取数据时, 路由系统若检测到集群A不可用, 则去访问集群B, 也能获得数据. 集群A和相邻的集群B同时发生故障的概率是非常小的, 这样就能保证系统的稳定运行.展开
作者回复: 加一颗星:),考虑到Raft集群本身就有节点故障容错能力,当发生领导者选举后,映射到新的领导者,就可以了。
共 7 条评论7 - 尿布2020-03-12为什么一个节点可以算出多个hash值?
作者回复: 加一颗星:),引入虚拟节点,比如,将包含主机名和虚拟节点编号的字符串,作为参数,来计算哈希值。
6 - 竹马彦四郎的好朋友影...2020-05-04这一节感觉还是比较轻松的~4
- Theodore2020-04-20解开了我多年的疑惑。我说一致性hash怎么解决迁移带来的问题,还是靠运维啊
作者回复: 加一颗星:),扩容或缩容时,一般是通过运维工具来迁移的。
4 - 沉淀的梦想2020-03-05当其中一个 Raft 集群领导者出现故障,读的时候还是可以从跟随者读,写的时候可以暂时先写到哈希环上的下一个集群中,等到重新选举领导者完成,再把数据捞回来。这么设计可以吗?
作者回复: 数据迁移,实际操作起来,还是有复杂度,需要流程化。其实,领导者选举是很快的,一般,写失败后,重试就可以了。
共 2 条评论4 - Kvicii.Y2020-03-24老师, 1.虚拟节点是要根据hash规则再做一次hash类似这样实现吗? 2.在这个例子中,节点A、B、C是不是就可以理解为三个Raft集群,每个集群上都分别有Leader,各自进行集群的维护操作呢?
作者回复: 加一颗星:),问题1,是的,还需要将虚拟节点映射到实际节点;问题2,也可以这么理解的。
3 - 小晏子2020-03-04将数据按照某种方式分片然后按照一致性hash算法存放到不同的raft集群中,这样当某个集群出问题时,这部分分区数据会迁移到临近raft集群,保障了系统的稳定运行。理论上可行,可是实际中好像没有这样做的,管理多个raft集群感觉是个麻烦的事情。
作者回复: Raft集群本身有容错能力,可以和一致哈希结合着使用,尽量避免数据迁移,在现实中,数据迁移还是有复杂度,除了要流程化,还避免引起节点CPU的高负载。大系统、容错要求高,是需要的。
共 2 条评论3 - Kvicii.Y2020-03-243.对2^32取模的过程是不是相当于计算hash环的索引,实际对key进行hash计算找位置时才是找真正的索引?
作者回复: 加一颗星:),前半句,是的,后半句,对key执行hash计算,得出key对应的索引值,然后根据key的索引值,找到key对应节点。
2 - 高志强2020-03-04老师,consistent-hash.go 和 hash.go 算法在github上有代码么,想看看
作者回复: https://github.com/hanj4096/hash
2 - Ricky Fung2021-06-29课后问题 可以维护二级映射,hash(key) -> 集群,集群 -> leader节点IP,集群对应的leader节点IP可以统一存储到某个地方(例如redis)便于查询。1
- 明翼2020-04-17老师我对一致hash算法搬迁数据量有疑问,比如文中三个节点变成四个节点假设数据是均衡的三个节点存数据为总得33.3%,调整数据大概只要调整第三个节点的一半即16%这个比您文中的要少,怎么回事,是不是hash不均衡造成的偏差那您又如何知道该如何均衡的那
作者回复: 加一颗星:),如果数据和节点的映射关系变了,那么数据就需要搬迁,比如,你可以这样推导来感性理解下,1~10,10个数作为key,分别按照3和4来取余,余数为对应的节点,然后统计下,有多少key对应节点的映射关系发生了变化,然后再增加key的数量,比如100,再来统计下。
1 - winfield2020-04-12有个疑问,一致性哈希中引入虚拟节点能解决冷热不均的问题么,虚拟节点最后不还是映射到了实际节点上?请老师帮忙解答下,谢谢!
作者回复: 加一颗星:),是的,最终是需要寻址到实际节点上的。
共 3 条评论1 - 吟游雪人2020-04-02多集群是多领导者节点么?多领导者不就脑裂了么?
作者回复: 多个集群,不是同一个集群多个领导者节点,是指多个独立的集群。比如,你配置了2个基于Raft的KV存储集群,集群1,存放的是来自业务1的数据;集群2,存放的是来自业务2的数据。
共 4 条评论1 - 孙成子2020-03-31一致性HASH算法,为什么会出现不均匀的情况? hash的目的就是打散数据。
作者回复: 加一颗星:),值少。均匀是相对的,值越多越均匀,所以,当节点数少时,需要引入虚拟节点,也就是更多的值。可以写个程序,实际运行,感性的体验下:)。
1