jedis的ShardedJedisPool链接池的扩容问题
回顾上一篇文章jedis连接池的构建。
我们来分析ShardedJedisPool的基于客户端分片所可能带来的问题:扩容
ShardedJedisPool的节点扩容 。ShardedJedisPool采用的 是客户端分片模式 ,我们来看一下Sharded的初始化代码,获取节点信息后,其节点按照权重*160个的虚拟节点,将创建的节点放在TreeMap中,value为虚拟节点对应的 正式分片信息。
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());
}
}
至于为什么创建160个虚拟节点与一致性hash一致,单一的节点很可能导致数据的分布不均。
其后只要遵循同样的 规则,set和get,即可满足相同的 key到相同的 节点上,其代码如下:
其后我们在每次之心jedis操作是先通过可以获取其对应的连接,其代码如下,其依赖于treemapd.tailMap()实现:
public R getShard(String key) {
return resources.get(getShardInfo(key));
} 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());
} public S getShardInfo(String key) {
return getShardInfo(SafeEncoder.encode(getKeyTag(key)));
}
回到我们的问题,扩容:
虚拟节点的创建将数据均匀的分布到各个节点,但是随着节点的扩容,伴随的问题节点数据的迁移与拷贝,但是什么节点此hash并不是一致性hash,也不是集群模式可以很容易的分配槽点,我们也很难确定什么样的数据需要拷贝到什么新的节点,所以这就给节点扩容带来了困难,扩容必然存在redis数据的丢失,需要有相应的 兼容策略,如数据缺失的兜底策略。
那么我们有什么办法来避免这种情况么 ?
最简单的 就是 prehash,即提前创建相对多的分片,可以将多个集中在单台服务器上,这虽然会带来一定资源的浪费,但是在数据膨胀需要迁移时,我们只需将相应的节点迁移出去,就避免了扩容的 问题。
同时 我们可以注意到 jedis采用的 hash算法是 MurmurHash,这个hash算法是一种非加密型算法,其会比MD5,SHA1,SHA256这些加密算法快很多倍,目前Redis,Memcached,Cassandra,HBase,Lucene都是使用这个hash算法。
最新文章
- java 解 poj 1000
- SOLID面向对象的五个设计原则,留空待学习。
- EF联合查询的新用法
- 剑指offer系列34----按之字形顺序打印二叉树
- 类的__slots__属性
- 理解js中的闭包
- require.js入门指南(三)
- ACE的包装器
- AVAudioRecorder 录制音频
- yii
- Oracle 字符集的查看和修改 -转
- verilog中读取文件中的字符串_modelsim高级仿真
- MVC区域 vs2013 mvc 搭建基架项
- (NO.00003)iOS游戏简单的机器人投射游戏成形记(十九)
- 团体程序设计天梯赛(CCCC) L3014 周游世界 BFS证明
- SSH框架学习摸索记
- .NET项目中使用PostSharp
- Orchard Core 中数据库使用postgresql-10
- hdu-5889-最短路+网络流/最小割
- android 的几个黄色警告解决办法(转)
热门文章
- java并发初探ThreadPoolExecutor拒绝策略
- Prometheus组件
- JetBrains IntelliJ IDEA(IJ)v2019.3.3/3.1/3.2/3.4/3.5 for mac/windows/linux 详细安装破解教程
- 关于fpga的后仿真重要性
- pyhon 内置函数
- centos7安装mariadb(mysql)
- DeprecationWarning:&#39;open()&#39; is deprecated in mongoose>;=4.11.0,use &#39;openUri()&#39; instead or set the &#39;useMongoClient&#39; option if using &#39;connect()&#39; or &#39;createConnection&#39;
- CentOS 7安装/卸载Redis,配置service服务管理
- ubuntu14安装一些常用的软件
- Day4 - L - Tram POJ - 1847