博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Jedis之ShardedJedis虚拟节点一致性哈希分析
阅读量:5974 次
发布时间:2019-06-19

本文共 2256 字,大约阅读时间需要 7 分钟。

hot3.png

Jedis之ShardedJedis虚拟节点一致性哈希分析 博客分类: 缓存 算法

Jedis之ShardedJedis一致性哈希分析

 

ShardedJedis通过一致性哈希实现的的分布式缓存。主要思路:

  • redis服务器节点划分:将每台服务器节点采用hash算法划分为160个虚拟节点(可以配置划分权重)

  • 将划分虚拟节点采用TreeMap存储

  • 对每个redis服务器的物理连接采用LinkedHashMap存储

  • 对Key or KeyTag 采用同样的hash算法,然后从TreeMap获取大于等于键hash值得节点,取最邻近节点存储;当key的hash值大于虚拟节点hash值得最大值时,存入第一个虚拟节点

  • sharded采用的hash算法:MD5 和 MurmurHash两种;默认采用64位的MurmurHash算法;

 

源码:

1
2
3
4
5
6
7
8
9
public 
class 
Sharded<R, S 
extends 
ShardInfo<R>> {
 
  
public 
static 
final 
int 
DEFAULT_WEIGHT = 
1
;
  
private 
TreeMap<Long, S> nodes;
  
private 
final 
Hashing algo;
  
private 
final 
Map<ShardInfo<R>, R> resources = 
new 
LinkedHashMap<ShardInfo<R>, R>();
  
........................
  
........................
}

这个类维护了一致性哈希后的物理机器和虚拟节点的映射关系,看一张图你会秒懂,

 

TreeMap<Long, S> nodes,存储的是虚拟节点和key的映射关系。有了虚拟节点,还要找到真正的存储位置。

Map<ShardInfo<R>, R> resources维护了虚拟节点和真正的存储位置的映射关系。

也是说,hash(key) -> virtual node -> real node;  

 

jedis划分虚拟节点的逻辑代码,在Sharded类中,方法是initialize。这是在实例化对象池ShardedJedisPool过程中执行的划分虚拟节点。 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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 
{
            
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());
    
}
}

以上代码就是划分虚拟节点的逻辑。

 

那么ShardedJedis客户端是如何执行set key value呢?

通过这里可以看出还是通过Jedis客户端执行的set key value。

1
2
3
4
public 
String set(String key, String value) {
  
Jedis j = getShard(key);
  
return 
j.set(key, value);
}

看一下代码中大体的逻辑,首先通过key得到ShardInfo,然后通过ShardInfo得到泛型Jedis客户端。

Sharded.java

1
2
3
public 
R getShard(
byte
[] key) {
  
return 
resources.get(getShardInfo(key));
}
1
2
3
4
5
6
7
public 
S getShardInfo(
byte
[] key) {
  
SortedMap<Long, S> tail = nodes.tailMap(algo.hash(key));
  
if 
(tail.isEmpty()) {
    
return 
nodes.get(nodes.firstKey());
  
}
  
return 
tail.get(tail.firstKey());
}

来看一下ShardedJedis的继承关系吧,

还有ShardInfo和JedisShardInfo继承关系,

参考:

 

http://my.oschina.net/xinxingegeya/blog/391713

转载于:https://my.oschina.net/xiaominmin/blog/1599290

你可能感兴趣的文章
JavaScript学习总结(9)——JS常用函数(一)
查看>>
Maven+SpringMVC+MyBatis实现系统(一)
查看>>
易宝典文章——如何在Exchange 2010中使用PowerShell文本文件批量移动邮箱
查看>>
智能dns 根据地区解析
查看>>
VS2012配置Git并连接到osc@git
查看>>
索尼高清影视技术学院参观观后感
查看>>
jQuery 文本编辑器插件 HtmlBox 使用
查看>>
怎么看自己服务器的带宽?
查看>>
go的错误处理
查看>>
apache2.4.4的安装过程
查看>>
php5.3安装oracle的扩展oci8与pdo_oci
查看>>
发送超长短信的协议格式
查看>>
CentOS 6.x 快速安装L2TP ***
查看>>
mysql主主复制(双主复制)配置步骤
查看>>
一篇文章能够看懂基础源代码之JAVA篇
查看>>
什么是大数据技术架构
查看>>
【分享】如何救援記憶卡中誤刪的資料
查看>>
北方计算机专修学院“展示自我 秀出风采” 网页创意设计大赛成功举办
查看>>
DNS解析相关实验:7台主机的恩怨情仇
查看>>
Goldengate双向复制配置
查看>>