《Redis设计与实现》读书笔记

这本书是一本不多的好书,把Redis设计和实现的细节讲得很清楚,虽然里面有一些细节算法如raft选举算法和variable swar

循环机制

redis服务器是事件驱动程序,服务器会处理两类事件

  1. 文件事件。套接字操作
  2. 时间时间。链表保存,非顺序链表,遍历查找
    • 定时时间
    • 定期时间

处理总逻辑

def main():
    #初始化服务器
    init_server()
    #一直处理事件,知道服务器关闭
    while server_is_not_shutdown():
        asProcessEvents()
    #服务器关闭
    clean_server()

事件的调度和执行
def aeProcessEvents():
#获取到达时间离当前时间事件
time_event = aeSearchNearestTimer()

    #计算最近的时间事件距离到达还有多少毫秒
    remaind_ms = time_event.when - unix_ts_now()
    
    #根据remaind_ms的值,创建timeval
    timeval = create_timeval_with_ms(remaind_ms)
    if timeval < 0:
        remaind_ms = 0
    
    #阻塞并期待文件事件产生,最大阻塞时间由传入的timeval结构决定
    #如果remaind_ms的值为0,那么aeApiPoll调用后立刻返回,不阻塞
    aeApiPoll(timeval)
    
    #处理所有已经产生的文件事件
    processFileEvent()
    #处理所有已经到达的时间时间
    processTimeEvent()

4种网络模型

  • 阻塞 I/O(blocking IO)
  • 非阻塞 I/O(nonblocking IO)
  • I/O 多路复用( IO multiplexing)
  • 异步 I/O(asynchronous IO)
    Redis采用的是I/O多路复用

集群

Redis集群是Redis提供的分布式数据库方案,集群通过分片(sharding)来进行数据共享,并提供复制和故障转移方案

节点

#连接各个节点
cluster meet <ip> <port>
#显示当前集群节点
cluster nodes
//3537963976396397 :0 myself, master - 0 0 0 connected

数据结构

  • clusterNode每个节点都会为集群内所有的一个clusterNode结构
    • ctime 创建的时间
    • name 节点的名字
    • flags 表示主从,上线下线
    • configEpoch 配置纪元,用于故障转移
    • ip 节点ip
    • port
    • clusterLink link 保存链接节点所需的有关信息
    • unsigned char数组 slots长度为16384/8
  • clusterLink
    • ctime 连接的创建时间
    • fd 描述符int类型
    • sndbuf 输出缓冲区
    • rcvbuf 输入缓冲区
    • ClusterNode nodes 与这个链接相关的节点
  • clusterState每个节点保存一个
    • myself,指向一个clusterNode
    • currentEpoch
    • state 上线还是下线
    • size
    • nodes 集群节点名单
    • slots 16384数组
      16384个槽,及槽指派

    槽指派

    cluster addslots 0 1 2 3 4
    槽指派信息,保存在clusterState和clusterNode中,不同处理场景
    MOVED命令



    重新分片及ASK错误



    故障检测流程
  • 通过ping消息,设置节点疑似下线
  • 集群中各个节点会通过互相发送消息交换信息,如在线,PFAIL,FAIL
  • 当收到疑似下线(PFAIL>一般),发送FAIL
  • 其他节点立刻表示FAIL
    故障转移及选举算法
  • 发现FAIL
  • 通过Raft在从节点中选择一个
  • 被选中的执行slaveof no one命令
  • 新节点指派FAIL节点所有的槽给自己
  • 发送pong消息

发布和订阅

服务器状态在pubsub channels字典里保存所有频道的订阅关系



服务器会在pubsub patterns链表保存所有模式的的订阅关系



publish命令执行两个动作
  1. 将消息发送给channel频道的所有订阅者
  2. 遍历patterns链表,对匹配的订阅者发送

事务

事务入队



watch命令通过watched——keys字典实现,将key对应到客户端,如果一个key被修改了,在客户端的表示里加REDIS-DIRTY-CAS


二进制维数组

getbit
setbit
bitcount
bittop

汉明重量的计算(Variabel-precision)

统计一个位数组非0二进制位的数量
#以32位为例
uint32_t swar(uint32_t t) {
#将该二进制以两个一组进行分组,各组的十进制表示该组的汉明重量
i = (i & 0x55555555) + ((i >> 1) & 0x55555555)
#将得到的结果以四个一组进行分组,各组的十进制表示该组的汉明重量
i = (i & 0x33333333) + ((i >> 1) & 0x33333333)
#将得到的结果以八个一组进行分组,各组的十进制表示该组的汉明重量
i = (i & 0x0F0F0F0F) + ((i >> 1) & 0x0F0F0F0F)
#计算出汉明质量并保存在最高为八位,然后转移到最低8
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 本文档翻译自 http://redis.io/topics/cluster-tutorial 。 本文档是 Red...
    会跳舞的机器人阅读 67,025评论 2 21
  • Redis Cluster原理分析 文章较长,如需转载可分段。转载请标明作者以及文章来源,谢谢! 作者介绍 姓名:...
    lihanglucien阅读 20,668评论 3 30
  • Redis Cluster Redis Cluster是Redis官方在Redis 3.0版本正式推出的高可用以及...
    Springlin阅读 9,203评论 1 5
  • 本文将从Redis的基本特性入手,通过讲述Redis的数据结构和主要命令对Redis的基本能力进行直观介绍。之后概...
    kelgon阅读 61,438评论 23 625
  • 一句话,挣着城市人的钱,还着农村人的债,钱债好还,人情难付。 好心人,天不负,身体健康! 抗的起家,抗的起责任,无...
    带有bug的文艺青年阅读 1,382评论 0 0

友情链接更多精彩内容