Redis设计与实现阅读笔记

第一部分:数据结构与对象

  • 第二章 字符串 SDS

  1. SDS simple dynamic string 
  2. 对c字符数组进行封装,支持len、free、buf。
  3. 解决了二进制安全问题
  4. 解决了频繁分配空间和计算长度等问题,优化了性能
  5. 末尾\0可复用string.h的部分函数
  • 第三章 链表

  1. ListNode:  *prev,*next, * value  List: listNode *head/tail, len
  2. 双端、无环、多态(可保存不同值)
  • 第四章 字典
  1. redis数据库和哈希键都使用字典存储。字典 ht[2]在rehash的时候使用
  2. 使用murmurHash算法计算hash :【需要了解一下】
  3. hash键冲突通过链表解决,会插入到头部。并没有使用树形结构,因此hash算法比较重要
  4. rehash的过程,创建一个新的hashtable,通过设置rehashidx,逐步将节点迁移到ht[1]中。
    1. 查询是先ht[0]/没有就查ht[1]
    2. 插入的时候ht[1]插入
    3. 更新的时候可以先查询再更新
    4. 删除操作:【书上没说,应该是ht[0]/ht[1]都尝试】
  • 第五章跳跃表
  1. 调表的能力和双向链表
  • 第六章 整数集合

  1. 有序存储,连续存储空间,为了减少存储空间,提升性能

  2. 只支持编码升级,不支持降级
  • 第七章 压缩列表

  1. 长度字段是可变字节,可能存在连锁更新问题
  2. 对于整数、短字符处理有优势
  • 第八章 对象
  1. 记录对象的信息,编码、元素等等,为一些指令提供高效支持,利用多态特性可以对编码转换问题提供更好支持。
  2. 内存回收:通过引用计数来判定对象是否回收
  3. 对象共享:共享相同对象,提升空间利用率。会初始化10000以内的整数字符串对象
  • 总结

    • 字符串、列表、哈希、集合、有序集合五中类型的对象。至少有2种编码方式。
    • 链表:列表键
    • 字典:哈希键
    • 跳表:有序集合
    • 整数集合:集合键
    • 压缩列表:列表键、hash键

第二部分 单机数据库的实现

  • 数据库
    • 单机Redis存在多个数据库,集群中每个redis实例只会使用0号数据库
    • 支持设置生存时间和过期时间,有专门的字段存放key的过期时间。过期字段有定时清理、惰性清理、定期清理三种策略,使用的是后两种。其中定期清理采用随机选择key进行判断和删除。
  • RDB持久化
    • 过期键不会被持久化
    • 支持同步和异步持久化指令。满足条件时会进行持久化,存在一定可能的数据不一致问题。持久化支持防竞争条件,一个时间只能有一个指令在执行。dirty计数器用于判定是否需要进行持久化。
    • bgsave通过创建子进程进行持久化,bgsave不解决持久化时增量数据问题
  • AOF持久化
    • 过期键不会被重写,过期键被持久化后不会影响一致性,因为del命令会被追加或者在还原数据库的时候,通过惰性策略会发现过期。
    • AOF持久化策略支持always、everysec、no三种策略。安全和效率不可兼得
    • AOF重写通过新建子进程来实现,同时通过buf区来缓存重写过程中的增量操作
  • 事件
    • ·需要处理文件事件和时间事件
    • 文件事件与IO相关,处理命令请求、恢复、连接应答等事件,轮流处理
    • 时间事件:分定时事件和周期事件。更新统计信息、过期key删除、关闭、清理失效客户端、AOF&RDB持久化、主从服务器定期同步、集群定期同步和连接测试
  • 客户端
    • ·包含伪客户端,这类客户端不需要套接字连接。普通客户端。
    • 可配置需要身份验证。
    • 空转时间过长的客户端会被关闭,但是存在订阅的客户端不会
  • 服务器
    • 前置:会验证客户端的指令、指令参数、身份验证、内存使用情况、
    • 后置:慢查询日志、统计技术、AOF、主从复制
    • 通过抽样判断一段时间的执行情况

第三部分 多级数据库实现

  • 复制
    • 复制指的是主从复制,可通过slaveof指令来复制一个主服务器数据
    • 支持完整重同步、部分重同步。通过记录偏移量来判断从哪个位置进行增量同步,解决各种原因导致的暂时失联问题。但是部分重同步存在缓存大小限制,偏移量不在缓存中了只能进行完整同步。
  • sentinel 哨兵
    • 解决redis高可用性的方案。由一个或多个sentinel实例监视多个主、从服务状态。启动sentinel和redis是一套代码,不同的指令集。
    • 连接服务器的有两个连接,一个命令连接、一个订阅连接
    • 通过获取主服务器信息,会同时获得主服务器的从服务器信息。
    • 通过发布订阅消息,sentinel也相当于向其他sentinel广播自己的信息,sentinel之间不会创建订阅连接
    • sentinel通过配置会主观判断主服务器、从服务器、sentinel的在线状态。发现下线实例以后会询问其他sentinel的判断状态,当超过配置阈值数的sentinel认为相同实例下线时,会判定客观下线。会发起故障转移命令
    • 需要选择领头sentinel来执行故障转移指令,选举方式为
      • 发现客观下线的机器会要求其他sentinel将自己设置为领头sentinel,如果超过半数支持就会确定了领头sentinel,否则在一段时间后再次进行选举。每个sentinel会接受第一个收到的要求,拒绝之后的要求(先到先得)
    • 故障转移:领头sentinel会从复制偏移量最大、优先级最高的从服务器中选择运行ID最小的从服务器作为新的主服务器。如果原来的主服务器上线了会被指定为从服务器
  • 集群
    • 集群机器通过分配槽点来建立完整集群,槽点个数为16384个
    • 如果指定不属于当前服务器处理的槽点,会返回moved错误,指引客户端到正确的节点发送指令
    • 计算槽点通过crc-16校验和来判断
    • 重新分片
      • 向向目标节点发送指令
      • 向源节点发送指令,获取槽点的多个键值对
      • 向目标节点发送迁移指令
      • 重复3/4知道完整迁移
      • 转移过程中,如果对转移槽点的键进行操作且键不存在时,会发送ASK错误,让客户端向目标节点发送指令
      • ask错误会在请求先打开REDIS_AKING标识,该标识只在一次请求中有效
    • 消息:MEET、PINT、PONG消息都会随机选择两个节点发送出去,接收者可以获取到其他节点信息

第四部分

  • 发布与订阅
    • 支持指定频道订阅和模式订阅
    • 需要将消息发送到指定订阅者
    • 如果一个频道无订阅者了要删除
  • 事务
    • MULTI、EXEC、来标记事务的开始和执行,一次可执行多个指令
    • WATCH来监视指定key,但是如果在执行前watch的key被操作了,会失败,服务器会判断监视的client的标识是否正确。
    • redis不支持回滚,即使错误也会把指令执行完
    • 事务中存在非法指令,事务会被拒绝
  • Lua脚本
    • 支持eval、evalsha、script load,script flush,script exists、script kill指令
    • 在服务器端会创建一个lua环境,替换其中的随机函数、排序函数。通过伪客户端来发送和redis的交互指令。会保护lua的全局环境,防止全局变量被修改。
    • 主从同步的时候,会记录是否所有从服务器都同步了脚本,是则发送evalsha指令,否则发送eval 指令。
    • 服务器上返回的sha1校验和也是lua函数名
  • 排序
    • 通过创建指针表,指针指向排序对象和排序依据
    • 通过快排实现
    • 支持limit、get、asc、desc指令,支持数值和字符串的排序
  • 二进制位数组
    • 位运算的实现
    • 计算1的个数的三种算法
      • 遍历计算
      • 查表
      • variable-precision  swar算法
        • 归并思想,对二进制进行分组,相邻的两组通过位移解决高低位不同问题,再通过加法得到每个组的1的个数
        • 归并3次算出分组为2/4/8的1的个数,在通过一次乘法+右移获取4组上1的个数总和。非常漂亮的算法
        • 计算非0二进制数的数量称为,计算汉明重量
  • 慢查询日志
    • 最近一段时间缓存中慢查询的信息
  • 监视器
    • 发送监视器指令,可以监控服务器的执行状态

REDIS 6的和3.0的差别

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GDRetop

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值