Jedis 分片原理

一.根据节点权重将节点名散列成160*(权重:默认为1),并将散列值与节点存入 TreeMap.
得到一棵有序树.代码如下.
 1 private void initialize(List<S> shards) {
 2 nodes = new TreeMap<Long, S>();
 3 for (int i = 0; i != shards.size(); ++i) {
 4 final S shardInfo = shards.get(i);
 5 if (shardInfo.getName() == null) for (int n = 0; n < 160 * shardInfo.getWeight(); n++) {
 6 nodes.put(this.algo.hash("SHARD-" + i + "-NODE-" + n), shardInfo);
 7 }
 8 else for (int n = 0; n < 160 * shardInfo.getWeight(); n++) {
 9 nodes.put(this.algo.hash(shardInfo.getName() + "*" + shardInfo.getWeight() + n), shardInfo);
10 }
11 resources.put(shardInfo, shardInfo.createResource());
12 }
13 }
二.将请求 Key 散列得到 hashCode,取出tailMap(即TreeMap 的 KEY 值>hashCode),若 tailMap 为空则使用 TreeMap,最后取map 的第一个元素做节点.代码如下.
 1 public R getShard(String key) {
 2 return resources.get(getShardInfo(key));
 3 }
 4  
 5 public S getShardInfo(byte[] key) {
 6 SortedMap<Long, S> tail = nodes.tailMap(algo.hash(key));
 7 if (tail.isEmpty()) {
 8 return nodes.get(nodes.firstKey());
 9 }
10 return tail.get(tail.firstKey());
11 }
三.分析.
1.散列160个虚拟节点,可以使节点数据更加平均.
2.利用 TreeMap实现一致性 Hash
例如:TreeMap 的 Key 值如下列表.
23,789,1035,4576,986,.............114144433414,23423432429
利用 TreeMap 实现一个环.每个节点控制当前节点到右边节点间的数据.
原文地址:https://www.cnblogs.com/hhbk/p/7813214.html