ShardedJedis的分片原理
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的分片原理的更多相关文章
- 进阶的Redis之哈希分片原理与集群实战
前面介绍了<进阶的Redis之数据持久化RDB与AOF>和<进阶的Redis之Sentinel原理及实战>,这次来了解下Redis的集群功能,以及其中哈希分片原理. 集群分片模 ...
- ElasticSearch高可用集群环境搭建和分片原理
1.ES是如何实现分布式高并发全文检索 2.简单介绍ES分片Shards分片技术 3.为什么ES主分片对应的备分片不在同一台节点存放 4.索引的主分片定义好后为什么不能做修改 5.ES如何实现高可用容 ...
- Mongodb 分片原理
1.主从mongodb 模式 类似,MySQL的主从配置 参照:https://blog.csdn.net/liusong0605/article/details/11551699 mongoDB有 ...
- MongoDB分片原理篇
MongoDB分片 为什么需要Sharded cluster? MongoDB目前3大核心优势:『灵活模式』+ 『高可用性』 + 『可扩展性』,通过json文档来实现灵活模式,通过复制集来保证高可用, ...
- MongoDB 分片的原理、搭建、应用
一.概念: 分片(sharding)是指将数据库拆分,将其分散在不同的机器上的过程.将数据分散到不同的机器上,不需要功能强大的服务器就可以存储更多的数据和处理更大的负载.基本思想就是将集合切成小块,这 ...
- MongoDB 分片的原理、搭建、应用 !
MongoDB 分片的原理.搭建.应用 一.概念: 分片(sharding)是指将数据库拆分,将其分散在不同的机器上的过程.将数据分散到不同的机器上,不需要功能强大的服务器就可以存储更多的数据和处 ...
- MongoDB 分片的原理、搭建、应用 (转)
一.概念: 分片(sharding)是指将数据库拆分,将其分散在不同的机器上的过程.将数据分散到不同的机器上,不需要功能强大的服务器就可以存储更多的数据和处理更大的负载.基本思想就是将集合切成小块,这 ...
- Jedis分片连接池
[http://blog.csdn.net/lang_man_xing/article/details/38405269] 一下内容来自网络,但是很多细节没有写出来,所以我经过自己琢磨,终于找到原 ...
- mongodb 学习笔记 09 -- shard分片
概述 shard 分片 就是 把不同的数据分在不同的server 模型 当中: 用户对mongodb的操作都是向mongs请求的 configsvr 用于保存,某条数据保存在哪个sha ...
随机推荐
- 01: vue.js安装
1.1 vue.js安装与基本使用 官网:https://cn.vuejs.org/ 1.使用之前,我们先来掌握3个东西是用来干什么的 1. npm: Nodejs下的包管理器. 2. webpack ...
- mbr看图
- P3952 NOIP2017 时间复杂度
写了两三个小时,麻烦倒是不麻烦,要考虑清楚,想全了 只过了样例提交是不是傻,要自己造数据 数据不大可以用STL 建议自己刚一下,不看代码 #include <iostream> #incl ...
- JavaScript:正则表达式 应用
1. var data = "<table id=\"test\"><tr class=\"light\"><td> ...
- ovs-ofctl: s1 is not a bridge or a socket 解决方法
参考: ovs-vsctl: Error detected while setting up bridge ovs-ofctl: s1 is not a bridge or a socket 解决方法 ...
- #网页中动态嵌入PDF文件/在线预览PDF内容#
摘要:在web开发时我们有时会需要在线预览PDF内容,在线嵌入pdf文件: 问题1:如何网页中嵌入PDF: 在网页中: 常用的几种PDF预览代码片段如下: 代码片段1: 1 <object ty ...
- AtCoder square869120 Contest #3 F sushi
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
- Intel微处理器学习笔记(二) 三种模式
三种模式:实模式.保护模式和平展模式. 实模式存储器(DOS存储器)位于00000H~FFFFFH,共1M空间(任何型号微处理器都支持). 保护模式存储器(Windows存储器)可位于整个保护存储系统 ...
- ubuntu 14.04 添加、删除用户,修改用户名称,修改主机名
ubuntu添加用户 sudo adduser test ubuntu删除用户 sudo userdel test cd /home/ sudo rm -r test
- 附加题找bug
private: void ReSize(int sz) { ) { return; } if(maxSize != sz) { T *arr = new T[sz]; if(arr == NULL) ...