redis设计与实现学习---(四)独立功能的实现

一 发布与订阅

1 简介
Redis的发布与订阅功能由PUBLISH、SUBSCRIBE、PSUBSCRIBE等命令组成。
SUBSCRIBE “news.it”
PUBLISH “news.it” “hello”
PSUBSCRIBE命令订阅一个或多个模式,从 而成为这些模式的订阅者:每当有其他客户端向某个频道发送消息时,消息不仅会被发送给 这个频道的所有订阅者,它还会被发送给所有与这个频道相匹配的模式的订阅者。

2 频道的订阅与退订SUBSCRIBE和UNSUBSCRIBE
订阅与退订对应着链表中怎加或者删除数据(如果没人订阅之后则key也会被直接删除)
在这里插入图片描述
在这里插入图片描述

3 模式的订阅与退订PSUBSCRIBE和PUNSUBSCRIBE
pubsub_patterns属性是一个链表,链表中的每个节点都包含着一个pubsub Pattern结构, 这个结构的pattern属性记录了被订阅的模式,而client属性则记录了订阅模式的客户端。
每当客户端执行PSUBSCRIBE命令订阅某个或某些模式的时候,服务器会对每个被订阅 的模式执行以下两个操作:
1)新建一个pubsubPattern结构,将结构的pattern属性设置为被订阅的模式,client属性设置为订阅模式的客户端。
2)将pubsubPattern结构添加到pubsub_patterns链表的表尾。
PUNSUBSCRIBE退订时则遍历链表并删除对应节点
在这里插入图片描述

4 发送消息
当一个Redis客户端执行PUBLISH命令将消息message发送给频道 channel的时候,服务器需要执行以下两个动作:
1)将消息message发送给channel频道的所有订阅者。
2)如果有一个或多个模式pattern与频道channel相匹配,那么将消息message发送给 pattern模式的订阅者(需要遍历整个pubsub_patterns链表)。

二 事务

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

2 事务队列
事务队列以先进先出(FIFO)的方式保存入队的命令,较先入队的命令会被放到数组的 前面,而较后入队的命令则会被放到数组的后面。
在这里插入图片描述

3 WATCH命令的实现
WATCH命令是一个乐观锁(optimistic locking),它可以在EXEC命令执行之前,监视任 意数量的数据库键,并在EXEC命令执行时,检查被监视的键是否至少有一个已经被修改过了,如果是的话,服务器将拒绝执行事务,并向客户端返回代表事务执行失败的空回复。
每个Redis数据库都保存着一个watched_keys字典,这个字典的键是某个被WATCH命令 监视的数据库键,而字典的值则是一个链表,链表中记录了所有监视相应数据库键的客户端。
在这里插入图片描述

4 执行事务
当服务器接收到一个客户端发来的EXEC命令时,服务器会根据这个客户端是否打开了 REDIS_DIRTY_CAS标识来决定是否执行事务:
如果客户端的REDIS_DIRTY_CAS标识已经被打开,那么说明客户端所监视的键当中, 至少有一个键已经被修改过了,在这种情况下,客户端提交的事务已经不再安全,所以服务 器会拒绝执行客户端提交的事务。
如果客户端的REDIS_DIRTY_CAS标识没有被打开,那么说明客户端监视的所有键都没 有被修改过(或者客户端没有监视任何键),事务仍然是安全的,服务器将执行客户端提交 的这个事务,如果其中有命令格式错误,则只会执行之前的命令,之后的则不会被执行。

三 二进制位数组

1 二进制位数组的操作
SETBIT key 0 1 #0下标的bit设置为1
GETBIT key 0 #获取0下标的bit值
BITCOUNT key #获取key中bit位是1的数量
BITOP AND and-result x y #对多个位数组进行按位与
BITOP OR or-result x y #对多个位数组进行按位或
BITOP XOR xor-result #对多个位数组进行按位异或
BITOP NOT not-value value #对单个位数组进行取反

2 二进制位数组的存储
Redis使用字符串对象来表示位数组,因为字符串对象使用的SDS数据结构是二进制安全的,所以程序可以直接使用SDS结构来保存位数组,并使用SDS结构的操作函数来处理位数组,buf本身存储的就是一个个的char,char=1字节=8bit。 但是注意,每个bit是按照逆序来存储的(CPU读数据从低位到高位读取即右->左)。例如下图我们看起来是10110010,实际这个字节存储的是01001101。
在这里插入图片描述

3 GETBIT命令的实现
1)计算byte= offset÷8,byte值记录了offset偏移量指定的二进制位保存在位数组的哪个字节,这里是下标。
2)计算bit=(offset mod 8)+1,bit值记录了offset偏移量指定的二进制位是byte字节的第几个二进制位,这里不按下标,是按第几个。
3)根据byte值和bit值,在位数组bitarray中定位offset偏移量指定的二进制位,并返回这个位的值。

4 SETBIT命令的实现
根据offset÷8的值与SDS中len的值进行比对判断需不需要扩容。然后按上面计算逻辑修改对应位置的BIT值

5 BITCOUNT命令的实现
① 遍历整个二进制数组,缺点效率太慢,但不浪费额外空间
② 采用查表法记录某个字节的bit位是1的数量,缺点占用空间,优点省时间
③ 汉明重量计算variable-precision SWAR算法,采用纯计算的方式获取N个字节二进制1数量
④ redis实现采用的是查表和variable-precisionSWAR两种算法的组合。

6 BITOP命令的实现
都是基于C语言提供的基础运算符计算的

四 慢日志查询

1 默认设置
可以通过SLOWLOG GET获取慢日志,服务器默认配置有两个和慢查询日志相关的选项,也可以通过启动后手动设置来实现。CONFIG SET slowlog-log-slower-than num 以及 CONFIG SET slowlog-max-len num。
slowlog-log-slower-than选项指定执行时间超过多少微秒(1秒等于1 000 000微秒)的命令请求会被记录到日志上。
slowlog-max-len选项指定服务器最多保存多少条慢查询日志。

2 慢日志存储
在这里插入图片描述
在这里插入图片描述

3 添加新日志的方式
在这里插入图片描述

五监视器

1 MONITOR命令
通过执行MONITOR命令,客户端可以将自己变为一个监视器,实时地接收并打印出服 务器当前处理的命令请求的相关信息

2 监视器的实现原理
在这里插入图片描述

六 GEO

建议查看原博客:
https://blog.csdn.net/ahjwpcn365373/article/details/101809840

七 stream

建议查看原博客:
https://blog.csdn.net/hanzkering/article/details/88833238

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值