目录前言《Redis常用命令及示例总结(api)》:https://www.cnblogs.com/dlhjw/p/15639773.html1. 发布订阅1.1 频道的订阅与退订1.2 模式的订阅与退订1.3 发送消息1.4 查看订阅消
参考资料:《Redis设计与实现 第二版》;
第三部分为独立功能的实现,主要由以下模块组成:发布订阅、事务、Lua 脚本、排序、二进制位数组、慢查询日志、监视器;
本篇将介绍 Redis 的发布订阅与事务。Redis 提供了频道与模式的订阅与退订,支持对频道发送消息。Redis 的事务机制支持一次性、按顺序执行多个命令,以及事务的 ACID 性质;
与本章相关的 Redis 命令总结在下篇文章,欢迎点击收藏,本篇将不再重复:
客户端使用 SUBSCRIBE 命令订阅某个或某些频道;
客户端使用 UNSUBSCRIBE 命令退订频道;
Redis 将所有频道的订阅关系保存在服务器状态的 pubsub_challens
字典里:
struct redisService{
//...
//保存所有频道的订阅关系
dict *pubsub_channels;
};
客户端使用 PSUBSCRIBE 命令订阅某个或某些模式;
客户端使用 PUNSUBSCRIBE 命令退订模式;
Redis 将所有模式的订阅关系保存在服务器状态的 pubsub_patterns
链表里:
struct redisServer{
//...
//保存所有模式订阅关系,记录被订阅的模式
list *pubsub_patterns;
};
pubsub_patterns
链表保存的结构体如下:
typedef struct pubsubPattern{
//订阅模式的客户端
redisClient *client;
//被订阅的模式
robj *pattern;
} pubsubPattern;
pubsubPattern
结构体,并添加到链表尾部;pubsub_channels
字典里找到频道 channel
的所有订阅者名单(链表),然后将消息发送给名单上的所有客户端;pubsub_patterns
链表,查找与 channel
频道相匹配的模式,然后将消息发送给订阅了这些模式的客户端;
pubsub_channels
字典中对应频道键的链表值的长度;pubsub_patterns
链表的长度;flags
属性为 REDIS_MULTI 实现;Redis 客户端里有事务状态属性 mstate
:
typedef struct redisClient{
//...
//事务状态
multiState mstate;
} redisClient;
multiState
事务状态结构,包含事务队列与计数器:
typedef struct multiState{
//事务队列,FIFO排序
multiCmd *commands;
//已入队命令计数
int count;
} multiState;
WATCH 命令是一个乐观锁;
在执行 EXEC 命令前:监视任意数量的数据库建;
在执行 EXEC 命令时:检查被监视的键是否至少有一个已经被修改,是则拒绝执行事务,返回错误;
Redis 数据库保存一个 watched_keys
字典:
typedef struct redisDb{
//...
// 字典,键表示被 WATCH 命令监视的数据库键;值为链表,记录监视该键的客户 端
dict *watched_keys;
} redisDb;
所有对数据库进行修改的命令,在执行后都会调用 multi.c/touchWatchKey
函数对 watched_keys
字典进行检查:
服务器接收到 EXEC 命令时,会根据客户端是否打开 REDIS_DIRTY_CAS 标识决定是否执行事务:
当一个事务执行完毕,执行事务所得的结果会被保存到永久性存储介质;
Redis 的事务耐久性由持久化模式支持:
服务器的持久化模式 | 事务的耐久性 | 说明 |
---|---|---|
无持久化模式 | 不具有 | |
RDB 持久化模式 | 不具有 | 服务器只会在特定条件下执行 BGSAVE |
AOF 持久化模式,且appendfsync 的值为 always |
具有 | 程序总在执行命令后调用同步函数 |
AOF 持久化模式,且appendfsync 的值为 everysec |
不具有 | 程序每秒同步一次命令数据到硬盘 |
AOF 持久化模式,且appendfsync 的值为 no |
不具有 | 同步操作由操作系统决定 |
服务器打开了 no-appendfsync-on-rewrite 选项 |
不具有 | 该选项打开时,服务器在执行 BGSAVE 或 BGREWRITEAOF 命令时,会暂时停止对 AOF 文件进行同步(尽可能减少 I/O 阻塞) |
不管 Redis 在上面模式下运行,在事务最后加上 SAVE 命令总可以保证事务的耐久性。但因为效率低,不具有实用性;
--结束END--
本文标题: Redis | 第8章 发布订阅与事务《Redis设计与实现》
本文链接: https://www.lsjlt.com/news/8986.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-05-08
2024-05-08
2024-05-08
2024-05-08
2024-05-08
2024-05-08
2024-05-08
2024-05-08
2024-05-08
2024-05-08
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0