ShardedJedisPool xml配置:

<bean id="shardedJedisPool" class="redis.clients.jedis.ShardedJedisPool">
<constructor-arg index="0">
<bean class="redis.clients.jedis.JedisPoolConfig"></bean>
</constructor-arg>
<constructor-arg index="1">
<list>
<bean class="redis.clients.jedis.JedisShardInfo">
<constructor-arg name="host" value="192.168.233.8"/>
<constructor-arg name="port" value="6379"/>
</bean>
<bean class="redis.clients.jedis.JedisShardInfo">
<constructor-arg name="host" value="192.168.233.8"/>
<constructor-arg name="port" value="6381"/>
</bean>
<bean class="redis.clients.jedis.JedisShardInfo">
<constructor-arg name="host" value="192.168.233.8"/>
<constructor-arg name="port" value="6382"/>
</bean>
</list>
</constructor-arg>
</bean>

xml配置对应的构造方法:

public class ShardedJedisPool extends Pool<ShardedJedis> {
public ShardedJedisPool(final GenericObjectPoolConfig poolConfig, List<JedisShardInfo> shards) {
this(poolConfig, shards, Hashing.MURMUR_HASH);
}
}

ShardedJedisPool使用示例:

ShardedJedisPool pool = ctx.getBean(ShardedJedisPool.class);
ShardedJedis jedis = pool.getResource();
String zhang = jedis.get("zhang");
jedis.close();

ShardedJedisPool.getResource 的调用栈:

代码分析:

//类 redis.clients.util.Sharded<R, S extends ShardInfo<R>>
private final Map<ShardInfo<R>, R> resources = new LinkedHashMap<ShardInfo<R>, R>(); private void initialize(List<S> shards) {
nodes = new TreeMap<Long, S>();
  //shards是xml中配置的redis.clients.jedis.JedisShardInfo的list
for (int i = 0; i != shards.size(); ++i) {
final S shardInfo = shards.get(i);
     //没有为JedisShardInfo设置name,所以执行if分支,weight默认为1
     //取 SHARD-0-NODE-0 ~ SHARD-0-NODE-159 哈希值
     //取 SHARD-1-NODE-0 ~ SHARD-1-NODE-159 哈希值
     //取 SHARD-2-NODE-0 ~ SHARD-2-NODE-159 哈希值
     //把(哈希值->JedisShardInfo)键值对放入nodes中
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);
}
//添加到map中,键为JedisShardInfo,值为Jedis
resources.put(shardInfo, shardInfo.createResource());
}
}

JedisShardInfo.createResource:

//省略其他代码
public class JedisShardInfo extends ShardInfo<Jedis> {
@Override
public Jedis createResource() {
return new Jedis(this);
}
}

存取一个键时,根据键获取一个JedisShardInfo,以get为例:

public S getShardInfo(byte[] key) {
   //nodes是TreeMap,由红黑树实现,是按键值排好序的map,默认为升序
   //假定 algo.hash(key) 的值为10086,该行代码是取出键大于10086的所有键值对 
SortedMap<Long, S> tail = nodes.tailMap(algo.hash(key));
//如果不存在,则取第一个键值对的JedisShardInfo
if (tail.isEmpty()) {
return nodes.get(nodes.firstKey());
}
//如果存在这样的键值对,则返回第一个键值对中的JedisShardInfo
return tail.get(tail.firstKey());
}

Sharded类中有2个map,TreeMap<Long, S> nodes和Map<ShardInfo<R>, R> resources,

运行时具体是:TreeMap<Long, JedisShardInfo>和Map<JedisShardInfo, Jedis>。

分析以上代码可知,首先计算出 "SHARD-i-NODE-n" 的哈希值,预先生成一颗红黑树,即填充nodes。

当存取键值对时,计算键的哈希值,然后从红黑树上摘下比该值大的第一个节点上的JedisShardInfo,随后从resources取出Jedis。

假定有红黑树如下:

ShardedJedis的分片原理的更多相关文章

  1. 进阶的Redis之哈希分片原理与集群实战

    前面介绍了<进阶的Redis之数据持久化RDB与AOF>和<进阶的Redis之Sentinel原理及实战>,这次来了解下Redis的集群功能,以及其中哈希分片原理. 集群分片模 ...

  2. ElasticSearch高可用集群环境搭建和分片原理

    1.ES是如何实现分布式高并发全文检索 2.简单介绍ES分片Shards分片技术 3.为什么ES主分片对应的备分片不在同一台节点存放 4.索引的主分片定义好后为什么不能做修改 5.ES如何实现高可用容 ...

  3. Mongodb 分片原理

    1.主从mongodb 模式 类似,MySQL的主从配置  参照:https://blog.csdn.net/liusong0605/article/details/11551699 mongoDB有 ...

  4. MongoDB分片原理篇

    MongoDB分片 为什么需要Sharded cluster? MongoDB目前3大核心优势:『灵活模式』+ 『高可用性』 + 『可扩展性』,通过json文档来实现灵活模式,通过复制集来保证高可用, ...

  5. MongoDB 分片的原理、搭建、应用

    一.概念: 分片(sharding)是指将数据库拆分,将其分散在不同的机器上的过程.将数据分散到不同的机器上,不需要功能强大的服务器就可以存储更多的数据和处理更大的负载.基本思想就是将集合切成小块,这 ...

  6. MongoDB 分片的原理、搭建、应用 !

    MongoDB 分片的原理.搭建.应用   一.概念: 分片(sharding)是指将数据库拆分,将其分散在不同的机器上的过程.将数据分散到不同的机器上,不需要功能强大的服务器就可以存储更多的数据和处 ...

  7. MongoDB 分片的原理、搭建、应用 (转)

    一.概念: 分片(sharding)是指将数据库拆分,将其分散在不同的机器上的过程.将数据分散到不同的机器上,不需要功能强大的服务器就可以存储更多的数据和处理更大的负载.基本思想就是将集合切成小块,这 ...

  8. Jedis分片连接池

    [http://blog.csdn.net/lang_man_xing/article/details/38405269]   一下内容来自网络,但是很多细节没有写出来,所以我经过自己琢磨,终于找到原 ...

  9. mongodb 学习笔记 09 -- shard分片

    概述 shard 分片 就是 把不同的数据分在不同的server 模型 当中:     用户对mongodb的操作都是向mongs请求的     configsvr 用于保存,某条数据保存在哪个sha ...

随机推荐

  1. P2512 [HAOI2008]糖果传递&&P3156 [CQOI2011]分金币&&P4016 负载平衡问题

    P2512 [HAOI2008]糖果传递 第一步,当然是把数据减去平均数,然后我们可以得出一串正负不等的数列 我们用sum数组存该数列的前缀和.注意sum[ n ]=0 假设为链,那么可以得出答案为a ...

  2. 经典模块化的前端框架:layer

    官网:http://layer.layui.com/ 官网论坛里有许多后台界面可参考下载.其中后台管理界面和弹窗功能都是比较常用的.

  3. 《课程设计》——foremost的使用

    <课程设计>--foremost的使用 foremost简介 formost 是一个基于文件头和尾部信息以及文件的内建数据结构恢复文件的命令行工具.这个过程通常叫做数据挖掘(data ca ...

  4. 20145309李昊《网络对抗技术》实验9 web安全基础实践

    本实验在同学帮助下完成 一.实验准备 1.0 实验目标和内容 Web前端HTML.能正常安装.启停Apache.理解HTML,理解表单,理解GET与POST方法,编写一个含有表单的HTML. Web前 ...

  5. Unity3D学习笔记(十三):委托、考试复习

    委托:比较什么时候用委托好   下课案例:不用下课铃 1.ClassManager需要拿到所有教室的引用,课堂管理者应该只负责计时并告知每间教室 2.每间教室应该是由当班老师负责是否需要下课,而课堂管 ...

  6. caffe深度学习网络(.prototxt)在线可视化工具:Netscope Editor

    http://ethereon.github.io/netscope/#/editor 网址:http://ethereon.github.io/netscope/#/editor 将.prototx ...

  7. js自动小轮播

    使用定时器,换个图片地址. 从1到5换,如果大于5了再跳到1,点击停止时关闭定时器. <!-- Author: XiaoWen Create a file: 2016-12-08 13:19:2 ...

  8. 04_Windows平台Spark开发环境构建

    Spark的开发环境,可以基于IDEA+Scala插件,最终将打包得到的jar文件放入Linux服务器上的Spark上运行 如果是Python的小伙伴,可以在Windows上部署spark+hadoo ...

  9. HDU 6071 Lazy Running(很牛逼的最短路)

    http://acm.hdu.edu.cn/showproblem.php?pid=6071 题意: 1.2.3.4四个点依次形成一个环,现在有个人从2结点出发,每次可以往它相邻的两个结点跑,求最后回 ...

  10. Cocos2d-x学习笔记(十)CC_CALLBACK回调函数相关宏

    这里加入一个插曲,是关于Cocos2d-x回调函数的.首先,让我们Cocos支持的回调函数宏有哪些,以及其原型: // new callbacks based on C++11 #define CC_ ...