ShardedJedis的一致性hash

网友投稿 654 2022-11-26

ShardedJedis的一致性hash

ShardedJedis的一致性hash

ShardedJedis是redis客户端分片的实现。 但问题是,一个key到底经过了怎样的过程,最终才找到她应该存储的Redis实例呢? 我们先看一下ShardedJedis是如何使用的

List shards = Arrays.asList( new JedisShardInfo("localhost",6379), new JedisShardInfo("localhost",6380)); ShardedJedis sharding = new ShardedJedis(shards); long start = System.currentTimeMillis(); for (int i = 0; i < 100000; i++) { String result = sharding.set("sn" + i, "n" + i); } long end = System.currentTimeMillis();

ShardedJedis继承自Sharded

而Sharded里面有两属性nodes与resources

public class Sharded> { public static final int DEFAULT_WEIGHT = 1; private TreeMap nodes; private final Map, R> resources = new LinkedHashMap, R>(); //.... }

假如我们的redis集群就像上面的代码,有两个实例,也就是说有两个JedisShardInfo

我们看下图:

ShardedJedis为每个redis实例做出了160个虚拟节点(也可是320或者480,这个权重可以设定,默认是160)

在ShardedJedis初始化的时候,两个redis实例就会初始化320个虚拟节点,分别属于2个JedisShardInfo

他们的关系,存储在nodes这个属性里

同时JedisShardInfo与jedis这个最基础的redis客户端也是一一对应的,他们的关系存储在resources中。

ShardedJedis初始化时,会调用initialize

private void initialize(List shards) { nodes = new TreeMap(); 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++) { 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()); } }

大家知道那320个节点的标识符的来源是什么了吧?反正结果就是一个long型的数字

如果我们get obj1

我们就首先hash obj1 然后在在320个节点里,找到第一个大于hash(obj1)的虚拟节点,如果hash(obj1)大于最大的那个虚拟节点,就把这个obj1放在1号虚拟节点里

然后根据nodes,找到1号虚拟节点对应的JedisShardInfo

再从resources中找到jedis

然后从这个jedis实例中get obj1

为什么要这么做

如果有3个redis实例,直接hash(key)%3 是几,就存放到哪个redis实例里么。

恩,这个想法很只管

问题是,如果我现在要扩容,把3个实例升级成5个实例。

那原先obj1经过hash然后对3求余的结果和对5求余的结果能一样么?

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:RedisCluser(v-3.2.0)与Tomcat7的Session整合
下一篇:关于用redis缓存对象
相关文章

 发表评论

暂时没有评论,来抢沙发吧~