Jedis下的ShardedJedis(分布式)使用方法(二)

上一篇中介绍了ShardedJedis的基本使用方法以及演示了一个简单的例子,在这一篇中我们来介绍了ShardedJedis的原理。

1.获取数据过程

首先我们来看一下ShardedJedis的一个继承关系

看完了图,那么我们一步一步跟着我们的代码调用来看下,以我们最简单的 ShardedJedis.get()方法为例:

这边有调用一个getShard 方法,参数为我们传入的key,然后返回一个普通的jedis对象,那么这个getShard是用来做什么的呢,大家可能已经猜到了,这个方法就是会根据我们传入的key做一致性哈希判断,然后返回key落到的那个redis实例上的一个redis连接,不同的key返回的redis连接可能是不同的。

进入getShard 方法,你会发现这个实现是在Sharded类中实现的(看上面的类图可以发现顶层的Sharded类),代码如下:

上面的方法是层层调用的关系,在这边不细说,我们主要看下红框的那个方法实现(上面的nodes变量是一个TreeMap 类型, algo Hashing类型,即key分片所使用的hash算法,这个在前一篇有简单说过),那么这段代码的含义我们大概成猜出来了,

  1. 就是在一个TreeMap中取出大于等于key之后的部分视图SortMap
  2. 在SortMap取得第一个键值对的值,然后返回一个 S 对象,
  3. 然后根据这个S 对象,去resources(resources = new LinkedHashMap<ShardInfo<R>, R>())中get一个R对象

那么这个S R对象各自代表什么呢?看下面的代码

可以得出  S = JedisShardInfo, R = Jedis 对象,即在TreeMap存储了服务器划分的虚拟节点的信息,LinkedHashMap中存储了服务器的物理连接。

JedisShardInfo具体信息如下:里面包含了jedis服务器的一些信息,最重要的是它的父类中有一个weight字段,作为本jedis服务器的权值。

ok,那我们了解了实际上就是根据jedis服务器的信息去获取一个jedis的连接,返回给上层调用。

我们可以梳理下这个逻辑:

  1. 当我们使用ShardedJedis去查一个key时,首先它会把这个key进行一个hash算法
  2. 根据这个hash值然后去treeMap中,查出这个key落在哪个实例中,并返回redis实例对应的具体信息
  3. 根据这个redis的实例信息,到一个保存jedis链接和实例信息对应关系的LinkedHashMap中找到这个jedis连接
  4. 最终返回jedis连接,执行对象的命令操作(到这步后实际上和单机操作一样了)

那么我们的nodes 服务器虚拟节点和resources 服务器物理连接是什么时候初始化的呢,接下来继续看

2.nodes和resources 初始化

我们看到Sharded的构造方法

这边有一个initialize方法,看其实现

具体细节就不说了,根据上面的,我们就知道是在这边进行了初始化,将每台服务器节点采用hash算法划分为160个虚拟节点(可以配置划分权重),保存在TreeMap中,

然后把每台服务器节点的信息和物理连接以键值对保存LinkedHashMap中。

然后通过一系列的查找,发现Sharded的构造方法其实是在我们 jedisPool.getResource() 时就完成的

纳尼? 每次jedisPool.getResource() 才初始化?那会不会造成很慢呢,其实不用担心,其底层是使用了commons.pool来进行连接池的一些操作,会根据我们配置的连接池参数来生成对应的连接并保存,其中的细节很复杂,博主没有继续深究,实现其实和数据库连接池是一致的。

3.总结

ShardedJedis分布式具体的的实现思路:

  • redis服务器节点划分:将每台服务器节点采用hash算法划分为160个虚拟节点(可以配置划分权重)
  • 将划分虚拟节点采用TreeMap存储
  • 对每个redis服务器的物理连接采用LinkedHashMap存储
  • 对Key or KeyTag 采用同样的hash算法,然后从TreeMap获取大于等于键hash值得节点,取最邻近节点存储;当key的hash值大于虚拟节点hash值得最大值时,存入第一个虚拟节点
  • sharded采用的hash算法:MD5 和 MurmurHash两种;默认采用64位的MurmurHash算法;

好了,大概的实现如上面所说的,都是图可能会有点乱,大家如果有什么问题或者发现了什么错误,please tell me!

时间: 2024-10-12 03:32:47

Jedis下的ShardedJedis(分布式)使用方法(二)的相关文章

Jedis下的ShardedJedis(分布式)使用方法(一)

原来项目中有用到Redis用作缓存服务,刚开始时只用一台Redis就能够满足服务,随着项目的慢慢进行,发现一台满足不了现有的项目需求,因为Redis操作都是原子性这样的特性,造成有时同时读写缓存造成查询效率的下降.但是由于我们现在用的还是2.X版本,还是没有集群功能的(Redis作者在3.0版本中已经加入了集群功能), 因此只能使用2.x版本中自带的一个叫做ShardedJedis的来实现分布式缓存. ShardedJedis是通过一致性哈希来实现分布式缓存的,通过一定的策略把不同的key分配到

linux系统下php安装mbstring扩展的二种方法

.执行 复制代码代码如下: yum install php-mbstring 2. 修改php.ini (这一步非常重要, 部分lxadmin版本无法自动修改) 复制代码代码如下: echo ‘extension=mbstring.so' >>/etc/php.ini #更具php安装目录而定 3. 重启web service 如果是apache: service httpd restart 方法二:php 5.36安装目录:/usr/local/php 复制代码代码如下: #cd /usr/

win7下建立软AP -- 方法二

命令提示符(CMD)下建立软AP 步骤/方法(驱动安装及用户接入均如在界面下建立AP是一样) 1.      点开始-运行,输入cmd,回车.如图: 2.      在cmd里输入:netsh wlan showdrivers回车.查看无线网卡是否支持承载网络:是,则下一步如果否,则不能开启虚拟AP 3.继续输入:netsh wlan set hostednetwork    mode=allow ssid=wifi key=12345678 4.      此时已经成功建立一个虚拟的AP,再输

用python + hadoop streaming 编写分布式程序(二) -- 在集群上运行与监控

写在前面 前文:用python + hadoop streaming 编写分布式程序(一) -- 原理介绍,样例程序与本地调试 为了方便,这篇文章里的例子均为伪分布式运行,一般来说只要集群配置得当,在伪分布式下能够运行的程序,在真实集群上也不会有什么问题. 为了更好地模拟集群环境,我们可以在mapred-site.xml中增设reducer和mapper的最大数目(默认为2,实际可用数目大约是CPU核数-1). 假设你为Hadoop安装路径添加的环境变量叫$HADOOP_HOME(如果是$HAD

was集群下基于接口分布式架构和开发经验谈

某b项目是我首次采用was环境下架构和开发的手机wap应用,尽管做到了该项目的主程,但对此项目的全面构件依然有不清楚的地方,因此在这里我只能简单的谈谈开发中遇到的问题怎么处理和应对办法. 记得第一天接触这个项目时,只记得些案例代码(不知道那些是对的,那些是错的)似曾相识,但不懂如何动手写下第一个helloword,因其中的基于接口开发的ejb的架构以前根本就没接触过.好了,没办法,于是只有硬着头皮去尝试第一个基于接口开发的ejb的第一个查询方法(呵呵最简单了吧).因为一切都是新的,一没有相对完整

FLV视频在IIS6.0下不能播放 处理的方法

FLV视频在IIS6.0下不能播放 Flash视频由于其较高的压缩率和优越的下载速度,前景普遍看好,同时也为Flash课件增色不少.然而,在FLV视频播放中,却有两个头痛的问题    一.FLV视频在IIS 6.0中不能调用问题  早期版本的 IIS 不需要对 Flash 视频流做任何修改.在 Windows 2003 附带的默认 Web 服务器 IIS 6.0 中,服务器需要借助 MIME 类型来确认 FLV 文件为流媒体.   解决办法大致有三种:   1.修改服务器.既然Web服务器上没有

windows下mongodb基础玩法系列二CURD操作(创建、更新、读取和删除)

windows下mongodb基础玩法系列 windows下mongodb基础玩法系列一介绍与安装 windows下mongodb基础玩法系列二CURD操作(创建.更新.读取和删除) 简单说几句 在mongodb中3元素:db(数据库).collection(集合).document(文档) 其中collection类似于数据库中的表,document类似于行,这样一来我们就将内容对比起来记忆学习了. 数据格式 MongoDB documents是BSON格式(一种类json的一种二进制形式的存

.NET下对MongoDB进行操作(二)

这次说下关于利用C#driver,对mongoDB进行简单的查询. 我们可以利用Query类中的静态方法来创建一系列query,达到查询的目的. Query在using MongoDB.Driver.Builders这一名称空间中. 1. 单一条件查询,可以参考如下代码: var query = Query.EQ("ColName", "Value"); foreach (BsonDocument doc in collection.Find(query)) { D

iOS7下滑动返回与ScrollView共存二三事

[转载请注明出处] = =不是整篇复制就算注明出处了亲... iOS7下滑动返回与ScrollView共存二三事 [前情回顾] 去年的时候,写了这篇帖子iOS7滑动返回.文中提到,对于多页面结构的应用,可以替换interactivePopGestureRecognizer的delegate以统一管理应用中所有页面滑动返回的开关,比如在UINavigationController的派生类中 1 //我是一个NavigationController的派生类 2 - (id)initWithRootV