redis3.0管道pipeline支持及遇到的问题

本文介绍了在redis3.0集群中,由于slot导致的批量操作难题,以及如何通过自定义pipeline解决这个问题。文中详细阐述了整体思路,包括预加载slot-jedisPool关系,计算key的slot值,根据slot获取pipeline,以及批量操作后的关闭流程。同时,文章提到了多线程操作pipeline时需要注意的线程安全问题。
摘要由CSDN通过智能技术生成

redis3.0管道pipeline支持及遇到的问题

无关紧要的屁话

hello,我又回来啦,消失的这一年时间发生了好多事呀,换了工作,当了房奴,在这里祝天下太平,苍生幸福~

惯例

前言

最近项目当中遇到需要对数据落地到redis,并且集群使用了最新的redis3.0,满心欢喜的使用新功能,压测的时候却发现吞吐只有几万,达不到要求怎么办,嘿,多次相同操作pipeline有巨大优势,于是,管道加上,什么?redis3.0不支持管道,没办法,只有自己造轮子了。。。

整体思路是:

首先我们要知道为什么现在redis3.0不支持管道,现redis-cluster是采用slot方式写入数据(查找这个数据对应的槽位的方法就是对数据的key取模,即 CRC16(key) mod 16384,得到的结果就是写入数据存放的slot位置 ),导致想批量进行操作得数据位于不同slot上,从而操作失败。
而由于key是我们设置的,所以我们可以通过预先计算key所对应的slot(写了半天crc发现jedis自带计算方法。。。),然后再将数据进行一个归纳,将属于相同redis分片上的key放入相同的一个pipeline当中,然后在整体对所有pipeline进行一个sync同步即可。

1、对redis-cluster进行预加载,将每个分片对应的slot-jedisPool关系保存到本地缓存当中
2、从一批数据当中依次获得相应的key
3、通过key计算出对应的slot值
4、通过slot值获得相应的pipeline,并缓存产生的pipeline
5、将redis操作放入相应的pipeline
6、对缓存当中的所有pipeline依次进行一个sync
7、关闭对应的pipeline和jedis
8、新一批数据来了之后重复以上2~7过程

注意,这里有一个小坑:

因为pipeline不支持多线程操作,并且在进行sync之后,管道并没有消失,仍然持有jedis的client对象,如果对象池归还了jedis,但是这个jedis对象的client被pipeline持有,会导致线程不安全报错。所以我这里在每次使用完一个pipeline之后都会进行一个close,保证了每次操作的client和pipeline都是新的对象。

正文

由于项目需要,我的代码做了相应的改动,这里只列出相关核心代码,读者需要的话可以自行调试改动:

找出host和jedisPool的映射关系
JedisPoolConfig config = new JedisPoolConfig();
config
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值