一致性哈希算法的稳定性检测和它存在的问题及解决策略
加入机器节点:
假设p2p网络中要新加入一个机器节点N(new),那么N(new)首先得与p2p网络中的N(x)节点建立联系,通过N(x)按照 “路由查询”的路由算法查找N(new)对应的哈希值 H(N(new))=new,再查找它的后继节点,假设它的后继节点为N(s),N(s)的前趋节点为N(j),那么要将 N(new)节点假如它们两者之间,就必须重新建立它们之间的p2p网络架构关系。
非并发环境下可以做这样两步:
1.改变N(j),N(new),N(s)的前趋节点,后继节点的记录,来构成新的网络架构。
2.N(new)节点插入N(j)和N(s)节点之后,那么 N(new)就是N(s)的前趋节点,N(s)就是N(new)的后继节点,将N(s)上原本落在前趋节点N(new)哈希数值空间的键值 迁移到 N(new)节点上。
并发环境下,N(j)和N(s)之间可能同时有多个节点需要加入,这样做:
1. N(new)的后继节点指为N(s),把N(new)的前趋节点指为 null.
2. 稳定性检测 (这一步并非只为了新加入一个节点而设立,而是 每个节点都会周期性自动完成,通过 它可以完成前趋和后继 的更新和数据迁移,p2p网络架构中,每个节点都会定期执行它)
稳定性检测算法流程:
1.假设N(s)为N(c)的后继节点,N(c)向N(s)询问前趋节点N(p),
2.如果N(p)介于N(c)和N(s)之间,N(c)记录N(p)为它的后继节点。
3.令N(x)为N(c)的后继节点,其有可能是N(s)或者N(p),这得看前一步, 如果N(x)的前趋节点为 null 或者 N(c)位于N(x)和 它的前趋节点之间,那么 N(c)就发消息告诉 N(x),它是N(x)的前趋节点,N(x) 将它的前趋节点设置为 N(c)。
4. N(x)把它上面属于 N(c)的部分数据(哈希值小于c的)迁移到N(c)上,
二话不说上图:
----将N(c)加入p2p网络之前--------------------》之后--->
红线代表后继节点,蓝线代表前趋节点。
假设过了一点时间N(p)开始执行稳定性检测,此时,
,新加入节点后 ,原先节点的路由表可能已经不正确了,把本应该 指向新节点的路由项指向了旧的节点,因此,每个节点需要周期性的检查路由表,对路由表内每一项 k=2的i次方(0<=i<=m-1)加上本机节点执行路由算法,经过查询获得后,如果路由项保留内容不同则更新到新内容,完成路由表的更新。
节点离开p2p网络有两种方式: 正常离开和异常离开。
正常离开一般会通知前趋节点和后继节点 迁移数据,路由表失效可以通过 “加入新节点的情形”来更新。异常离开是机器故障导致 ,此时数据可能丢失,为了避免,可以将数据在多台机器是备份。
一致性哈希存在的问题:
1.机器节点映射到环状结构位置是随机的,容易导致机器负载不均衡,
2. 大规模数据中心,既有高性能,高配置的机器 ,也有低性能的,低配置 的,一致性哈希并未考虑这种情况,将所有的机器 都一律平等看待,容易造成低配置高负载的情况 。
针对它存在的问题 引入了 “虚拟节点”:
一个物理节点虚拟成若干虚拟节点,分布到一致性哈希的环状结构的不同位置。(可以导致更佳的负载均衡,也减轻了机器异质性问题)