Redis中的订阅发布和事务(一)

news2024/11/26 20:28:53

订阅发布

PUBSUB NUMSUB

PUBSUB NUMSUB [channel-1 channel-2… channel-n]子命令接受任意多个频道作为输入参数,并返回这些频道的订阅者数量。
这个子命令是通过pubsub_channels字典中找到频道对应的订阅者链表,然后返回订阅者链表的长度来实现的(订阅者链表的长度
就是频道订阅者的数量),这个过程可以用以下伪代码来描述:

def pubsub_numsub(*all_input_channels):
# 遍历输入的所有频道
for channel in all_input_channels:
# 如果pubsub_channels字典中没有channel这个键
# 那么说明channel频道没有任何订阅者
if channel not in server.pubsub_channels:
# 返回频道名
reply_channel_name(channel)
# 订阅者数量为0
reply_subscribe_count(0)

# 如果pubsub_channels字典中存在channel键
# 那么说明channel频道至少有一个订阅者
else:
# 返回频道名
reply_channel_name(channel)
# 订阅者链表的长度就是订阅者数量
reply_subscribe_count(len(server.pubsub_channels(channel)))

例子

在这里插入图片描述

  • 举个例子。对于图中所示的pubsub_channels字典来说,对字典中的四个频道执行PUBSUB NUMSUB命令将获得以下回复
redis>PUBSUB NUMSUB news.it news.sport news.business news.movie
1)."news.it"
2)."3"
3)."news.sport"
4)."2"
5)."news.business"
6)."2"
7)."news.movie"
8)."1"

PUBSUB NUMPAT

PUBSUB NUMPAT子命令用于返回服务器当前被订阅模式的数量。这个子命令是通过返回pubsub_patterns链表的长度来实现的,因为这个链表的长度就是服务器被订阅模式的数量,这个过程可以用以下伪代码来描述:

def pubsub_numpat():
# pubsub_patterns链表的长度即是被订阅模式的数量
reply_pattern_count(len(server.pubsub_patterns))

例子

  • 举个例子。对于图中所示的pubsub_patterns链表来说,执行PUBSUB NUMPAT命令将返回3:
redis>PUBSUB NUMPAT
(integer) 3

在这里插入图片描述

事务

概述

Redis通过MULTI、EXEC、WATCH等命令来实现事务(transaction)功能。事务提供了一种将多个命令请求打包,然后一次性、按顺序地执行多个命令的机制,并且在事务执行期间,服务器不会中断事务而改去执行其他客户端的命令请求,它会将事务中的所有命令都执行完毕,然后采取执行其他客户端的命令请求。

例子
  • 举个例子。事务首先以一个MULTI命令为开始,接着将多个命令放入事务当中,最后由EXEC命令将这个事务提交(commit)给服务器执行:
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> SET "name" "Practical Common Lisp"
QUEUED
127.0.0.1:6379> GET "name"
QUEUED
127.0.0.1:6379> SET "author" "Peter Seibel"
QUEUED
127.0.0.1:6379> GET "author"
QUEUED
127.0.0.1:6379> EXEC
1) OK
2) "Practical Common Lisp"
3) OK
4) "Peter Seibel"

事务的实现

一个事务从开始到结束通常会经历以下三个阶段:

  • 1.事务开始
  • 2.命令入队
  • 3.事务执行

事务开始

MULTI命令的执行标志着事务的开始:

redis> MULTI
OK

MULTI命令可以将执行该命令的客户端从非事务状态切换至事务状态,这一切换是通过在客户端状态的flags属性中打开REDIS_MULTI标识来完成的,MULTI命令的实现可以用以下伪代码来表示:

def MULTI():
# 打开事务表示
client.flags |= REDIS_MULTI

# 返回OK回复
replyOK()

命令入队

当一个客户端处于非事务状态时,这个客户端发送的命令会立即被服务器执行:

127.0.0.1:6379> SET "name" "Practical Common Lisp"
OK
127.0.0.1:6379> GET "name"
"Practical Common Lisp"
127.0.0.1:6379> SET "author" "Peter Seibel"
OK
127.0.0.1:6379> GET "author"
"Peter Seibel

与此不同的是,当一个客户端切换到事务状态之后,服务器会根据这个客户端法拉的不同命令执行不同的操作:

  • 1.如果客户端发送的命令为EXEC、DISCARD、WATCH、MULTI四个命令的其中一个,那么服务器立即执行这个命令
  • 2.与此相反,如果客户端发送的命令是EXEC、DISCARD、WATCH、MULTI四个命令以外的其他命令,那么服务器并不立即执行这个命令,而是将这个命令放入一个事务队列里面,然后向客户端返回QUEUED回复。

服务器判断命令是该入队还是该立即执行的过程可以用流程图来描述
在这里插入图片描述

事务队列

每个Redis客户端都由自己的事务状态,这个事务状态保存在客户端状态的mstate属性里面:

typedef struct redisClient {
// ...

// 事务状态
multiState mstate; // MULTI/EXEC state

// ...
}redisClient;

事务状态包含一个事务队列,以及一个已入队命令的计数器(也可以说是事务队列的长度):

typedef struct multiState {
// 事务队列, FIFO顺序
multiCmd *commands;

// 已入队命令计数
int count;
} multiState;

事务队列是一个multiCmd类型的数组,数组中的每个multiCmd结构都保存了一个已入队命令的相关信息,包括指向命令实现函数的指针、命令的参数,以及参数的数量:

typedef struct multiCmd {
// 参数
robj **argv;

// 参数数量
int argc;

// 命令指针
struct redisCommand *cmd;
}multiCmd;

事务队列以先进先出(FIFO)的方式保存入队的命令,较先入队的命令会被放到数组的前面,而较后入队的命令则会被放到数组的后面

例子
  • 举个例子。如果客户端执行以下命令:
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> SET "name" "Practical Common Lisp"
QUEUED
127.0.0.1:6379> GET "name"
QUEUED
127.0.0.1:6379> SET "author" "Peter Seibel"
QUEUED
127.0.0.1:6379> GET "author"
QUEUED

那么服务器将为客户端创建如图所示的事务状态:
1.最先入队的SET命令被放在了事务队列的索引0位置上
2.第二入队的GET命令被放在了事务队列的索引1位置上
3.第三入队的另一个SET命令被放在了事务队列的索引2位置上
4.最后入队的另一个GET命令被放在了事务队列的索引3位置上
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

bdf文件导入事件错误情况

先打开脑电再导入事件 数据情况

500元左右的运动耳机怎么选?五大质量超群品牌分享

在运动中,一款合适的耳机不仅可以提升运动的乐趣,更能激励我们坚持锻炼,在市场上的运动耳机种类繁多,价格不一,如何选择一款既适合自己又物有所值的运动耳机呢?特别是在500元左右的预算范围内,我…

PostgreSQL入门到实战-第二十七弹

PostgreSQL入门到实战 PostgreSQL中数据分组操作(二)官网地址PostgreSQL概述PostgreSQL中HAVING命令理论PostgreSQL中HAVING命令实战更新计划 PostgreSQL中数据分组操作(二) 使用PostgreSQL HAVING子句来指定组或聚合的搜索条件 官网地址 声明: 由于操作系统, 版本更新等原因…

卷积神经网络的结构组成与解释(详细介绍)

文章目录 前言 1、卷积层 2、激活层 3、BN层 4、池化层 5、FC层(全连接层) 6、损失层 7、Dropout层 8、优化器 9、学习率 10、卷积神经网络的常见结构 前言 卷积神经网络是以卷积层为主的深层网络结构,网络结构包括有卷积层、激活层、BN层、…

Visual Studio 2019 社区版下载

一、网址 https://learn.microsoft.com/zh-cn/visualstudio/releases/2019/release-notes#start-window 二、选择这个即可

【每日刷题】Day16

【每日刷题】Day16 🥕个人主页:开敲🍉 🔥所属专栏:每日刷题🍍 🌼文章目录🌼 1. 24. 两两交换链表中的节点 - 力扣(LeetCode) 2. 160. 相交链表 - 力扣&…

【编程Tool】DevC++的安装配置及使用保姆级教程

目录 前言:软件介绍 1.软件下载及安装 1.1. 双击可执行文件进行安装 2.软件配置 2.1.选择语言 2.2 同意相关协议 2.3.组件保持默认并点击Next 2.4. 修改安装路径 2.5. 等待安装 2.6. 点击Finish,完成安装 2.7 选择语言 2.8.个性化设置 2.9. 点击OK&…

MySQL——创建和插入

一、插入数据 INSERT 使用建议; 在任何情况下建议列出列名,在 VALUES 中插入值时,注意值和列的意义对应关系 values 指定的值顺序非常重要,决定了值是否被保存到正确的列中 在指定了列名的情况下,你可以仅对需要插入的列给到…

MongoDB的go SDK使用集锦

在上一章解读MongoDB官方文档获取mongo7.0版本的安装步骤与基本使用介绍了如何使用mongo shell操作mongo数据库,接下来介绍如何使用sdk来操作数据库,这里以go语言为例,其他语言请查看源文档mongo docs Quick Start 内置数据结构 MongoDB是存…

24 静动态库

首先创建两个函数的头文件和源文件 最后的main函数 #include <stdio.h> #include "print.h" #include "sum.h"int main() {Print("时间");printf("%d\n", sum(3, 5));return 0; }将函数编译成.o文件 make生成文件 make he…

ENVI实战—一文学会使用传感器自带信息配准工具进行几何校正

实验1&#xff1a;学会使用传感器自带信息配准工具 目的&#xff1a;利用ENVI的传感器自带信息配准工具&#xff0c;掌握几何校正的一般方法。 过程&#xff1a; 1.对MODIS影像进行校正&#xff1a; ①读取影像&#xff1a;打开文件&#xff0c;点击“打开为”&#xff0c;…

windows下已经创建好了虚拟环境,但是切换不了的解决方法

用得多Ubuntu&#xff0c;今天用Windows重新更新anaconda出问题&#xff0c;重新安装之后&#xff0c;打开pycharm发现打开终端之后&#xff0c;刚开始是ps的状态&#xff0c;后面试了网上改cmd的方法&#xff0c;终端变成c盘开头了 切换到虚拟环境如下&#xff1a;目前的shell…

IDA动态调试

动态调试 这里我使用测试程序是buuctf逆向题目中的第一题easyre.exe 将其拖进IDA中打开 在调试前要选择调试器&#xff0c;在菜单栏找到调试器&#xff0c;如下选择之后点击确定。 在启动调试前下断点 下好断电到调试器里点击启动进程 会有警告信息&#xff0c;选择是即可…

ARP代理

10.1.0.1/8 和10.2.0.1/8是在同一个网段 10.1.0.2/16 和10.2.0.2/16 不在同一个网段 10.1.0.1/8 和10.1.0.2/16 是可以ping通的 包发出来了&#xff0c;报文有发出来&#xff0c;目的地址是广播包 广播请求&#xff0c;发到路由器的接口G 0/0/0 target不是本接口&#xff0…

Linux 序列化、反序列化、实现网络版计算器

目录 一、序列化与反序列化 1、序列化&#xff08;Serialization&#xff09; 2、反序列化&#xff08;Deserialization&#xff09; 3、Linux环境中的应用实例 二、实现网络版计算器 Sock.hpp TcpServer.hpp Jsoncpp库 Protocol.hpp MyDaemon.hpp CalServer.cc Ca…

3.1 iHRM人力资源 - 组织架构、树形结构、添加子部门

iHRM人力资源 - 组织架构 文章目录 iHRM人力资源 - 组织架构一、展示数据-树形组件1.1 组件说明1.2 树组件自定义结构获取作用域数据1.2.1 说明1.2.2 页面代码1.2.3 获取组织架构数据-api 1.3 效果图1.4 修改树形结构bug 二、添加子部门2.1 表单弹层2.1.1 下拉菜单点击事件2.1.…

中国科学院大学学位论文LaTeX模版

Word排版太麻烦了&#xff0c;公式也不好敲&#xff0c;推荐用LaTeX模版&#xff0c;全自动 官方模版下载位置&#xff1a;国科大sep系统 → \rightarrow → 培养指导 → \rightarrow → 论文 → \rightarrow → 论文格式检测 → \rightarrow → 撰写模板下载百度云&#…

Vitis HLS 学习笔记--readVec2Stream 函数-探究

目录 1. 高效内存存取的背景 2. readVec2Stream() 参数 3. 函数实现 4. 总结 1. 高效内存存取的背景 在深入研究《Vitis HLS 学习笔记--scal 函数探究》一篇文章之后&#xff0c;我们对于scal()函数如何将Y alpha * X这种简单的乘法运算复杂化有了深刻的理解。本文将转向…

前端console用法分享

console对于前端人员来讲肯定都不陌生&#xff0c;相信大部分开发者都会使用console来进行调试&#xff0c;但它能做的绝不仅限于调试。 最常见的控制台方法 作为开发者&#xff0c;最常用的 console 方法如下&#xff1a; 控制台打印结果&#xff1a; 今天我分享的是一些 co…

Vue3项目中快速引入ElementUI框架

ElementUI介绍 ElementUI是一个强大的PC端UI组件框架&#xff0c;它不依赖于vue&#xff0c;但是却是当前和vue配合做项目开发的一个比较好的ui框架&#xff0c;其包含了布局&#xff08;layout)&#xff0c;容器&#xff08;container&#xff09;等各类组件&#xff0c;基本上…