Redis(三) 事务与发布订阅

结合前两期 Redis(一) Redis简介(Redis(一) Redis简介-CSDN博客) Redis(二) 可编程性(Redis(二) 可编程性-CSDN博客)

目录

事务在 Redis 中的运作方式

用法 

事务中的错误

回滚

放弃命令队列

使用检查和设置的乐观锁定

WATCH解释 

使用 WATCH 实现 ZPOP

Redis 发布/订阅 

推送消息的格式

有线协议示例

模式匹配订阅

与模式和频道订阅匹配的消息 

模式匹配的订阅计数的含义

分片发布/订阅


事务在 Redis 中的运作方式

Redis 事务允许执行一组命令 在一个步骤中,它们以 MULTI、EXEC、DISCARD 和 WATCH 命令为中心。 Redis 事务提供两个重要保证:

  • 事务中的所有命令都经过序列化和执行 顺序。其他客户端发送的请求永远不会 在 Redis 事务执行过程中提供服务。 这保证了命令作为单个命令执行 隔离操作。

  • EXEC 命令 触发事务中所有命令的执行,因此 如果客户端在上下文中失去与服务器的连接 调用 EXEC 命令前的事务,无任何操作 ,相反,如果调用 EXEC 命令,则所有 执行操作。使用仅追加文件时,Redis 确保 使用单个 write(2) 系统调用将事务写入磁盘。 但是,如果 Redis 服务器崩溃或被系统管理员杀死 以某种困难的方式,可能只有部分操作 已注册。Redis 将在重新启动时检测到此情况,并退出并显示错误。 使用该工具可以修复 仅附加将删除部分事务的文件,以便 服务器可以重新启动。redis-check-aof   

从版本 2.2 开始,Redis 允许对 在两个以上,以一种非常类似于 检查和设置 (CAS) 操作。 

用法 

使用 MULTI 命令输入 Redis 事务。命令 总是回复 .此时,用户可以发出多个 命令。Redis 不会执行这些命令,而是会排队 他们。调用 EXEC 后,将执行所有命令。OK

改为调用 DISCARD 将刷新事务队列并退出 交易。

以下示例以原子方式递增键。foobar

> MULTI
OK
> INCR foo
QUEUED
> INCR bar
QUEUED
> EXEC
1) (integer) 1
2) (integer) 1

从上面的会话中可以清楚地看出,EXEC 返回一个 回复数组,其中每个元素都是单个命令的回复 在事务中,命令的发出顺序相同。

当 Redis 连接位于 MULTI 请求的上下文中时, 所有命令都将回复字符串(作为状态回复发送 从Redis协议的角度来看)。排队的命令是 只需在调用 EXEC 时安排执行。QUEUED

事务中的错误

在事务过程中,可能会遇到两种命令错误:

  • 命令可能无法排队,因此在调用 EXEC 之前可能会出现错误。 例如,命令可能在语法上是错误的(参数数量错误, 错误的命令名称,...),或者可能存在一些关键情况,例如 内存条件(如果使用指令将服务器配置为具有内存限制)。maxmemory
  • 调用 EXEC 后,命令可能会失败,例如,由于我们执行了 对具有错误值的键的操作(例如针对字符串值调用列表操作)。

从 Redis 2.6.5 开始,服务器会在命令累积过程中检测到错误。 然后,它将拒绝执行事务,并在 EXEC 期间返回错误,从而丢弃事务。

在 Redis 2.6.5 之前,客户端需要通过检查来检测 EXEC 之前发生的错误 queued 命令的返回值:如果命令回复 QUEUED,则为 正确排队,否则 Redis 返回错误。 如果在对命令进行排队时出现错误,则大多数客户端 将中止并放弃事务。否则,如果客户选择继续交易 EXEC 命令将执行所有成功排队的命令,而不考虑以前的错误。

EXEC 之后发生的错误不会以特殊方式处理: 即使某些命令在事务期间失败,也会执行所有其他命令。

这在协议级别上更为明确。在以下示例中,一个 即使语法正确,命令在执行时也会失败:

Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
MULTI
+OK
SET a abc
+QUEUED
LPOP a
+QUEUED
EXEC
*2
+OK
-WRONGTYPE Operation against a key holding the wrong kind of value

EXEC 返回了两个元素的批量字符串回复,其中一个是代码和 另一个是错误回复。由客户端库来查找 向用户提供错误的明智方式。OK

需要注意的是,即使命令失败,队列中的所有其他命令也会被处理——Redis 不会停止 命令的处理。

另一个示例,再次使用 wire 协议和 ,显示了如何 语法错误会尽快报告:telnet

MULTI
+OK
INCR a b c
-ERR wrong number of arguments for 'incr' command

这一次,由于语法错误,错误的 INCR 命令未排队 完全。

回滚

Redis 不支持事务回滚,因为支持回滚 将对 Redis 的简单性和性能产生重大影响。

放弃命令队列

DISCARD 可用于中止事务。在这种情况下,不可以 执行命令并将连接状态恢复到 正常。

> SET foo 1
OK
> MULTI
OK
> INCR foo
QUEUED
> DISCARD
OK
> GET foo
"1"

使用检查和设置的乐观锁定

WATCH 用于向 Redis 提供检查和设置 (CAS) 行为 交易。

监视 WATCHed 密钥,以检测针对它们的更改。如果 在 EXEC 命令之前,至少修改了一个监视密钥, 整个事务中止,EXEC 返回 Null 回复以通知 事务失败。

例如,假设我们需要以原子方式递增值 键的 1(假设 Redis 没有 INCR)。

第一次尝试可能如下:

val = GET mykey
val = val + 1
SET mykey $val

只有当我们有一个客户端执行 在给定时间内操作。如果多个客户端尝试递增密钥 大约在同一时间,将有一个竞争条件。例如 客户端 A 和 B 将读取旧值,例如 10。该值将 由两个客户端递增到 11,最后 SET 作为值 的键。因此,最终值将是 11 而不是 12。

多亏了 WATCH,我们才能很好地对问题进行建模:

WATCH mykey
val = GET mykey
val = val + 1
MULTI
SET mykey $val
EXEC

 使用上面的代码,如果存在竞争条件和另一个客户端 修改 in 我们调用 WATCH 和 我们对 EXEC 的调用,事务将失败。val

我们只需要重复操作,希望这次我们不会得到 新种族。这种锁定形式称为乐观锁定。 在许多用例中,多个客户端将访问不同的密钥, 因此,不太可能发生碰撞 - 通常无需重复操作。

WATCH解释 

那么WATCH到底是什么呢?这是一个命令,将 使 EXEC 有条件:我们要求 Redis 执行 仅当 WATCHed 密钥均未修改时,才进行交易。这包括 客户端所做的修改,如写入命令,以及 Redis 本身, 比如过期或驱逐。如果在监视和接收 EXEC 之间修改了密钥,则整个事务将被中止 相反。

注意:

  • 在 6.0.9 之前的 Redis 版本中,过期的密钥不会导致事务 要中止。
  • 事务中的命令不会触发 WATCH 条件,因为它们 仅在发送 EXEC 之前排队。

WATCH可以多次调用。简单地说,所有的 WATCH 调用都会 从通话开始,可以监视变化的效果,直到 调用 EXEC 的那一刻。您还可以将任意数量的密钥发送到 单次观看通话。

调用 EXEC 时,无论是否 事务是否中止。此外,当客户端连接是 关闭,一切都变得 UNWATCHed。

也可以使用 UNWATCH 命令(不带参数) 为了刷新所有监视的键。有时这很有用,因为我们 乐观地锁定几个键,因为可能需要执行 事务来更改这些键,但在读取当前内容后 我们不想继续的键。发生这种情况时,我们只需调用 UNWATCH,以便该连接已经可以自由地用于新的 交易。

使用 WATCH 实现 ZPOP

一个很好的例子来说明如何使用 WATCH 来创建新的 否则 Redis 不支持的原子操作是实现 ZPOP (仅添加了 ZPOPMIN、ZPOPMAX 及其阻塞变体 在 5.0 版中),这是一个弹出元素的命令,具有较低的 以原子方式从排序集得分。这是最简单的 实现:

WATCH zset
element = ZRANGE zset 0 0
MULTI
ZREM zset element
EXEC

如果 EXEC 失败(即返回 Null 回复),我们只需重复该操作。 

Redis 发布/订阅 

SUBSCRIBE、UNSUBSCRIBE 和 PUBLISH 实现了发布/订阅消息传递范式,其中(引用维基百科)发送者(发布者)没有被编程为将其消息发送给特定的接收者(订阅者)。 相反,已发布的消息被定性为频道,而不知道可能有哪些(如果有的话)订阅者。 订阅者对一个或多个频道表示兴趣,并且只收到感兴趣的消息,而不知道有哪些(如果有)发布者。 发布者和订阅者的这种解耦允许更大的可伸缩性和更动态的网络拓扑。

例如,要订阅频道“channel11”和“ch:00”,客户端会发出 SUBSCRIBE,提供频道名称:

SUBSCRIBE channel11 ch:00

其他客户端发送到这些通道的消息将由 Redis 推送到所有订阅的客户端。 订阅者按照消息的发布顺序接收消息。

订阅一个或多个频道的客户端不应发出命令,尽管它可以对其他频道进行 SUBSCRIBE 和取消订阅。 对订阅和取消订阅操作的回复以消息的形式发送,以便客户端可以只读取连贯的消息流,其中第一个元素指示消息类型。 在订阅的 RESP2 客户端的上下文中允许的命令包括:

  • PING
  • PSUBSCRIBE
  • PUNSUBSCRIBE
  • QUIT
  • RESET
  • SSUBSCRIBE
  • SUBSCRIBE
  • SUNSUBSCRIBE
  • UNSUBSCRIBE

但是,如果使用 RESP3(请参阅 HELLO),则客户端可以在订阅状态下发出任何命令。

请注意,在订阅模式下使用 时,不能使用 UNSUBSCRIBE 和 PUNSUBSCRIBE 等命令,因为不接受任何命令,只能退出 WITH 模式。redis-cliredis-cliCtrl-C

推送消息的格式

消息是具有三个元素的数组回复。

第一个元素是消息的类型:

subscribe:表示我们成功订阅了回复中作为第二个元素给出的频道。 第三个参数表示我们当前订阅的频道数量。

unsubscribe:表示我们已成功取消订阅回复中作为第二个元素给出的频道。 第三个参数表示我们当前订阅的频道数量。 当最后一个参数为零时,我们不再订阅任何通道,客户端可以发出任何类型的 Redis 命令,因为我们处于 Pub/Sub 状态之外。

message:它是由于另一个客户端发出的 PUBLISH 命令而接收的消息。 第二个元素是原始通道的名称,第三个参数是实际的消息负载。

有线协议示例

SUBSCRIBE first second
*3
$9
subscribe
$5
first
:1
*3
$9
subscribe
$6
second
:2

此时,我们从另一个客户端对名为 :second 

> PUBLISH second Hello

这是第一个客户端收到的内容:

*3
$7
message
$6
second
$5
Hello

现在,客户端使用 UNSUBSCRIBE 命令从所有通道中取消订阅,而无需其他参数:

UNSUBSCRIBE
*3
$11
unsubscribe
$6
second
:1
*3
$11
unsubscribe
$5
first
:0

模式匹配订阅

Redis Pub/Sub 实现支持模式匹配。 客户端可以订阅 glob 样式模式,以接收发送到与给定模式匹配的通道名称的所有消息。

例如:

PSUBSCRIBE news.*

将接收发送到频道的所有消息,等等。 所有 glob 样式模式都有效,因此支持多个通配符。news.art.figurativenews.music.jazz

PUNSUBSCRIBE news.*

然后,将取消订阅该模式的客户端。 此调用不会影响其他订阅。

由于模式匹配而收到的消息以不同的格式发送:

  • 消息的类型是:它是从另一个客户端发出的 PUBLISH 命令接收的消息,与模式匹配订阅匹配。 第二个元素是匹配的原始模式,第三个元素是原始通道的名称,最后一个元素是实际的消息负载。pmessage

与 SUBSCRIBE 和 UNSUBSUBSCRIBE 类似, 和 PUNSUBSCRIBE 命令由发送类型为消息的系统确认,并使用与 and 消息格式相同的格式。psubscribepunsubscribesubscribeunsubscribe

与模式和频道订阅匹配的消息 

如果客户端订阅了与已发布消息匹配的多个模式,或者订阅了与该消息匹配的模式和通道,则客户端可能会多次收到一条消息。 以下示例显示了这一点:

SUBSCRIBE foo
PSUBSCRIBE f*

在上面的示例中,如果将消息发送到 通道,客户端将收到两条消息:一条是 type 的消息,另一条是 type 的消息。foomessagepmessage 

模式匹配的订阅计数的含义

在 、 和 消息类型中,最后一个参数是仍处于活动状态的订阅计数。 此数字是客户端仍订阅的通道和模式的总数。 因此,只有当此计数因取消订阅所有通道和模式而降至零时,客户端才会退出 Pub/Sub 状态。subscribeunsubscribepsubscribepunsubscribe

分片发布/订阅

从 Redis 7.0 开始,引入了分片 Pub/Sub,其中分片通道通过用于为插槽分配密钥的相同算法分配给插槽。 必须将分片消息发送到拥有分片通道散列到的插槽的节点。 群集确保将发布的分片消息转发到分片中的所有节点,以便客户端可以通过连接到负责槽位的主节点或其任何副本来订阅分片通道。SSUBSCRIBE、SUNSUBSCRIBE 和 SPUBLISH 用于实现分片的 Pub/Sub。

分片发布/订阅有助于在集群模式下扩展发布/订阅的使用。 它将消息的传播限制在集群的分片内。 因此,与全局发布/订阅相比,通过集群总线的数据量是有限的,在全局发布/订阅中,每条消息都传播到集群中的每个节点。 这允许用户通过添加更多分片来横向扩展 Pub/Sub 使用量。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/559888.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JUC(java.util.concurrent) 的常见类

Callable 接口 Callable 的用法 Callable 是一个 interface(类似之前的 Runnable,用来描述一个任务,但是没有返回值)也是描述一个任务的,有返回值。方便程序猿借助多线程的方式计算结果. 例如:创建线程…

CZT Blusetein‘s FFT

参考文献: [Sto66] Stockham Jr T G. High-speed convolution and correlation[C]//Proceedings of the April 26-28, 1966, Spring joint computer conference. 1966: 229-233.[Blu68] Bluestein L. A linear filtering approach to the computation of discrete …

代码优化实践之税率计算问题

开篇 今天的问题来自于《编程珠玑》第三章【数据决定程序结构】,这里提出了几条代码优化相关的原则,受益不浅。下面是提到的几条原则: 使用数组重新编写重复代码。冗长的相似代码往往可以使用最简单的数据结构——数组来更好的表述&#xff1…

Vue3: toRefs与toRef的基本使用

一、前言 本文主要介绍toRefs与toRef的基本使用。 二、内容 1、基本概念 作用: toRefs与toRef可以将一个响应式对象中的每一 个属性,转换为ref对象;不同 toRefs与toRef功能一致,但toRefs可以批量转换。 2、toRefs 如果把reactive定义的…

ROS仿真小车(四)—— URDF与Gazebo集成

文章目录 前言一、ubuntu20.04中下载gazebo_models二、在gazebo中显示简单模型1 创建功能包,导入依赖2 编写URDF文件3 编写launch文件4 在gazebo中显示机器人模型 三、URDF集成Gazebo相关设置四、在gazebo中导入小车模型1 编写xacro文件2 编写launch文件3 运行结果 …

Stable Diffusion 模型分享:MeinaMix(动漫)meinamix_meinaV11

本文收录于《AI绘画从入门到精通》专栏,专栏总目录:点这里,订阅后可阅读专栏内所有文章。 文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八 下载地址 模型介绍 MeinaMix 的目标是:能够在很少的提示下…

SpectralMamba:用于高光谱图像分类的高效 Mamba

SpectralMamba:用于高光谱图像分类的高效 Mamba 摘要IntroductionMethodologyPreliminariesSpectralMamba: OverviewSpectralMamba: Key ComponentsB1 Piece-wise Sequential ScanningIii-B2 Gated Spatial-Spectral Merging SpectralMamba: Efficient Mamba for Hy…

【InternLM 实战营第二期作业06】Lagent AgentLego 智能体应用搭建

基础作业 1.完成 Lagent Web Demo 使用 使用 LMDeploy 部署 conda activate agent lmdeploy serve api_server /root/share/new_models/Shanghai_AI_Laboratory/internlm2-chat-7b \--server-name 127.0.0.1 \--model-name internlm2-chat-7b \--cache-max-entry-count 0.1 …

Linux文件的特殊权限(SUID|SGID|SBIT)

一、SUID 介绍:SUID是一种对二进制程序进行设置的特殊权限,能够让二进制程序的执行者临时拥有所有者的权限(仅对拥有执行权限的二进制程序有效)。 (一)语法格式 chmod us 文件名(设置SUID权限…

SOLIDWORKS批量改名工具个人版 慧德敏学

每个文件都会有自己的名字,SOLIDWOKRKS模型也不例外。但是如果从资源管理器直接修改模型的文件名,就会导致模型关联的丢失,导致装配体打开之后找不到模型,因此就需要使用SOLIDWORKS的重命名功能。 SOLIDWORKS批量改名插件- Solid…

智能电网线路阻抗模拟器基础认识

智能电网线路阻抗模拟器是专门用于模拟电力系统输电线路阻抗特性的装置,它能够根据设定的参数,精确地模拟出各种不同类型、不同长度和不同截面积的输电线路在正常运行或故障状态下的阻抗特性。这种模拟器在电力系统的规划、设计、运行和维护中起着重要的…

交换机的种类有哪些?主要都具有哪些作用?

在当今数字化时代,网络已经成为我们生活和工作中不可或缺的一部分。无论是家庭网络还是企业网络,都需要有效的网络设备来实现数据通信和资源共享。而网络交换机作为一种重要的网络设备,扮演着连接和管理网络设备的关键角色。本文将探讨交换机…

TXT文本编辑器,高效将文本里特定符号前的内容作为关键词一键复制或移动文件,效管理文件内容

在日常工作和生活中,我们经常需要处理大量的文件,而文件的管理和整理则成为了一个重要的问题。传统的文件管理方式不仅效率低下,而且容易出错。为了解决这一难题,我们推出了一款强大的TXT文本编辑器,它能够帮助你以文件…

岩石变角剪切试验夹具 技术参数

岩石变角试验夹具是根据TB10115-2014铁路工程岩石试验规程等标准利用压力机施加垂直荷载,通过一套特制的夹具使试件沿某一剪切面产生剪切破坏,然后通过静力平衡条件解析剪切面上的法向压应力和剪应力,从而绘制法向压应力(σ)与剪应力(τ&…

flutter release 报错 Error: SocketException: Failed host lookup:

flutter 的 debug 模式没有任何问题 ,打了release 包后一直报下面的错,查了一下是 因为没有网络权限 Error: SocketException: Failed host lookup: yomi-test-aws-sg.yomigame.games (OS Error: No address associated with hostname, errno 7) 按照下…

YOLOv5 / YOLOv7 / YOLOv8 / YOLOv9 / RTDETR -gui界面-交互式图形化界面

往期热门博客项目回顾:点击前往 计算机视觉项目大集合 改进的yolo目标检测-测距测速 路径规划算法 图像去雨去雾目标检测测距项目 交通标志识别项目 yolo系列-重磅yolov9界面-最新的yolo 姿态识别-3d姿态识别 深度学习小白学习路线 AI健身教练-引体向上…

使用 大模型快速生成-jsToJava 的正则表达式离线版本的简单html页面

注意&#xff1a;需求要描述清楚-提高程序员的工作效率 代码 <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0&quo…

C++相关概念和易错语法(6)(运算符重载)

1.运算符重载注意事项&#xff1a; &#xff08;1&#xff09;多个同一运算符重载可构成函数重载 &#xff08;2&#xff09;在成员函数中由于隐含了this指针&#xff0c;外部调用看上去前置和后置不会有任何区别&#xff0c;所以为了区分这个在后置时强制引入参数int&#x…

医药行业如何巧用AI智能客服机器人?看完你就会了

我们都知道&#xff0c;医药行业信息量庞大&#xff0c;行业规范严格&#xff0c;客户查询和服务需求复杂多变。那么&#xff0c;医药企业该如何高效响应客户&#xff0c;同时保持服务质量并降低成本呢&#xff1f;答案很可能就在AI智能客服机器人。 AI智能客服机器人利用人工智…

【鸿蒙NEXT】web组件debug模式

官方文档 使用Devtools工具调试前端页面 打开web debug模式 webview.WebviewController.setWebDebuggingAccess(true)chrome 访问 chrome://inspect/#devices Discover network targets 中添加 localhost:9222 创建cat.sh name$(hdc shell ps -ef | grep com.cib.qdzg | …
最新文章