回顾上一篇文章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算法。

jedis的ShardedJedisPool链接池的扩容问题的更多相关文章

  1. jedis 链接池使用(转)

    Jedis作为redis的最佳客户端,它提供了连接池的特性,“连接池”在通常情况下可以有效的提高应用的通信能力,并且这是一种良好的设计模式.Jedis的连接池设计基于apache commons-po ...

  2. Jedis分片Sentinel连接池实验

    Jedis分片Sentinel连接池实验 1.起因 众所周知,Redis官方HA工具Sentinel已经问世很久了,但令人费解的是,Jedis官方却迟迟没有更新它的连接池.到目前Maven库中最新的2 ...

  3. c3p0链接池

    频繁的链接数据库是非常消耗性能的,所以就采用了将一定量的链接保存在一个池中,这个池我们叫做链接池. 详细请看:http://baike.baidu.com/link?url=dlTW-fTS3N_-j ...

  4. ServiceStack.Redis 使用链接池方法

    PooledRedisClientManager 1.RedisManage.cs public static class RedisManager { private static PooledRe ...

  5. 自定义JDBC链接池

    上篇简单介绍了jdbc链接数据库: 本篇就说一下自定义连接池以及增删改查的测试: 自定义连接池 自定义链接池的原因 JDBC连接中用到Connection   在每次对数据进行增删查改 都要 开启  ...

  6. 数据库链接池c3p0的配置

    由于我看的是远古教程,所以里面各种驱动jar包还有c3p0包都是远古版本,对于最新版本的jdbc已经失去的作用,所以我在这里重写一下! 1.首先是c3p0的位置,package的外面,src的里面 2 ...

  7. c3p0链接池配置使用

    c3p0链接池初步使用:直接上代码 c3p0是开源面粉的连接池,目前使用它的开源项目主要有:Spring,Hibernate等,使用时需要导入相关jar包及配置文件c3p0-config.xml文件 ...

  8. 诡异的druid链接池链接断开故障经验总结

    背景 症状 排查 修复 背景 最近在陆续做机房升级相关工作,配合DBA对产线数据库链接方式做个调整,将原来直接链接读库的地址切换到统一的读负载均衡的代理 haproxy 上,方便机柜和服务器的搬迁. ...

  9. java 代码实现使用Druid 链接池获取数据库链接

    因为原先使用的c3p0链接池,时常出现:APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks,以及出 ...

随机推荐

  1. 使用 sp_attach_db 系统存储过程附加数据库时---转载

    //附加数据库 sp_attach_db 当使用 sp_attach_db 系统存储过程附加数据库时. sp_attach_db:将数据库附加到服务器. 语法 sp_attach_db [ @dbna ...

  2. pip升级报错(权限问题)

    今天跟新pip的时候错一个接一个 看到拒绝访问应该是权限的问题,想起安装的时候选择谁可以使用软件(大概是这样的一个选项),选择了“只有我”,选择所有用户应该就不会存在这个问题了,那么怎么解决呢? 敲黑 ...

  3. SpringCloud学习之Zuul路由转发、拦截和熔断处理(七)

    Spring Cloud Zuul 服务网关是微服务架构中一个不可或缺的部分.通过服务网关统一向外系统提供REST API的过程中,除了具备服务路由.均衡负载功能之外,它还具备了权限控制等功能. Sp ...

  4. luogu P2763 试题库问题

    本题可以用最大流也可以用最大匹配(本质一样),用dinic最大流好建图,但码量大,匈牙利码量小,建图费点劲. 最大流:依旧是设一个源点一个汇点,对于每一个种类,连一条到汇点的边,capacity为需要 ...

  5. 5.7 Nginx 其他模块

  6. jmeter学习笔记---循环控制器计数器函数助手

    循环控制器与计数器,以及函数助手需要配合使用,实现循环 循环控制器的“循环次数”输入最大循环次数的参数 计数器:除输入最大值外,还需要输入“引用名称”,供后续请求使用 请求中,如果需要实现循环,需要借 ...

  7. L1-046. 整除光棍(模拟除法)

    题意: 这里所谓的“光棍”,并不是指单身汪啦~ 说的是全部由1组成的数字,比如1.11.111.1111等.传说任何一个光棍都能被一个不以5结尾的奇数整除.比如,111111就可以被13整除. 现在, ...

  8. Express 应用程序生成器

    通过应用生成器工具 express-generator 可以快速创建一个应用的骨架. express-generator 包含了 express 命令行工具.通过如下命令即可安装: $ npm ins ...

  9. mysql提示 Lock wait timeout exceeded解决办法 事务锁死

    查询  select concat('KILL ',id,';') from information_schema.processlist; 复制结果 新建sql脚本粘贴并执行

  10. 结题报告:luogu P2014

    题目链接:P2014 选课 简单的树形\(dp\),借助\(dfs\)实现. 一般的树形\(dp\)数组是需要二维的,其中一维记录节点(编号或父/子节点的状态(有时三维)),另一维记录权值或计数. 重 ...