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://yychao.iteye.com/blog/1751583
=================END=================
相关推荐
带虚拟节点的一致性哈希是其优化策略之一,以提高哈希表的负载均衡性。 在一致性哈希中,每个实际的物理节点会被映射到哈希环上的多个虚拟节点,这些虚拟节点均匀分布在环上。这样做的好处在于,当新增或删除物理...
在Java实现中,一致性哈希通常会用到如Jedis、Voldemort等分布式存储库。这些库内部实现了哈希函数和虚拟节点的概念,虚拟节点可以看作是对实际节点的多次映射,增加了哈希空间的覆盖,使得数据分布更均匀。然而,...
5. 一致性哈希:通过一致性哈希算法,实现Redis集群的数据分布,保证在添加或移除服务器时,数据迁移的影响最小。 在实际项目中,开发人员通常会将`jedis-2.1.0.jar`和`jedis-2.0.0.jar`这样的库文件包含到项目的类...
在分布式系统中,数据一致性是至关重要的,而Redis作为一个高性能的键值存储系统,常被用作缓存和分布式锁的解决方案。`ShardedJedis`是Jedis库的一个扩展,用于处理多Redis实例的分片操作,它可以提高对大量数据的...
此外,Jedis还支持Sentinel和Cluster模式,以适应高可用性和分布式环境的需求。 总的来说,这个压缩包提供了在Java环境中使用Jedis与Redis交互的基础。无论是开发简单的单机应用还是构建复杂的分布式系统,这些jar...
3. **哈希操作**:`hset(hashKey, field, value)`设置哈希表字段值,`hget(hashKey, field)`获取哈希表字段值。 4. **列表操作**:`lpush(listKey, value)`向列表头部添加元素,`rpop(listKey)`从列表尾部移除元素。...
Jedis是Redis官方推荐的Java客户端,用于与Redis服务器进行通信。版本2.9.0是Jedis的一个稳定版本,提供了...通过深入学习和使用Jedis,开发者可以更好地理解和掌握Redis的数据结构和操作,提升应用的效率和扩展性。
2. **基本操作**:Jedis提供了对字符串、哈希、列表、集合和有序集合的操作方法。例如,可以使用`set()`和`get()`方法存储和检索字符串,使用`hset()`和`hget()`操作哈希表,`lpush()`和`rpop()`处理列表,`sadd()`...
3. **哈希操作**:添加哈希字段 `jedis.hset("hash", "field", "value")`,获取整个哈希 `jedis.hgetAll("hash")`。 4. **列表操作**:向列表尾部添加元素 `jedis.rpush("list", "item")`,获取列表 `jedis.lrange(...
它以其高性能、高可用性和丰富的数据结构而受到广大开发者喜爱。在这个压缩包中,包含了不同平台下的Redis安装包,以及Jedis驱动,这使得在Windows和Linux环境下都能轻松地使用Redis。 首先,让我们详细了解Redis的...
Transaction则提供了原子性操作,确保数据一致性。 **源码分析** Jedis的源码对于理解其工作原理和优化自己的实现非常有帮助。通过查看源码,开发者可以了解如何封装Redis命令,如何处理网络通信,以及如何实现...
使用`Jedis`对象执行命令,如`set`、`get`、`hset`、`lpush`等,以操作Redis中的键值对、哈希、列表等数据结构。 2. **连接与关闭**: 连接Redis服务器通常使用`connect()`方法,而关闭连接则调用`close()`。源码...
Jedis允许通过Lua脚本来执行Redis的复杂操作,提高性能和一致性。 9. 其他特性: 包括管道(Pipeline)技术,用于批量发送命令;连接监控和断线重连机制;以及支持Redis Sentinel和Cluster的分布式环境。 总结来...
- 在高并发场景下,考虑使用JedisCluster或Sentinel支持的分布式配置,以获得更好的可扩展性和可用性。 通过理解和正确使用Jedis及Apache Commons Pool,Java开发者可以高效地与Redis数据库进行交互,实现数据存储...
总结,Java通过Jedis连接Redis提供了高效的数据交互手段,Jedis连接池能优化资源利用,而对字符串和哈希的操作满足了多种存储需求。在Linux环境中,如CentOS7,可以便捷地部署和管理Redis服务器,从而在实际项目中...
Jedis还支持批量操作,通过`Transaction`类可以实现事务处理,确保一组操作的原子性: ```java jedis.multi(); jedis.set("key1", "value1"); jedis.set("key2", "value2"); List<Object> results = jedis.exec(); ...
Jedis作为Java与Redis之间的桥梁,为开发者提供了简单易用的API,包括字符串、哈希、列表、集合、有序集合等数据类型的操作,以及发布/订阅、事务、脚本执行等功能。Jedis 3.0.0版本对前代进行了优化,提升了性能和...
在本文中,我们将深入探讨Jedis的安装、配置、基本操作以及它在实际应用中的重要性。 一、Jedis简介 Jedis是由Xavier Lachier开发的Java Redis客户端,它提供了丰富的Redis命令支持,包括字符串、哈希、列表、集合...
3. **哈希分片**:Jedis 集群版会自动处理哈希槽分配,确保数据均匀分布。 4. **故障转移**:当某个节点失效时,Jedis 集群会自动检测并重新路由请求到其他正常节点。 5. **分布式锁**:在集群中实现分布式锁,...