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对 ...
随机推荐
- Eclipse 引导阮卓项目 No projects are found to import解
我们指示import当项目.由于一些git项目不.project和.classpath档.因此,直接import当然不是现有项目. 下面是解决方式: 1. new Android Project里面换 ...
- ajax——client访问webservice基本用法
学前aps.net当我学会了使用服务器端的访问webservice方法,然后实现一个样本:web server模拟网上购物,今天学习asp.net ajax的时候学习到了client直接訪问webse ...
- 内存排查 valgrind
内存问题排查工具 --- valgrind 1. 概述 2. Valgrind 3. 内存泄漏监测 3.1. 示例代码 3.2. 编译它 3.3. 用Valgrind监测进程的内存泄漏 4. 悬挂指针 ...
- Swift # 异常处理
面向轨道编程 - Swift 中的异常处理 问题 在开发过程中,异常处理算是比较常见的问题了. 举一个比较常见的例子:用户修改注册的邮箱,大概分为以下几个步骤: 接收到一个用户的请求:我要修改邮箱地址 ...
- WebService它CXF注释错误(两)
WebService它CXF注解 1.详细报错例如以下 五月 04, 2014 11:24:12 下午 org.apache.cxf.wsdl.service.factory.ReflectionSe ...
- Python学习笔记16:标准库多线程(threading包裹)
Python主要是通过标准库threading包来实现多线程. 今天,互联网时代,所有的server您将收到大量请求. server要利用多线程的方式的优势来处理这些请求,为了改善网络port读写效率 ...
- hadoop 2.2.0集群安装
相关阅读: hbase 0.98.1集群安装 本文将基于hadoop 2.2.0解说其在linux集群上的安装方法,并对一些重要的设置项进行解释,本文原文链接:http://blog.csdn.net ...
- C#操作 Advantage Database Server 数据库
相关下载 http://devzone.advantagedatabase.com/dz/content.aspx?key=31 1.安装数据库: Advantage Database Server ...
- 《Windows游戏编程技巧大师》就DirectDraw而创建DirectDraw知识笔记
1.DirectDraw 这可能是Directx中最重要的技术,由于它是2D图形赖以实现的渠道.也是Direct3D构建于其上的帧缓冲层. 2.DirectDraw是由非常多借口组成的.共同拥有5个接 ...
- 快速构建Windows 8风格应用4-FlipView数据控件
原文:快速构建Windows 8风格应用4-FlipView数据控件 本篇博文主要介绍为什么使用FlipView控件.什么是FlipView控件.如何使用FlipView控件和FlipView控件最佳 ...