redis设计与实现(二):订阅与事务

1. 发布与订阅功能

  频道订阅与发布    

        订阅频道
                Redis创建了订阅字典结构来保存频道和订阅客户端之间的关系。字典的键则是被订阅的频道,值则是一个链表结构,存储订阅该频道的客户端。

redis设计与实现(二):订阅与事务_第1张图片
               **订阅的两个类别**:
                      1.当订阅字典中有这个频道时,则直接将订阅客户端添加至链表的末端
                      2.当订阅字典中没有个频道时,redis直接创建这个键,并创建空的链表结构。将正在创建的客户端添加至链表结构。

       退订频道
          unsubscribe命令是作为退订的。
          退订的逻辑和订阅的逻辑是相反的,没啥好讲的了。

  模式订阅与退订

      模式订阅数据结构图

redis设计与实现(二):订阅与事务_第2张图片
        这个结构是一个链表结构,链表单元由订阅的客户端client和被订阅的模式pattern组成。
          订阅的模式psubscribe
                  1.创建一个链表单元,设置链表单元的订阅客户端和被订阅的模式。
                  2.将链表单元添加到链表结构尾端
          退订的模式punsubscribe
               将对应的链表单元删除    
          

2.事务

   redis事务:事务提供了一种将多个命令请求打包,然后一次性或者按顺序的执行多个命令的机制,并且在事务执行期间,服务器不会中断事务而改去其他客户端的命令请求,它会将事务中所有命令都执行完毕才会去处理客户端的命令请求。

    命令:multi:开启事务,

               exec:执行事务,

               watch:

  事务的实现

       multi命令将客户端切换为事务状态

redis设计与实现(二):订阅与事务_第3张图片

如图:当命令进来,先判断客户端是否出于事务中,不在,执行命令并返回执行结果。

            在客户端在事务中,判断是否是这四种命令,是,则执行命令并返回结果

           不是这四种命令,将命令放入事务队列中,并且执行返回给客户端。

exec命令的实现原理:

#伪代码
def exec(){
    #创建空白的回复队列
     reply_queue = [];
     
     #遍历事务队列的每一个项
     for arg in mstate.command{
        
        #执行命令,并获取返回值
        reply = execute_command(arg);
        reply_queue.add(reply)
        }    
        
       #移除客户端的事务标识,切换为非事务状态
       client.flag = !REDIS_MULTI
       
       #清空事务队列状态 1.清除命令计数器 2.释放事务队列
       client.mstate.count = 0;
       release_transaction_queue(client.mstate.commmand)
       
       #返回事务执行结果给客户端
       send_exec_result_client(client, reply_queue)
}

 

你可能感兴趣的:(redis)