jedis分片相關的類有Sharded ShardInfo Jedisnode
ShardInfo :redis
public abstract class ShardInfo<T> { private int weight; //加權 protected abstract T createResource(); //建立jedis鏈接實例 public abstract String getName(); }
Sharded : 算法
public Sharded(List<S> shards, Hashing algo, Pattern tagPattern) { this.algo = algo; this.tagPattern = tagPattern; initialize(shards); //shards 分片列表 }
private void initialize(List<S> shards) { nodes = new TreeMap<Long, S>(); for (int i = 0; i != shards.size(); ++i) { final S shardInfo = shards.get(i); if (shardInfo.getName() == null) for (int n = 0; n < 160 * shardInfo.getWeight(); n++) { //把一個分片分紅160個節點,存起來 nodes.put(this.algo.hash("SHARD-" + i + "-NODE-" + n), shardInfo); } else for (int n = 0; n < 160 * shardInfo.getWeight(); n++) { nodes.put(this.algo.hash(shardInfo.getName() + "*" + shardInfo.getWeight() + n), shardInfo); } resources.put(shardInfo, shardInfo.createResource()); // 建立jedis鏈接實例,存起來,因此 resources 是對redis實例的緩存 } }
當執行讀寫操做時要根據key從resources裏取出一個jedis實例 獲取jedis實例分爲兩個步,重點是 經過key 從nodes節點裏找到一個分片緩存
public S getShardInfo(byte[] key) { SortedMap<Long, S> tail = nodes.tailMap(algo.hash(key)); /默認的hash算法, if (tail.isEmpty()) { return nodes.get(nodes.firstKey()); //有序的map,即便返回多個值,經過取first也能保證每次取到 的結果是一個 } return tail.get(tail.firstKey()); }