一、为何用?

减少请求次数,将多条请求命令合成一次请求通过管道发给redis server,再通过回调函数一次性接收多个命令的结果,减少网络IO次数,在高并发情况下可带来明显性能提升。注意的是,redis server是单线程,多个命令合成一次请求到达redis server依然还是顺序一个个执行的,仅仅只是减少了请求IO次数。

二、如何用?

RedisCallback和SessionCallBack:

1.作用: 让RedisTemplate进行回调,通过他们可以在同一条连接中一次执行多个redis命令。
2.SessionCalback提供了良好的封装,优先使用它。
3.RedisCallback使用的是原生RedisConnection,用起来比较麻烦,可读性差,但原生api提供的功能比较齐全。

RedisTemplate引入

spring boot 提供了RedisTemplate简化redis客户端的操作,引入:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

代码使用

@Component
public class RedisTest {@AutowiredRedisTemplate<String, Object> redisTemplate;@PostConstructpublic void init() {test1();}public void test1() {List<Object> pipelinedResultList = redisTemplate.executePipelined(new SessionCallback<Object>() {@Overridepublic <K, V> Object execute(RedisOperations<K, V> operations) throws DataAccessException {ValueOperations<String, Object> valueOperations = (ValueOperations<String, Object>) operations.opsForValue();valueOperations.set("yzh1", "hello world");valueOperations.set("yzh2", "redis");valueOperations.get("yzh1");valueOperations.get("yzh2");// 返回null即可,因为返回值会被管道的返回值覆盖,外层取不到这里的返回值return null;}});System.out.println("pipelinedResultList=" + pipelinedResultList);}
}

运行结果:

pipelinedResultList=[true, true, hello world, redis]

由于 RedisCallback 的RedisConnection api都是类似于 Boolean set(byte[] key, byte[] value); key、value都需要转成字节数组这种,不推荐使用。

管道预热代码

有的系统对延迟要求很高,那么redis管道第一次请求很慢,就需要在系统启动时进行管道的预热,保证系统启动后每次请求的低延迟。

    @PostConstructpublic void init() {long startTime = System.currentTimeMillis();redisTemplate.executePipelined(new SessionCallback<Object>() {@Overridepublic <K, V> Object execute(RedisOperations<K, V> operations) throws DataAccessException {operations.hasKey((K) "");return null;}});log.info("redis初始化管道请求end,耗时:{}ms", System.currentTimeMillis() - startTime);}

其它记录:

redis的读写速度十分快,所以系统的瓶颈往往是在网络通信中的延迟,redis可能会在很多时候处于空闲状态而等待命令的到达。为了解决这个问题,可以使用redis的流水线(Pipeline),流水线是一种通讯协议,类似一个队列批量执行一组命令。

集群下优化RedisPipeline操作:https://blog.csdn.net/xiaoliu598906167/article/details/82218525,自己没有实际测试,todo,先记录一下。

pipelining官方解释:

Redis服务器可以实现即使没有读取旧响应的情况下也可以发送新的请求,以这种方式可以发送多个命令到服务器而不用等待回复,最后一次获取全部的回复。这就是Redis Pipelining。

executePipelined() 的官方注释:

在一个管道连接中执行给定的动作对象,并返回结果。但是需要注意的是callback不能返回一个非null的值,callback的值将被pipeline覆盖。这个方法将使用默认的序列化和反序列化方式处理结果集。

execute和executePipelined区别图示:

execute和executePipelined都支持事务管理器,支持multi,watch,exec,discard等事务操作。

redis事务代码:

     @ApiOperation(value = "multi测试接口", notes = "redis事务测试接口")@RequestMapping(value = "/multi", method = RequestMethod.GET)@ResponseBodypublic Map<String, Object> testmulti() {redisManager.setStr("wanwan", "wd小兔兔");List list = (List) redisTemplate.execute((RedisOperations res) ->{//设置监控key,在exec执行前如果这个key对应的值,发生了变化,事务bu执行//通常监控的key可以是ID,也可以是一个对象res.watch("wanwan");// 其实watch可以注释掉,或者设置成不监控res.unwatch();//开启事务,在exec执行前res.multi();res.opsForValue().increment("wanwan", 1);res.opsForValue().set("wanwan2", "我的小兔兔1");Object value2 = res.opsForValue().get("wanwan2");System.out.println("命令在队列,所以取值为空" + value2 + "----");res.opsForValue().set("wanwan3", "我的小兔兔3");Object value3 = res.opsForValue().get("wanwan3");System.out.println("命令在队列,所以取值为空" + value3 + "----");return res.exec();});System.out.println(list);Map<String, Object> map = new HashMap<>();map.put("success", true);System.out.println(";;;" + map.toString());return map;}

事务代码,尚未验证,todo,这里就是记录一下。

redis事务就是基于SessionCallback实现了一个监听watch,如果被监听的键发生了变化就会取消事务,没有变化就执行事务。(注意:即使被赋予了相同的值,同样视为发生变化,不予执行事务)

疑问:如果redis事务中要执行100条命令,那么watch会watch几次?

在执行前一直在watch,但是执行过程中比如开始执行100条命令中的第一条后,
就不会watch了,因为redis时单线程的,你在执行过程中,别的命令根本无法执行。
如果这个事务要执行10分钟,我在这10分钟内通过手动更改一个键的值可以不,答案是不行!因为redis单线程。

redis的事务类似mysql的串行化隔离界别,执行期间不会插入其他语句。redis使用的是乐观锁方式,这种方式允许exec前修改,这时会触发异常通知。

redis通过watch来监测数据,在执行exec前,监测的数据被其他人更改会抛出错误,取消执行。而exec执行时,redis保证不会插入其他语句来实现隔离。(可以预见到此机制如果事务中包裹过多的执行长指令,可能导致长时间阻塞其他人)

RedisTemplate使用PipeLine管道命令相关推荐

  1. RedisTemplate Pipeline 管道使用

    官网文档:https://docs.spring.io/spring-data/redis/docs/current/reference/html/ 一.前言 当需要执行大批量的写入或者查询时,使用 ...

  2. Redis05:Redis的高级特性:expire 生存时间、pipeline 管道、info命令、Redis的持久化、Redis 的安全策略、Redis监控命令-monitor

    一.expire 生存时间 Redis中可以使用expire命令设置一个键的生存时间,到时间后Redis会自动删除它. 它的一个典型应用场景是:手机验证码 我们平时在登录或者注册的时候,手机会接收到一 ...

  3. GPU上创建目标检测Pipeline管道

    GPU上创建目标检测Pipeline管道 Creating an Object Detection Pipeline for GPUs 今年3月早些时候,展示了retinanet示例,这是一个开源示例 ...

  4. php redis pipeline管道技术

    概念 如果需要一次执行多个redis命令,以往的方式需要发送多次命令请求,有redis服务器依次执行,并返回结果,为了解决此类问题,设计者设计出了redis管道命令:客户端可以向服务器发送多个请求,而 ...

  5. [20180627]测试bbed是否支持管道命令.txt

    [20180627]测试bbed是否支持管道命令.txt --//测试bbed是否支持管道命令.txt 1.环境: SCOTT@test01p> @ ver1 PORT_STRING       ...

  6. 谈谈Linux下的数据流重定向和管道命令

    一.标准输入.标准输出.错误输出概述 1.标准输入(stdin)是指令数据的输入,代码为0,使用<或者<<,默认是键盘. 2.标准输出(stdout)是指令执行成功返回的结果,代码为 ...

  7. linux——(8)数据流重定向、管道命令

    概念一:数据流重定向 数据流分输入流和输出流,还有一个标准错误流,负责管理出错信息,比如一般的命令的输出会输出到屏幕上,我们可以用重定向让他输入到某个文件内. 相关操作: 1,标准输入(stdin): ...

  8. 数据流重定向和管道命令, grep, tr,sort, wc, cut,split,tee,sleep(shell 02)

    主要内容 1.标准输入输出和错误 2.管道命令和 grep, tr,sort, wc, cut,split,tee,sleep 标准输入输出和错误 标准输入(stdin) 是指令数据的输入,代码为0, ...

  9. Python 技术篇-通过管道命令获取cmd执行的结果,获取os.system()、subprocess.Popen()执行命令返回的结果

    正常的 os.system() 执行完后只会返回个执行状态值,返回的 0 表示执行成功,1 表示执行失败. 如果想要获取到执行后的结果集,就需要用到管道命令 os.popen(),然后用 read() ...

最新文章

  1. 如何避免重构带来的危险
  2. boost::convert模块实现默认转换器的测试程序
  3. QDoc包括外部代码includingexternalcode
  4. 计算机网络资料篇(二)——快速理解网络协议
  5. 收藏的RabbitMQ资料,分享给大家
  6. 快速幂||取余运算【模板】(洛谷P1226题题解,Java语言描述)
  7. 任务26:dotnet watch run 和attach到进程调试
  8. 机器学习会成为2017年大数据​分析的瓦解者吗?
  9. SPSS实现神经网络(多层感知器)
  10. 【小月电子】ALTERA FPGA开发板系统学习教程-LESSON2 LED灯闪烁
  11. c语言中指数对数函数,在C语言中使用对数函数的方法
  12. 【我的OpenGL学习进阶之旅】什么是PVR文件以及如何打开它?
  13. 拓嘉启远:拼多多行家心得评论的作用
  14. 翻遍“微信小程序”的所有知乎问答,我们整理了大家最关注几个话题
  15. android环信删除会话列表,关于会话列表的置顶聊天
  16. java里面不等于怎么打_不等于在c语言中怎么打
  17. Java自学教程!mysql环境变量配置好了之后怎么办
  18. 灵性图书馆:好书推荐-《太傻天书》
  19. mysql子查询:标量子查询,行子查询,列子查询
  20. selenium驱动Firefox安装和环境配置

热门文章

  1. 蓝桥杯嵌入式 eeprom初次上电判断
  2. Python如何在从循环之外不断获取循环内的数据但不退出循环
  3. for循环内使用异步
  4. 利用exchange实现垃圾邮件过滤
  5. STM32光敏传感器实验
  6. 制作世界人口地图:JSON格式
  7. 【洛谷】P1137旅行计划
  8. linux 交叉编译dbus,expat
  9. 后疫情时代下,家庭服务机器人行业才刚启航
  10. oc预处理和编译的理解