jedis shardedjediss怎么调用jedis

推荐这篇日记的豆列
······菜菜光 的BLOG
用户名:菜菜光
文章数:149
评论数:118
访问量:149403
注册日期:
阅读量:5863
阅读量:12276
阅读量:344937
阅读量:1045356
51CTO推荐博文
1.pom.xml中依赖如下:&&&&&dependency&
&&&&&&&groupId&redis.clients&/groupId&
&&&&&&&artifactId&jedis&/artifactId&
&&&&&&&version&2.6.1&/version&
&&&&/dependency&2.jedis pool中ping的产生线上storm的bolt使用jedis pool操作redis,高峰时压力一直比较大,每s处理量多达10w/s,redis持续跑满(单线程,cpu100%),对monitor数据分析,发现50%以上的都是ping操作,ping是用来检测redis是否可用的操作,在jedis pool中由两个参数控制:setTestOnBorrow&//获取连接时是否触发ping
setTestOnReturn&//释放连接时是否触发ping默认两个值都是true的,设置为false即可3.获取不到资源时jedis的处理1)当setBlockWhenExhausted设置为true(默认即为true)时,阻塞setMaxWaitMillis时间(默认为-1,会一直阻塞),超过时间限制则抛出异常:Exception&in&thread&"main"&redis.clients.jedis.exceptions.JedisConnectionException:&Could&not&get&a&resource&from&the&pool
&&at&redis.clients.util.Pool.getResource(Pool.java:53)
&&at&redis.clients.jedis.JedisPool.getResource(JedisPool.java:99)
&&at&main.java.JedisPoolTest.main(JedisPoolTest.java:20)
Caused&by:&java.util.NoSuchElementException:&Timeout&waiting&for&idle&object
&&at&mons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:442)
&&at&mons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:360)
&&at&redis.clients.util.Pool.getResource(Pool.java:51)
&&...&2&more2)当setBlockWhenExhausted(false);设置为false时,直接抛出异常,不会阻塞4.jedis的默认db都是0,可以通过构造函数的参数进行设置5.防止资源泄露,在catch异常的时候使用JedisPool.returnBrokenResource释放连接,可以使用JedisPool.getNumActive获取当前的活动连接数6.pool的初始化经常使用静态代码块完成7.sharding的模式也是支持pipline的附1个jedissharding pipeline的例子:package&main.
import&redis.clients.jedis.JedisPoolC
import&redis.clients.jedis.JedisShardI
import&redis.clients.jedis.ShardedJedisP
import&redis.clients.jedis.ShardedJ
import&redis.clients.jedis.ShardedJedisP
import&java.util.L
import&java.util.LinkedL
public&class&JedisPoolTest&{
&&private&static&ShardedJedisPool&pool&=&
&&private&static&ShardedJedisPipeline&pip&=&
&&&public&static&void&main(String[]&args)&{&&&&&&&
&&&&&&JedisPoolConfig&jc&=&new&JedisPoolConfig();
&&&&&&jc.setBlockWhenExhausted(false);
&&&&&&jc.setMaxIdle(8);&
&&&&&&jc.setMaxTotal(20);&
&&&&&&jc.setTestOnBorrow(false);
&&&&&&jc.setTestOnReturn(false);
&&&&&&jc.setMaxWaitMillis(-1);
&&&&&&JedisShardInfo&jedisShardInfo1&=&new&JedisShardInfo("192.168.101.42",6379);
&&&&&&JedisShardInfo&jedisShardInfo2&=&new&JedisShardInfo("192.168.101.42",6380);
&&&&&&List&JedisShardInfo&&list&=&new&LinkedList&JedisShardInfo&();&&
&&&&&&list.add(jedisShardInfo1);
&&&&&&list.add(jedisShardInfo2);
&&&&&&pool&=&new&ShardedJedisPool(jc,&list);
&&&&&&ShardedJedis&jedis&=&pool.getResource();
&&&&&&pip&=&jedis.pipelined();
&&&&&&long&start&=&System.currentTimeMillis();
&&&&&&for(int&i&=&0;i&&=&100;i++){&&&&&&&&&&
&&&&&&&&&String&key&=&"shardpool"&+&String.valueOf(i);
&&&&&&&&&pip.del(key);&&
&&&&&&&&&pip.set(key,&"test");&&&
&&&&&pool.returnResource(jedis);&
&&&&&pip.syncAndReturnAll();
&&&&&&long&end&=&System.currentTimeMillis();
&&&&&&long&elapse&=&end&-&
&&&&&&System.out.println("10000&itmes&elapse&time&is&"&+&String.valueOf(elapse));
}本文出自 “” 博客,请务必保留此出处
了这篇文章
类别:┆阅读(0)┆评论(0)上一篇中介绍了ShardedJedis的基本使用方法以及演示了一个简单的例子,在这一篇中我们来介绍了ShardedJedis的原理。
1.获取数据过程
首先我们来看一下ShardedJedis的一个继承关系
看完了图,那么我们一步一步跟着我们的代码调用来看下,以我们最简单的 ShardedJedis.get()方法为例:
这边有调用一个getShard 方法,参数为我们传入的key,然后返回一个普通的jedis对象,那么这个getShard是用来做什么的呢,大家可能已经猜到了,这个方法就是会根据我们传入的key做一致性哈希判断,然后返回key落到的那个redis实例上的一个redis连接,不同的key返回的redis连接可能是不同的。
进入getShard 方法,你会发现这个实现是在Sharded类中实现的(看上面的类图可以发现顶层的Sharded类),代码如下:
上面的方法是层层调用的关系,在这边不细说,我们主要看下红框的那个方法实现(上面的nodes变量是一个TreeMap 类型, algo 是Hashing类型,即key分片所使用的hash算法,这个在前一篇有简单说过),那么这段代码的含义我们大概成猜出来了,
就是在一个TreeMap中取出大于等于key之后的部分视图SortMap
在SortMap取得第一个键值对的值,然后返回一个 S 对象,
然后根据这个S 对象,去resources(resources = new LinkedHashMap&ShardInfo&R&, R&())中get一个R对象
那么这个S、 R对象各自代表什么呢?看下面的代码
可以得出& S = JedisShardInfo, R = Jedis 对象,即在TreeMap了划分的虚拟节点的信息,LinkedHashMap中存储了服务器的物理连接。&
JedisShardInfo具体信息如下:里面包含了jedis服务器的一些信息,最重要的是它的父类中有一个weight字段,作为本jedis服务器的权值。
ok,那我们了解了实际上就是根据jedis服务器的信息去获取一个jedis的连接,返回给上层调用。
我们可以梳理下这个逻辑:
当我们使用ShardedJedis去查一个key时,首先它会把这个key进行一个hash算法
根据这个hash值然后去treeMap中,查出这个key落在哪个实例中,并返回redis实例对应的具体信息
根据这个redis的实例信息,到一个保存jedis链接和实例信息对应关系的LinkedHashMap中找到这个jedis连接
最终返回jedis连接,执行对象的命令操作(到这步后实际上和单机操作一样了)
那么我们的nodes 服务器虚拟节点和resources 服务器物理连接是什么时候初始化的呢,接下来继续看
2.nodes和resources 初始化
我们看到Sharded的构造方法
这边有一个initialize方法,看其实现
具体细节就不说了,根据上面的,我们就知道是在这边进行了初始化,将每台服务器节点采用hash算法划分为160个虚拟节点(可以配置划分权重),保存在TreeMap中,
然后把每台服务器节点的信息和物理连接以键值对保存LinkedHashMap中。
然后通过一系列的查找,发现Sharded的构造方法其实是在我们 jedisPool.getResource() 时就完成的
纳尼? 每次jedisPool.getResource()
才初始化?那会不会造成很慢呢,其实不用担心,其底层是使用了commons.pool来进行连接池的一些操作,会根据我们配置的连接池参数来生成对应的连接并保存,其中的细节很复杂,博主没有继续深究,实现其实和连接池是一致的。
ShardedJedis分布式具体的的实现思路:
redis服务器节点划分:将每台服务器节点采用hash算法划分为160个虚拟节点(可以配置划分权重)
将划分虚拟节点采用TreeMap存储
对每个redis服务器的物理连接采用LinkedHashMap存储
对Key or KeyTag 采用同样的hash算法,然后从TreeMap获取大于等于键hash值得节点,取最邻近节点存储;当key的hash值大于虚拟节点hash值得最大值时,存入第一个虚拟节点
sharded采用的hash算法:MD5 和 MurmurHash两种;默认采用64位的MurmurHash算法;
&好了,大概的实现如上面所说的,都是图可能会有点乱,大家如果有什么问题或者发现了什么错误,please tell me!JedisPool(非切片链接池)和ShardedJedisPool(切片链接池)有什么区别 - 开源中国社区
当前访客身份:游客 [
当前位置:
1.添加缓存的时候用ShardedJedisPool.为什么不用JedisPool。(网上例子)
2.这两个对象有什么区别。为什么很多例子都是JedisPool进行删除。用ShardedJedisPool进行添加(ShardedJedisPool没有删除方法)
3.JedisPool(非切片链接池)和ShardedJedisPool(切片链接池)有什么区别
共有4个答案
<span class="a_vote_num" id="a_vote_num_
JedisPool连一台Redis,ShardedJedisPool连Redis集群,通过一致性哈希算法决定把数据存到哪台上,算是一种客户端负载均衡,所以添加是用这个(Redis 3.0之后支持服务端负载均衡)
删除那个问题的答案就显而易见了,总不可能随机找一个Redis服务端去删吧
<span class="a_vote_num" id="a_vote_num_
引用来自“终曲”的评论
JedisPool连一台Redis,ShardedJedisPool连Redis集群,通过一致性哈希算法决定把数据存到哪台上,算是一种客户端负载均衡,所以添加是用这个(Redis 3.0之后支持服务端负载均衡)
删除那个问题的答案就显而易见了,总不可能随机找一个Redis服务端去删吧
哦...谢谢你的讲解。说的真好。。。
<span class="a_vote_num" id="a_vote_num_
引用来自“终曲”的评论
JedisPool连一台Redis,ShardedJedisPool连Redis集群,通过一致性哈希算法决定把数据存到哪台上,算是一种客户端负载均衡,所以添加是用这个(Redis 3.0之后支持服务端负载均衡)
删除那个问题的答案就显而易见了,总不可能随机找一个Redis服务端去删吧
JedisPool连一台,集群下只能用ShardedJedisPool,因为你不知道从哪台机器上取
<span class="a_vote_num" id="a_vote_num_
谁说的------》ShardedJedisPool没有删除方法???
更多开发者职位上
有什么技术问题吗?
kingjn...的其它问题

我要回帖

更多关于 shardedjedispool 的文章

 

随机推荐