Redis事务、管道、发布订阅

Redis提供事务(MULTI/EXEC/DISCARD/WATCH)和管道(Pipeline)机制来优化命令执行。事务保证命令的串行执行,但不保证原子性;管道通过减少RTT提高批量命令效率。此外,发布订阅功能允许发送者向订阅者广播消息,适合实时性高的异步通信,但无持久化和消息确认机制。
摘要由CSDN通过智能技术生成

Redis事务

事务: 在和数据库的交互中,其中包含多条语句,需要全部成功或者失败,不能部分成功;即一组命令的集合,所有命令必须串行执行,而且执行过程中不允许其他相关命令打断和插入

Redis中也提供了一些方法来管理事务

  • Redis的命令执行是单线程架构,在执行完事务的所有指令前不执行其他任何客户端请求
  • 不存在隔离级别,因为根本不需要加锁,不存在事务内外的区分
  • 不保证原子性,不能保证所有指令同时成功和失败,只能保证开始执行全部指令,没有进行一半后回滚的能力
  • 排他,Redis的事务中的命令是绝对连续执行的,不会被加塞
Redis事务命令
  • DISCARD 取消事务
  • EXEC 执行事务块的命令
  • MULTI 标记事务块的开始
  • UNWATCH 取消WATCH命令对所有key的监视
  • WATCH key [key …] 监视一些key,如果事务执行前这些key被其他命令改动,那么事务的执行被打断
Redis命令执行场景
  • 正常执行

    • 首先执行MULTI
    • 写自己的多条语句,每次的语句会返回QUEUED,即存入队列中
    • 使用EXEC,所有语句开始顺序执行
  • 放弃执行

    • 首先写MULTI
    • 写多条语句
    • 使用DISCARD,放弃队列中全部语句,不再执行
  • 全部成功

    • MULTI
    • 写多条语句,但有一条语句错误,则该语句在入队时报错
    • 使用EXEC时,整个事务都不会执行
  • 部分成功

    • MULTI
    • 写多条语句,有些语句错误但无法在运行前检查出来,则无法支持回滚
    • 此时使用EXEC,可能导致某条语句错误,但不影响其他语句执行
  • watch监控

    Redis使用Watch来提供乐观锁,类似于CAS(check and set)

    悲观锁是指每次访问数据都认为这个数据可能被修改,所以每次访问都加锁

    **乐观锁 **每次访问数据都认为这个数据不会被修改,所以不会上锁,但是更新的时候可以判断一下这个数据是否被修改

    乐观锁的提交策略是,提交版本必须大于当前记录的版本才能更新

    Watch可以用来监控一个key,如果这个key没有在事务修改它之前被修改,那么就可以执行事务内的修改操作

    • 首先使用Watch key监控数据
    • 使用MULTI和多个语句
    • 使用EXEC,如果此时key没被修改则事务成功 执行,如果key修改了,则导致事务中语句全部不执行
    • 如果执行了EXEC,则所以的WATCH都会被取消监控,也可以手动使用UNWATCH解除监控

Redis管道

Redis是一种客户端到服务端的模型,等到Socket监听到命令,通常情况下是阻塞等待的,每条命令消耗一个RTT(Round Trip Time)往返时间。

如果执行多条命令时,都需要等待上条命令响应,那么就多了很多的RTT;

Pipeline可以一次发送多条命令到服务端,服务端依次处理后,只通过一条响应携带多个结果返回即可,这样可以减少客户端和Redis的通信次数。而管道的原理就是队列,保证先进先出。

原生的多条处理命令入mset不能支持多类型数据操作,所以管道是一种优化的批处理方法。

我们可以在一个文本文件中依次写入语句,并且使用命令交给Redis客户端即可依次执行其中的语句

cat commands.txt | redis-cli -a password --pipe
  • 和原生批处理的对比

    • 管道的执行方式是在终端执行的,不具备原子性,而原生批处理是原子操作

    • 原生命令只能执行一种操作,而管道可以执行多种操作

    • 原生的批处理命令是服务端的,而管道是需要服务端和客户端共同完成的

  • 和事务的对比

    • 管道是一次性将所有命令发送到服务器,而事务中的命令只有在EXEC后才执行
    • 事务有原子性,管道没有
    • 事务执行时阻塞其他命令执行,管道不会
  • 注意事项

    • 管道的指令只会顺序执行,不存在原子性
    • 管道在的命令不要太多,不然可能导致客户端发生一定的阻塞等待,同时服务端也被迫恢复一个队列答复,占用内存较多

Redis发布订阅

这是一种消息通信模式,发送者(PUBLISH)发送消息,订阅者(SUBSCRIBE)接收消息,可以实现进程间通信;可以实现一些消息中间件的功能。

Redis客户端可以订阅任意数量的频道,当有新的消息发布时,所有订阅了频道的客户端都会接收到这个消息;

这是一个轻量级队列,数据不会被持久化,一般用来处理实时性较高的异步消息。

相关命令

  • PSUBSCRIBE pattern [pattern …] 支持订阅一个或多个频道
    • 批量订阅,支持模式串组合
  • PUBSUB subcommand[argument[argument …]] 查看订阅和发布系统状态
    • PUBSUB CHANNELS 查看活跃频道组成的列表
    • PUBSUB NUMSUB 查看某个频道的订阅者数量,不包含模式订阅的
    • PUBSUB NUMPAT 只统计使用PSUBSRIBE(模式订阅)命令执行的、返回给客户端订阅的唯一模式的数量
  • PUBLISH channel message 将信息发送到指定的频道
  • PUNSUBSCRIBE [pattern[pattern …]] 推定全部给定模式的频道
  • SUBSCRIBE channel[channel …] 订阅给定的一个或多个频道的信息
    • 推荐先进行订阅,再进行发布,否则收不到消息
    • 订阅的客户端每次可以收到一个3个参数的消息,包括消息的种类、始发频道的名称、实际的消息内容
  • UNSUBSCRIBE channel [channel…] 推定给定的一些频道

特点

  • 没有持久化,所以必须先订阅,否则就会丢失消息
  • 消息只管发送,没有ACK机制,无法保证消费成功
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值