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
http://my.oschina.net/xinxingegeya/blog/391713
相关推荐
带虚拟节点的一致性哈希是其优化策略之一,以提高哈希表的负载均衡性。 在一致性哈希中,每个实际的物理节点会被映射到哈希环上的多个虚拟节点,这些虚拟节点均匀分布在环上。这样做的好处在于,当新增或删除物理...
首先,一致性哈希的基本原理是将整个哈希空间组织成一个虚拟的圆环,每个数据项和服务器节点都通过哈希函数映射到这个环上。这样,当新的节点加入或退出时,只有与该节点相邻的几个数据项需要重新映射,大大降低了...
4. **解决数据迁移问题**:在一致性哈希中,当新增或删除一个节点时,只有与之相邻的节点受影响,其他节点不受影响,大大降低了因节点变动带来的数据迁移规模。 5. **Java实现**:在Java中,可以使用Guava库的...
5. 一致性哈希:通过一致性哈希算法,实现Redis集群的数据分布,保证在添加或移除服务器时,数据迁移的影响最小。 在实际项目中,开发人员通常会将`jedis-2.1.0.jar`和`jedis-2.0.0.jar`这样的库文件包含到项目的类...
1. **虚拟节点**:一致性哈希引入了虚拟节点的概念,每个实际节点可以对应多个虚拟节点,这些虚拟节点均匀分布在哈希空间中。这样即使增加或减少实际节点,只需映射或删除少量的虚拟节点,降低了对整体哈希映射的...
Redis的事务可以确保一组操作要么全部成功,要么全部失败,保证了数据的一致性。在Java中,可以调用Jedis的multi开始一个事务,然后执行一系列的命令,最后通过exec提交事务。如果在事务过程中出现错误,所有命令都...
Transaction则提供了原子性操作,确保数据一致性。 **源码分析** Jedis的源码对于理解其工作原理和优化自己的实现非常有帮助。通过查看源码,开发者可以了解如何封装Redis命令,如何处理网络通信,以及如何实现...
Jedis支持的操作包括但不限于连接管理、字符串操作、哈希处理、列表操作、集合操作、有序集合操作、发布/订阅、事务处理、脚本执行等。 在Jedis 3.0版本中,有以下几个关键的改进和特性: 1. **连接池支持**:...
通过Redlock算法,Jedis可以提供分布式锁服务,保证多节点间的协调一致性。 总之,Jedis 2.9.0是Java开发者与Redis交互的重要工具,它提供了一套完整的Redis操作接口,同时具备良好的性能和稳定性。通过深入学习和...
4. 分布式锁:Jedis提供了基于Redis的分布式锁实现,可以在多节点环境下保证数据的一致性。 5. 事务支持:Jedis实现了Redis的事务功能,允许用户一次性执行多个操作,并确保原子性。 在使用Jedis API进行开发时,...
4. 脚本支持:通过Lua脚本实现更复杂的逻辑,确保执行的原子性和一致性。 5. 缓存操作:提供过期策略,可自动清除不再需要的数据,保持缓存的高效性。 6. 集群支持:Jedis也支持Redis集群,可以在多个节点间分散数据...
通过一致性哈希算法,可以平滑地添加或移除节点,确保数据分布的均衡。 2. **Transactions Enhancements**: 提供了更好的事务处理机制,支持多条命令原子执行,确保在高并发环境下数据的一致性。 3. **LUA ...
- 命令执行:Jedis提供了与Redis命令一致的方法,如`incr(key)`实现自增操作,`hset(key, field, value)`操作哈希表。 - 事务支持:通过`Multi()`开启事务,接着连续执行多个命令,最后通过`exec()`提交。如果其中...
5. **脚本操作**:Jedis支持使用`eval`和`evalsha`命令执行Lua脚本,可以将一系列复杂操作打包成一个原子操作,提升性能和一致性。 6. **持久化操作**:Jedis提供了对Redis RDB和AOF两种持久化方式的支持,可以通过...
2. **事务处理**:Jedis提供了事务支持,允许用户在一个原子操作中执行多个命令,确保数据的一致性。 3. **发布/订阅**:Jedis实现了Redis的发布/订阅功能,使得应用可以实现消息传递,构建实时的消息系统。 4. **...
这允许开发者在一个原子操作中执行多个命令,保证了数据的一致性。 4. **发布订阅**:Jedis提供了`subscribe`和`publish`方法,实现了Redis的消息发布/订阅模式。这在构建实时消息系统或者分布式事件总线时非常有用...
Transaction则允许原子性地执行一组命令,确保数据一致性。 4. **集群支持**:Jedis 2.9.2支持Redis Cluster,可以透明地连接到多节点集群,并自动处理槽的映射,使得在分布式环境中操作Redis变得更加便捷。 5. **...
而一致性哈希允许我们为每个节点分配多个虚拟节点,使得数据在节点间的分布更加均匀。 其次,一致性哈希使用虚拟节点策略。每个物理节点在哈希环上可以有多个副本,这些副本均匀分布在环上,使得即使有节点失效,...
一致性哈希是分布式系统中常用的算法,用于解决节点增减时数据迁移的问题。它将键映射到哈希环上,通过虚拟节点和哈希函数确保键的分布相对均匀。Java中,可以使用开源库如Voldemort或Redisson来实现一致性哈希。 ...
- **主从复制**:支持SLAVEOF命令,可以设置Jedis客户端连接到Redis的从节点。 5. **2.9.1版本更新** - **性能优化**:Jedis 2.9.1可能包含了一些性能上的改进,比如更快的命令执行和更高效的内存管理。 - **Bug...