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()); }