题图来自:花瓣 场景: 上篇文章介绍到的《一致性hash算法(概念)》,附上代码实现及另外一种问题的解决办法。 代码实现 代码就在这里了~~代码有点长,不贴代码了,附上github的地址: 可以直接到:https://github.com/losetowin/learnning (在此下的learning/com.dutycode.learning.consistenthash包下) 具体代码地址如下: https://github.com/losetowin/learnning/blob/master/learnning/src/main/java/com/dutycode/learning/consistenthash/ConsistentHashDemo.java 直接看下结果 新增节点时,日志打印出现如下内容: 如图所示,当新增节点时,虚拟节点分散在了几个虚拟节点中,分别对应到目前已存在的几个真实节点: 10.0.0.1~10.0.0.4之间,也就意味着流量和数据分别分散到了现有的几个真实节点之上。 删除节点时:我们假定删除的节点是10.0.0.2节点: 日志打印如下: 如图所示,删除节点时,摘除真实缓存节点10.0.0.2之后,受到影响的虚拟节点为 VNode-10.0.0.3-Num-3 VNode-10.0.0.1-Num-2 VNode-10.0.0.3-Num-4 VNode-10.9.1.100-Num-2 也就意味着,删除节点后,原存储在10.0.0.2节点上的数据将迁移到10.0.0.3、10.0.0.1、10.9.1.100三台机器上,同时,虽然摘除了节点,但流量和数据压力并没有全部压到一台机器上,而是分散到了多台缓存服务器上。解决了之前提到的可能导致的雪崩问题。 另外一种实现方法 关于节点宕机还有另外一种处理方式: 主备服务器切换方式 一致性hash的方式虽然能够避免雪崩的问题,但同时也带来的一个问题是,一旦某个节点宕机之后,一定存在着数据迁移的问题,如果数据量大的话,迁移数据的时间可能会比较长。 有一种办法,可以空间换时间,这里的时间是指宕机之后的数据恢复时间。 可以采用主备服务器的方式,一旦主服务器宕机,则备服务器立马提供服务,接替主服务器提供服务。 比如,redis的sentinel。 具体如下图所示: 这样在主节点宕机之后,备用节点可以直接接替主节点,也就省去了数据迁移,同时对业务端也最友好。 但同时也会存在一定的问题:如果当前主节点容量或者抗压无法满足的时候,扩容便是件很难的事情。 假如流量很重,主节点宕机,那么这时候备用节点补上的时候,同样也会被压垮。 那如何解决呢? 可以结合一致性Hash来做。主备的方式来保证某个节点宕机的时候能够快速响应, 一致性Hash来保证单节点压力无法承受的时候快速低成本的扩容。 关于上篇文章的一个修正 上篇文章提到一个问题: 『2、为什么是2^32个桶空间?』 但上篇文章对这个问题的解释不太正确,在这里做下更正: 桶空间的大小根据选用的hash算法来定,一般情况下,hash的返回结果为32位的整型数据,无符号的整型的最大值是2^32-1,最小值是0,一共2^32个数字,所以,桶空间也就是2^32个了。 预告 一致性Hash应用到缓存服务器的时候,当出现增删节点的时候,会出现数据迁移的一个问题,该如何做数据迁移,后面会整理一个方案。 1、数据迁移方案。 个人博客:www.dutycode.com 微信公众号:dutycode_com |
|