当前位置: 首页 > article >正文

Redis7——基础篇(四)

 前言:此篇文章系本人学习过程中记录下来的笔记,里面难免会有不少欠缺的地方,诚心期待大家多多给予指教。

基础篇:

  1. Redis(一)
  2. Redis(二)
  3. Redis(三)

接上期内容:上期完成了Redis的持久化机制的学习。下面开始学习Redis的其他功能,话不多说,直接发车。


一、Redis事务

(一)、定义

Redis事务是一个单独的隔离操作,它将多个命令打包成一个原子操作序列。在事务执行过程中,要么所有命令都被执行,要么都不执行。这确保了数据操作的一致性和完整性。事务中的命令会被依次放入队列中,然后在执行阶段按顺序执行,不会被其它命令插入,不许加塞


(二)、Redis事务和常规事务区别

与传统数据库的事务相比,Redis事务有一些独特之处。传统数据库事务通常支持 ACID 特性(原子性、一致性、隔离性、持久性),而 Redis 事务不仅不保证原子性,而且在隔离性方面也有所不同。

redis特性:

1单独的隔离操作Redis的事务仅仅是保证事务里的操作会被连续独占的执行,redis命令执行是单线程架构,在执行完事务内所有指令前是不可能再去同时执行其他客户端的请求的。
2没有隔离级别概念因为事务提交前任何指令都不会被实际执行,也就不存在”事务内的查询要看到事务里的更新,在事务外查询不能看到”这种问题了。
3不保证原子性Redis的事务不保证原子性,也就是不保证所有指令同时成功或同时失败,只有决定是否开始执行全部指令的能力,没有执行到一半进行回滚的能力
4排它性Redis会保证一个事务内的命令依次执行,而不会被其它命令插入。

(三)、实操

1、正常执行

使用MULTI开启事务,EXEC执行事务。开启事务之后的所有操作,都只是加入到操作队列中,并没有实际执行。


2、放弃事务

使用MULTI开启事务,DISCARD放弃事务。


3、全部失败


4、冤头债主

与传统事务数据库区别,不一定要一起成功一起失败,redis可以部分成功部分失败。

INCRINCRBY命令操作只能是整数,所以这两条命令失败了,其他都成功了。


5、watch监控

乐观锁(Optimistic Lock),顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据。乐观锁策略是提交版本必须 大于记录当前版本才能执行更新。

悲观锁(Pessimistic Lock),顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。

watch命令是一种乐观锁的实现,Redis在修改的时候会检测数据是否被更改,如果更改了,则执行失败。

5.1、正常情况


5.2、加塞情况

就是开启对这个key监控后,另外一个redis也在操作这个key,那么这边事务就会执行失败。


5.3、watch小总结

在 Redis 事务中,WATCH命令用于监控一个或多个键,一旦被监控的键在事务执行之前被其他客户端修改,那么当前事务将被取消,不会执行。

不过需要注意的是,一旦执行了EXEC命令,那么之前加的所有监控锁都将取消,这意味着事务执行完成后,不再对监控的键进行监控。此外,退出Redis或者Redis宕机也会导致监控锁取消,所以在实际应用中,需要合理把握监控锁的生命周期,结合业务场景来确保数据操作的准确性和一致性。


(四)、事务小总结

redis的事务分为三步:

  1. 开启:以MULTI开启事务。
  2. 入队:将多个命令入队到事务中,接到这些命令并不会立即执行,而是放到等待执行的事务队列里面。
  3. 执行:由EXEC命令触发事务。

二、Redis管道

(一)、问题由来

Redis是一种基于客户端-服务端模型以及请求/响应协议的TCP服务。一个请求会遵循以下步骤:

  1. 客户端向服务端发送命令分四步(发送命令→命令排队→命令执行→返回结果),并监听Socker返回,通常以阻塞模式等待服务端响应。
  2. 服务端处理命令,并将结果返回给客户端。

如果同时需要执行大量的命令,那么就要等待上一条命令应答后再执行,这中间不仅仅多了RTT(Round Time Trip,简称RTT,数据包往返于两端的时间),而且还频繁调用系统IO,发送网络请求,同时需要redis调用多次read()和write()系统方法,系统方法会将数据从用户态转移到内核态,这样就会对进程上下文有比较大的影响了,性能不太好。

Q&A 如何优化频繁命令往返造成的性能瓶颈?

答:使用管道


(二)、定义

管道(pipeline)可以一次性发送多条命令给服务端,服务端依次处理完完毕后,通过一条响应一次性将结果返回通过减少客户端与redis的通信次数来实现降低往返延时时间。pipeline实现的原理是队列,先进先出特性就保证数据的顺序性。

总结一句话:管道是批处理命令变种优化措施,类似Redis的原生批命令(mget和mset)。


(三)、实操


(四)、管道功能小总结

1、pipeline与原生批命令对比

  • 原生批量命令是原子性(例如:mset, mget),pipeline是非原子性
  • 原生批量命令一次只能执行一种命令,pipeline支持批量执行不同命令
  • 原生批命令是服务端实现,而pipeline需要服务端与客户端共同完成。

2、pipeline与事务对比

  • 事务具有原子性,管道不具有原子性
  • 管道一次性将多条命令发送到服务器,事务是一条一条的发,事务只有在接收到exec命令后才会执行,管道不会。
  • 执行事务时会阻塞其他命令的执行,而执行管道中的命令时不会阻塞其他命令

3、pipeline注意事项

  • pipeline缓冲的指令只是会依次执行,不保证原子性,如果执行中指令发生异常,将会继续执行后续的指令。
  • 使用pipeline组装的命令个数不能太多,不然数据量过大客户端阻塞的时间可能过久,同时服务端此时也被迫回复一个队列答复,占用很多内存。

三、Redis发布订阅(了解即可

(一)、定义

Redis发布订阅是一种消息通信模式。客户端可以订阅一个或多个频道,当有其他客户端向这些频道发布消息时,订阅者会收到相应的消息。这是一种基于事件驱动的通信方式,适用于实时消息推送、实时通知等场景。


(二)、实操

开启三个客户端,A、B订阅C,C发布消息,A、B能及时获取消息。


(三)、发布订阅功能小总结

Redis可以实现消息中间件MQ的功能,通过发布订阅实现消息的引导和分流。但不推荐使用该功能,专业的事情交给专业的中间件处理,redis就做好分布式缓存功能。

Pub/Sub的缺点:

  • 发布的消息在Redis系统中不能持久化,因此,必须先执行订阅,再等待消息发布。如果先发布了消息,那么该消息由于没有订阅者,消息将被直接丢弃。
  • 消息只管发送对于发布者而言消息是即发即失的,不管接收,也没有ACK机制,无法保证消息的消费成功。
  • 以上的缺点导致Redis的Pub/Sub模式就像个小玩具,在生产环境中几乎无用武之地,为此Redis5.0版本新增了Stream数据结构,不但支持多播,还支持数据持久化,相比Pub/Sub更加的强大。但是仍然不推荐使用Stream来做MQ的功能,还是那句话,专业的事情交给专业的中间件处理。

四、总结

Redis 的事务、管道以及发布订阅功能,赋予了开发者强大的数据处理与通信能力。事务机制保证了数据操作具备一致性和完整性,管道技术提升了客户端与服务器之间的通信效率,发布订阅机制则实现了实时消息推送功能。在实际项目开发过程中,可依据具体业务需求,灵活运用上述功能,充分发挥 Redis 的技术优势,从而有效提升系统性能与用户体验。


ps:努力到底,让持续学习成为贯穿一生的坚守。学习笔记持续更新中。。。。


http://www.kler.cn/a/552142.html

相关文章:

  • 深度学习06 寻找与保存最优模型
  • Flink SQL与Doris实时数仓Join实战教程(理论+实例保姆级教程)
  • WPS/WORD$OffterAI
  • Vue3项目,蛋糕商城系统
  • C++ Primer 访问控制与封装
  • Android Studio:如何使用 RxBus 类进行事件发布和订阅
  • Kafka分区管理大师指南:扩容、均衡、迁移与限流全解析
  • 算法12-贪心算法
  • 前端基础——axios、fetch和xhr来封装请求
  • 用LangGraph轻松打造测试用例生成AI Agent
  • 【保姆级教程】DeepSeek R1+RAG,基于开源三件套10分钟构建本地AI知识库
  • 青少年网络安全竞赛python 青少年网络安全大赛
  • 【故障处理】- 11g迁19C数据泵报错: ORA-39083 ORA-06598 导致数据库大量对象导入不进去
  • Linux环境Docker使用代理推拉镜像
  • Postgresql的三种备份方式_postgresql备份
  • ARM中断流程思考。
  • 百度搜索融合 DeepSeek 满血版,开启智能搜索新篇
  • 微信小程序---计划时钟设计与实现
  • 欢乐力扣:旋转图像
  • redis的应用,缓存,分布式锁