ShardedJedis实现学习
ShardedJedis实现学习-我们到底能走多远系列(33)
我们到底能走多远系列(31)
扯淡:
工作是容易的赚钱是困难的
恋爱是容易的成家是困难的
相爱是容易的相处是困难的
决定是容易的可是等待是困难的
主题:
1,Sharded的实现
Memcached 和 redis 都使用了该算法来实现自己的多服务器均匀分派存储值的。
shardedJedisPool的配置如下:(具体可以参考《spring和redis的整合》)

<bean id="shardedJedisPool" class="redis.clients.jedis.ShardedJedisPool" scope="singleton">
<constructor-arg index="0" ref="jedisPoolConfig" />
<constructor-arg index="1">
<list>
<bean class="redis.clients.jedis.JedisShardInfo">
<constructor-arg name="host" value="${redis.host}" />
<constructor-arg name="port" value="${redis.port}" />
<constructor-arg name="timeout" value="${redis.timeout}" />
<constructor-arg name="weight" value="1" />
</bean>
</list>
</constructor-arg>
</bean>

注入了两个对象:jedisPoolConfig 和 JedisShardInfo
然后产生ShardedJedis:

public ShardedJedis getRedisClient() {
try {
ShardedJedis shardJedis = shardedJedisPool.getResource();
return shardJedis;
} catch (Exception e) {
log.error("getRedisClent error", e);
}
return null;
}

ShardedJedis 继承 BinaryShardedJedis 继承Sharded<Jedis, JedisShardInfo>
而Sharded的实现就是前面一致性哈希算法的实现啦~

// 使用TreeMap来完成构造出一个很多节点的环形
private TreeMap<Long, S> nodes; // 构造方法
public Sharded(List<S> shards, Hashing algo, Pattern tagPattern) {
this.algo = algo;
this.tagPattern = tagPattern;
// 初始化方法,建立一个个节点
initialize(shards);
}

initialize方法:

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++) {
nodes.put(this.algo.hash("SHARD-" + i + "-NODE-" + n), shardInfo);
}
else
// 将设置的权重放大160倍,产生更多的节点,因为hash一下就散落到各道各处了,如此就是所谓的虚拟节点,以保证均匀分布
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());
}
}

redis放key value的时候,需要判断应该放在那个服务器上,就是判断hash后更靠近哪个节点。

public R getShard(byte[] key) {
return resources.get(getShardInfo(key));
} public R getShard(String key) {
return resources.get(getShardInfo(key));
}
//最终调用方法
public S getShardInfo(byte[] key) {
// 首先判断是不是tree中最大的key,及最后一个,注意我们是环,所以最大的后面就要从头开始。
SortedMap<Long, S> tail = nodes.tailMap(algo.hash(key));
// 是最后一个key了,所以取第一个节点对应的服务器
if (tail.size() == 0) {
return nodes.get(nodes.firstKey());
}
// 不是最后一个就是比自己离自己最近的大的key对应的服务器
return tail.get(tail.firstKey());
} public S getShardInfo(String key) {
return getShardInfo(SafeEncoder.encode(getKeyTag(key)));
}

到这里基本明白了如何抽象实现一个环状的排序的数据结构了。值得借鉴。
2,实践中的一个例子

TreeMap<Integer, AwardConfigDO> extentTree = new TreeMap<Integer, AwardConfigDO>();
// 获奖区间划分
for (AwardConfigDO awardConfig : configList) {
//Probability是区间节点,如100,500
extentTree.put(awardConfig.getProbability(), awardConfig);
}
// 进入中奖区 random 是随机产生的数字,首先判断是否进入中奖区
if (random < extentTree.lastKey()) {
//然后判断 中奖奖项 是哪个
AwardConfigDO awardConfig = extentTree.higherEntry(random).getValue();
}

所以TreeMap可以来抽象实现这种区间的结构。关于TreeMap可以看API哦。
让我们继续前行
----------------------------------------------------------------------
努力不一定成功,但不努力肯定不会成功。
共勉。
ShardedJedis实现学习的更多相关文章
- jedis访问redis学习笔记
最近在学习redis,在网上查了些文章,利用他人已有的知识,总结写下了这篇文章,大部分内容还是引用别人的文章内容.经过测试发现spring-data-redis现在有的版本只能支持reids 2.6和 ...
- Redis学习记录之Java中的初步使用
1.关于Redis redis下载地址:<span style="font-family: Arial, Helvetica, sans-serif;">http:// ...
- Dubbo入门到精通学习笔记(八):ActiveMQ的安装与使用(单节点)、Redis的安装与使用(单节点)、FastDFS分布式文件系统的安装与使用(单节点)
文章目录 ActiveMQ的安装与使用(单节点) 安装(单节点) 使用 目录结构 edu-common-parent edu-demo-mqproducer edu-demo-mqconsumer 测 ...
- 从直播编程到直播教育:LiveEdu.tv开启多元化的在线学习直播时代
2015年9月,一个叫Livecoding.tv的网站在互联网上引起了编程界的注意.缘于Pingwest品玩的一位编辑在上网时无意中发现了这个网站,并写了一篇文章<一个比直播睡觉更奇怪的网站:直 ...
- Angular2学习笔记(1)
Angular2学习笔记(1) 1. 写在前面 之前基于Electron写过一个Markdown编辑器.就其功能而言,主要功能已经实现,一些小的不影响使用的功能由于时间关系还没有完成:但就代码而言,之 ...
- ABP入门系列(1)——学习Abp框架之实操演练
作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...
- 消息队列——RabbitMQ学习笔记
消息队列--RabbitMQ学习笔记 1. 写在前面 昨天简单学习了一个消息队列项目--RabbitMQ,今天趁热打铁,将学到的东西记录下来. 学习的资料主要是官网给出的6个基本的消息发送/接收模型, ...
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- Unity3d学习 制作地形
这周学习了如何在unity中制作地形,就是在一个Terrain的对象上盖几座小山,在山底种几棵树,那就讲一下如何完成上述内容. 1.在新键得项目的游戏的Hierarchy目录中新键一个Terrain对 ...
随机推荐
- 【转】Uiautomator Api浅析
原文地址:http://blog.sina.com.cn/s/blog_ae2575ff01018b2o.html uiautomator api: http://android.toolib.net ...
- jsp的<%%>
于jsp于 可以使用<% %> 嵌入java代码,简称jsp文字. 可以使用<% -- -- %> 凝视,这是jsp注视 可以使用<%! %> 声明全局变量 版权声 ...
- BIP Requests Are Failing With Error "OPP Error Oracle.apps.xdo.XDOException: Error Creating Lock Fil
In this Document Symptoms Cause _afrLoop=975833031487795&id=1512691.1&displayIndex=1&a ...
- C语言库函数大全及应用实例七
原文:C语言库函数大全及应用实例七 [编程资料]C语言库函数大全及应用实例七 函数名: getw 功 能: 从流中取一整数 用 法: int getw(FILE *strem); 程序例: #i nc ...
- NM常用网络命令
Ipconfig命令 Ipconfig命令可以被用来显示机器当前TCP/IP配置信息. 当使用Ipconfig时不带不论什么參数选项,那么它为每一个已经配置好的接口显示IP地址.子网掩码和默认网关值. ...
- android项目总体界面架构(可直接复用)
文章解读.效果图.源代码下载链接 http://blog.csdn.net/gao_chun/article/details/37903673
- 部分PC端安卓管理器使用强行断开重连的方法来连接手机,容易丢书数据,损坏数据
最近发现部分PC端的安卓管理器,貌似是百度影音以及PPTV的安卓客户端,使用强行断开手机连接,然后重新连接手机的方法,来实现客户端程序连接手机. 此时,如果刚好正在复制文件,则复制的文件会损坏,并且基 ...
- 三个创建WebStorm项目的方法
WebStorm项目代表一个完整的解决方案和定义项目范围设置.而重点则是代码完成.代码重构.代码风格等. 因此在建立项目时,WebStorm可以通过三个方面来完成:下载远程项目.复制控制存储库项目和直 ...
- Entity Framework 丢失数据链接的绑定,在已绑好的EDMX中提示“Choose Your Data Connection”
早先做的一个练手的项目中, 使用到了Entity framework . 最近碰到一个问题,在edmx 里面选择“Update model from Database” 的时候提示了 “Choose ...
- jQuery弹出窗口完整代码
jQuery弹出窗口完整代码 效果体验:http://keleyi.com/keleyi/phtml/jqtexiao/1.htm 1 <!DOCTYPE html PUBLIC "- ...