之前项目中曾使用一致性 Hash 路由请求至指定的缓存节点,关于 Dubbo 的一致性 Hash 实现可以参考 Dubbo 一致性Hash负载均衡实现剖析,源码参见 ConsistentHashLoadBalance.java at dubbo-3.0.0。其 hash 值与 Invoker 的映射关系采用 TreeMap
作为底层的数据结构,其根据当前调用查询调用者的源码如下:
1 | private final TreeMap<Long, Invoker<T>> virtualInvokers; |
关键点在于 selectForKey
方法中对 TreeMap
实例的 ceilingEntry
调用及 firstEntry
调用,我们知道 TreeMap
底层实现为红黑树,即自平衡的二叉搜索树。ceilingEntry
方法用于使用计算出的 hash 值查找大于等于 hash 值的节点,跟随 ceilingEntry
方法调用至 TreeMap.java at jdk8-b120:
1 | /** |
1 | 节点示例图一 节点示例图二 |
根据上方 selectForKey
的代码,我们知道,当在 TreeMap
中无法找到大于等于指定 hash 值的节点时,此时我们调用 virtualInvokers.firstEntry()
获取 TreeMap
中的最小节点,firstEntry()
方法将调用至 TreeMap.java at jdk8-b120:
1 | /** |
即一直向左子树寻找,定位至左下角的节点,即二叉搜索树中的最小值,这样就模拟出了一致性 Hash 的环。
Reference
Fix wrong interpretation by tianshuang · Pull Request #1686 · apache/dubbo-website · GitHub