redis---第四部分 独立功能的实现
1 发布与订阅
# 发布与订阅
Redis的发布与订阅功能由PUBLISH、SUBSCRIBE、PSUBSCRIBE等命令组成
## 频道的订阅与退订
Redis将所有频道的订阅关系都保存在服务器状态的pubsub_channels字典里面,资格字典的键是某个被订阅的频道,而键的值则是一个链表,链表里面记录了所有订阅这个频道的客户端
## 模式的订阅与退订
1 频道的订阅与退订
订阅频道
退订频道
2 模式的订阅与退订
订阅模式
退订模式
3 发送消息
将消息发送给频道订阅者
将消息发送给模式订阅者
4 查看订阅信息
PUBSUB CHANNELS
PUBSUB NUMSUB
PUBSUB NUMPAT
订阅模式和频道到底有什么区别
2 事务
Redis通过MULTI、EXEC、WATCH等命令来实现事务功能。
一个事务从开始到结束通常会经历以下三个阶段:
1. 事务开始
2. 命令入队
3. 事务执行
1 事务的实现
1事务开始
MULTI
2 命令入队
3 事务队列
4 执行事务
EXEC
2 WATCH命令的实现
## WATCH命令的实现
WATCH命令是一个乐观锁,它可以在EXEC命令执行之前,监视任意数量的数据库键,并在EXEC命令执行时,检查被监视的键是否至少有一个已经被修改过了,如果是的话,服务器将拒绝执行事务,并向客户端返回代表事务执行失败的空回复
当服务器接收到一个客户端发来的EXEC命令时,服务器会根据这个客户端是否打开了`REDIS_DIRTY_CAS`标识来决定是否执行事务。
1 使用WATCH命令监视数据库键
2 监视机制的触发
3 判断事务是否安全
4 一个完整的WATCH事务执行过程
3 事务的ACID性质
原子性
一致性
隔离性
耐久性
3 Lua脚本
1 创建并修改Lua环境
创建Lua环境
载入函数库
创建redis 全局表格
使用Redis自制的随机函数来替换Lua原有的随机函数
创建排序辅助函数
创建redis.pcall 函数的错误报告辅助函数
保护Lua的全局环境
将Lua环境保存到服务器状态的lua属性里面
2 Lua环境协作组件
伪客户端
lua_scripts字典
3 EVAL命令的实现
定义脚本数据
将脚本保存到lua_scripts字典
执行脚本函数
4 EVALSHA命令的实现
5 脚本管理命令的实现
SCRIPT FLUSH
SCRIPT EXISTS
SCRIPT LOAD
SCRIPT KILL
6 脚本复制
复制EVAL命令、SCRIPT FLUSH命令和SCRIPT LOAD命令
EVAL SCRIPT FLUSH SCRIPT LOAD
复制EVALSHA命令
4 排序
1 SORT<key> 命令的实现
2 ALPHA选项的实现
3 ASC选项和DESC选项的实现
4 BY选项的实现
5 带有ALPHA选项的BY选项的实现
6 LIMIT选项的实现
7 GET选项的实现
8 STORE选项的实现
9 多个选项的执行顺序
# 排序
Redis的`SORT`命令可以对列表键、集合键或者有序集合键的值进行排序
`SORT`命令的最简单执行形式为:`SORT <key>`
```c
// 用于保存被排序值及其权重的结构
typedef struct _redisSortObject {
// 被排序键的值
robj *obj;
// 权重
union {
// 排序数字值时使用
double score;
// 排序字符串时使用
robj *cmpobj;
} u;
} redisSortObject;
```
5 二进制数组
1 位数组的表示
2 GETBIT命令的实现
3 SETBIT命令的实现
4 BITCOUNT命令的实现
二进制位统计算法 遍历算法
二进制位统计算法 查表算法
二进制位统计算法 variable-precision SWAR算法
二进制位统计算法 Redis算法
5 BITOP 命令的实现
# 二进制位数组
Redis提供了SETBIT、GETBIT、BITCOUNT、BITOP四个命令用于处理二进制数组
## 位数组的表示
Redis使用字符串对象来表示位数组,因为字符串对象使用的SDS数据结构是二进制安全的,所以程序可以直接使用SDS结构来保存位数组,并使用SDS结构的操作函数来处理位数组。
## BITCOUNT命令的实现
### 二进制位统计算法(1):遍历算法
遍历算法虽然实现起来简单,但效率非常低,因为这个算法在每次循环中只能检查一个二进制位的值是否为1,所以检查操作执行的次数将与位数组包含的二进制位的数量成正比
### 二进制位统计算法(2):查表算法
查表法是一种比遍历算法更好的统计方法,但受限于查表法带来的内存压力,以及缓存不命中可能带来的影响,我们只能考虑创建键长为8位或者键长为16位的表,而这两种表带来的效率提升,对于处理非常长的位数组来说任然远远不够。
### 二进制位统计算法(3):variable-precision SWAR算法
### 二进制位统计算法(4):Redis的实现
`BITCOUNT`命令的实现用到了查表和`variable precision SWAR`两种算法:
如果未处理的二进制位的数量小于128位,那么程序使用查表算法来计算二进制位的汉明重量
6 慢查询日志
# 慢查询日志
Redis的慢查询日志功能用于记录执行时间超过给定时长的命令请求,用户可以通过这个功能产生的日志来监视和优化查询速度
1 慢查询记录的保存
2 慢查询日志的阅览和删除
3 添加新日志
7 监视器
1成为监视器
2 向监视器发送命令信息
。