redis cluster支持pipeline的实现思路

 更新时间:2021年06月23日 16:49:15   作者:mushishi  
本文给大家介绍redis cluster支持pipeline的实现思路,在 cluster 上执行 pipeline 可能会由于 redis 节点扩缩容 中途 redirection 切换连接导致结果丢失,具体细节问题请参考下本文

什么是pipeLine 为什么使用pipeLine ?

上篇文章给大家介绍过redis为什么要提供pipeline功能 今天给大家普及redis cluster如何支持pipeline?

管道(pipeline)将客户端 client 与服务器端的交互明确划分为单向的发送请求(Send Request)和接收响应(Receive Response):用户可以将多个操作连续发给服务器,但在此期间服务器端并不对每个操作命令发送响应数据;全部请求发送完毕后用户关闭请求,开始接收响应获取每个操作命令的响应结果。

管道(pipeline)在某些场景下非常有用,比如有多个操作命令需要被迅速提交至服务器端,但用户并不依赖每个操作返回的响应结果,对结果响应也无需立即获得,那么管道就可以用来作为优化性能的批处理工具。性能提升的原因主要是减少了 TCP 连接中交互往返的开销。

不过在程序中使用管道请注意,使用 pipeline 时客户端将独占与服务器端的连接,此期间将不能进行其他“非管道”类型操作,直至 pipeline 被关闭;如果要同时执行其他操作,可以为 pipeline 操作单独建立一个连接,将其与常规操作分离开来。

当我们要操作一批key时,可以通过 redis pipline 再执行完后一次性读取所有结果来较少网络传输的消耗; 很明显,这有个限制条件 => 这批key的执行必须在同一个连接上

当部署的redis为 standalone 或 master-slave 结构的时候还好,可以从 pool 取出来的连接都是一个 master 节点的, 那要是 redis cluster 的时候怎么办? 这批key 可能在同一个 redis node 也可能分散在多个 redis nodes 这样就是多个连接了

redis cluster 虽然自动对 key 进行了分片,但是它对 client 的要求比较高,需要客户端连接所有 cluster 内的节点(这个和 db client方案类似)并缓存 slots分配信息,然后在客户端采用同样的算法进行hash后定位 key 的 slot 进而定位 slot 所属的 redis 节点,然后获取对应节点的连接发送命令

cluster pipeline 实现思路

java 常用的客户端 jedis,虽然提供了 redis-cluster 功能,但是并没有提供 cluster 下的 pipeline 能力,我们借助它封装好的 JedisClusterCRC16 工具去计算 slot 定位对应 redis node 的连接,按照 redis node 将这批 key 进行分组 ,那么每组 key 就能分别进行 pipeline 逻辑了

伪代码

static List<Integer, HostAndPort> slot2NodeMap; // 可以通过主动调用Jedis.clusterNodes获取slot映射关系,并缓存在本地

List<Object> clusterPipeline(List keys) {
	 Map<HostAndPort, List<String>> node2Keys= new HashMap<>();  // 节点对应keys分组
	for(String key : keys) {
	   // 计算key对应的slot
	   int slot = JedisClusterCRC16.getSlot(key); 
	   // 根据slot获取对应的节点信息,将同一节点的key收在一组
	  node2Keys.get(slot2NodeMap.get(slot)).add(key);
	}

    List<Object> results = new ArrayList();
	// 分组执行
	for (Map.Entry<HostAndPort, List<String>> group : node2Keys) {
		Jedis jedis =  JedisClusterConnectionHandler.getConnectionFromNode(group.key);
		PipeLine pipeline = jedis.pipelined();
		// 执行本组keys 
		 result.addAll(jedis.syncAndReturnAll());
	}
   return results;
}

注意:在 cluster 上执行 pipeline 可能会由于 redis 节点扩缩容 中途 redirection 切换连接导致结果丢失; 可以把 attempts 重试次数设为0 不允许自动切换连接 以感知到异常,然后业务主动进行重试

jedis 官方支持?

github 上其实2017年就有人提交了 cluster pipeline 的pr,维护人员也很乐意 merge 但是~~ 后续跟进比较慢,然后19年 merge review的时候有些异常,提交人也没再跟进,导致一直没有合并成功;
https://github.com/redis/jedis/pull/1455


实现 cluster pipeline 也可以参考这个pr 的提交代码

以上就是redis cluster支持pipeline的实现思路的详细内容,更多关于redis cluster支持pipeline的资料请关注脚本之家其它相关文章!

相关文章

  • Redis与数据库数据一致性的原因及解决方案

    Redis与数据库数据一致性的原因及解决方案

    Redis作为一种高效的键值对存储系统,常用于缓存数据库减少IO操作,下面这篇文章主要介绍了Redis与数据库数据一致性的原因及解决方案,文中介绍的非常详细,需要的朋友可以参考下
    2025-04-04
  • Redis+拦截器实现接口防刷

    Redis+拦截器实现接口防刷

    接口防刷有很多种实现思路,例如:拦截器/AOP+Redis、拦截器/AOP+本地缓存、前端限制等等很多种实现思路,本文主要来讲一下 拦截器+Redis 的实现方式,需要的可以参考下
    2023-08-08
  • Caffeine实现类似redis的动态过期时间设置示例

    Caffeine实现类似redis的动态过期时间设置示例

    这篇文章主要为大家介绍了Caffeine实现类似redis的动态过期时间示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08
  • 设置Redis最大占用内存的实现

    设置Redis最大占用内存的实现

    本文主要介绍了设置Redis最大占用内存的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-05-05
  • redis分布式锁的8大坑总结梳理

    redis分布式锁的8大坑总结梳理

    这篇文章主要介绍了redis分布式锁的8大坑总结梳理,使用redis的分布式锁,我们首先想到的可能是setNx命令,文章围绕setNx命令展开详细的内容介绍,感兴趣的小伙伴可以参考一下
    2022-07-07
  • 浅谈一下如何保证Redis缓存与数据库的一致性

    浅谈一下如何保证Redis缓存与数据库的一致性

    这篇文章主要介绍了一下如何保证Redis缓存与数据库的一致性,今天这篇文章就带你详细了解一下四种同步策略,需要的朋友可以参考下
    2023-03-03
  • Redis实现持久化的方式汇总

    Redis实现持久化的方式汇总

    Redis是一种高级key-value数据库。它跟memcached类似,不过数据可以持久化,而且支持的数据类型很丰富。今天我们就来看看如何实现Redis持久化,需要的朋友可以参考下
    2022-10-10
  • Redis中跳表的实现原理分析

    Redis中跳表的实现原理分析

    Redis中的跳表是一种高效的多层链表结构,通过随机概率算法决定节点的层数,从而实现快速的插入、删除和查询操作,跳表的平均时间复杂度为O(logn),最差情况为O(n),每个节点包含值和指向更高层节点的指针,以及回退指针以提高操作效率
    2025-02-02
  • Redis中常见的几种集群部署方案

    Redis中常见的几种集群部署方案

    本文主要介绍了Redis中常见的几种集群部署方案,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • Redis实现用户签到的示例代码

    Redis实现用户签到的示例代码

    Redis的位图可以高效实现用户签到功能,每个bit位对应一个签到状态,节省存储空间,利用SETBIT、GETBIT等命令操作签到数据,可统计连续签到天数和本月签到情况,感兴趣的可以了解一下
    2024-09-09

最新评论