简读笔记-Redis设计与实现第四章

栏目: 数据库 · 发布时间: 5年前

内容简介:无非就是在数据结构上进行增加,删除节点事务从开始到结束所经历的几个阶段
  • 订阅频道
  • 订阅模式
SUBSCRIBE "news.it"		//订阅频道
SUBSCRIBE "news.[ie]t"	//订阅模式
PUBLISH "news.it" "hello" //发布消息
复制代码
简读笔记-Redis设计与实现第四章

频道订阅的数据结构

#使用字典保存所有频道的订阅信息
struct redisServer{
    //保存所有频道的订阅信息
    dict *pubsub_channels;
}
复制代码
简读笔记-Redis设计与实现第四章

模式订阅的数据结构

#使用链表保存所有模式的订阅信息
struct redisServer{
	//保存所有模式的订阅信息
	list *pubsub_patterns;
}

struct pubsubPattern{
	//订阅模式的客户
	redisClient *client;
	//被订阅的模式
	robj *pattern;
}pubsubPattern;
复制代码
简读笔记-Redis设计与实现第四章

频道和模式的订阅和退订过程

无非就是在数据结构上进行增加,删除节点

发送消息

  • 将消息发送给频道订阅者
    • 在频道字典表中找出对应的频道
    • 遍历链表,将消息发送给所有的订阅者
  • 将消息发送给模式订阅者
    • 遍历模式订阅链表
    • 如果频道和模式匹配,则将消息发送给订阅该模式的客户端

几个常用的命令

  • PUBSUB CHANNELS [pattern]

    • 用于返回服务器当前被订阅的频道

      若给定pattern参数, 则还需从被订阅频道列表中过滤 与pattern匹配 的频道

  • PUBSUB NUMSUB [channel_1,channel_2....]

    • 返回给定频道的订阅者数量
  • PUBSUB NUMPAT

    • 返回服务器当前被订阅模式的数量

回顾

  1. 服务器状态在pubsub_channels字典保存了所有频道的订阅信息: SUBSCRIBE命令负责将客户端和被订阅的频道关联到字典中,而UNSUBSCRIBE命令则负责解除客户端和被退订频道的关联
  2. 服务器状态在pubsub_patterns链表保存了所有频道的订阅信息: PSUBSCRIBE命令负责将客户端和被订阅的模式关联到这个链表中,而PUNSUBSCRIBE命令则负责解除客户端和被退订模式的关联
  3. PUBLISH命令通过访问pubsub_channels字典来向频道的所有订阅者发送消息,而通过pubsub_patterns链表来向所有匹配频道模式的订阅者发送消息
  4. PUBSUB命令的几个常用命令都是通过读取频道的字典和模式的链表信息来实现的.

事务

事务的实现

事务从开始到结束所经历的几个阶段

  • 事务开始
  • 事务入队
  • 事务执行

事务开始

MULTI

def MULTI();
	#打开事务标志
	client.flags |= REDIS_MULTI
	#返回OK回复
复制代码

事务入队

简读笔记-Redis设计与实现第四章

表示事务状态的数据结构

typedef struct redisClient{
    //事务状态
    multiState mstate ; 	
}

typedef struct multiState{
    //事务队列,FIFO顺序
    multiCmd *commands;
    // 已入队命令计数
    int count
}multiState;

typedef struct multiCmd{	//记录命令相关信息
    //命令参数
    robj **argv
    //参数数量
    int argc;
    //命令指针
    struct redisCommand *cmd
}multiCmd;
复制代码

结构图

简读笔记-Redis设计与实现第四章

事务执行

EXEC

执行事务的伪代码

def execute_transaction():

    # 创建空白的回复队列
    reply_queue = []

    # 取出事务队列里的所有命令、参数和参数数量
    for cmd, argv, argc in client.transaction_queue:

        # 执行命令,并取得命令的返回值
        reply = execute_redis_command(cmd, argv, argc)

        # 将返回值追加到回复队列末尾
        reply_queue.append(reply)

    # 清除客户端的事务状态
    clear_transaction_state(client)

    # 清空事务队列
    clear_transaction_queue(client)

    # 将事务的执行结果返回给客户端
    send_reply_to_client(client, reply_queue)
复制代码

watch命令的实现

WATCH命令是一个 乐观锁 , 它可以在EXEC命令执行之前,监视任意数量的数据库键,并在EXEC命令执行时,检查被监视的键是否至少有一个已经被修改过了, 如果是的话 , 服务器将拒绝执行事务,并向客户端返回代表事务执行失败的空回复

案例

简读笔记-Redis设计与实现第四章

WATCH命令的数据结构

typedef struct redisDB{
    //正在被WATCH命令监视的键
    dict *watched_keys;	//键为被监视的数据库键, 值为监视该键的客户端链表
}
复制代码
简读笔记-Redis设计与实现第四章

WATCH机制的触发

当数据库执行修改命令之后,都会调用 touchWatchKey函数对 watches_keys字典进行检查, 检查是否有客户端正在监视刚刚被命令修改过的数据库键, 如果有的话,那么touchWatchKey函数会将 监视被修改键的客户端REDIS_DIRTY_CAS 标志打开, 表示该客户端的事务安全性被破坏了.

判断事务是否安全

当服务端收到一个客户端发来的EXEC命令时,服务器会根据这个客户端是否打开了REDIS_DIRTY_CAS标志来决定是否执行事务

简读笔记-Redis设计与实现第四章

回顾

  • 事务提供了一种将多个命令打包,然后一次性,有序地执行的机制
  • 多个命令会被入队到事务队列中,然后按先进先出的顺序执行
  • 事务在执行过程中不会被中断,当事务队列的所有命令都被执行完毕之后,事务才会结束
  • 带有WATCH命令的事务会将客户端和被监视的键在数据库的watched_keys字典中进行关联,当键被修改时,程序会将所有监视被修改键的客户端的REDIS_DIRTY_CAS标志打开

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Java并发编程的艺术

Java并发编程的艺术

方腾飞、魏鹏、程晓明 / 机械工业出版社 / 2015-7-1 / 59.00元

并发编程领域的扛鼎之作,作者是阿里和1号店的资深Java技术专家,对并发编程有非常深入的研究,《Java并发编程的艺术》是他们多年一线开发经验的结晶。本书的部分内容在出版早期发表在Java并发编程网和InfoQ等技术社区,得到了非常高的评价。它选取了Java并发编程中最核心的技术进行讲解,从JDK源码、JVM、CPU等多角度全面剖析和讲解了Java并发编程的框架、工具、原理和方法,对Java并发编......一起来看看 《Java并发编程的艺术》 这本书的介绍吧!

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具