redis设计与实现笔记

参考 黄健宏.Redis 设计与实现[M].机械工业出版社:北京,2014

chapter 2 简单动态字符串

  • SDS (简单动态字符串) 定义
struct sdshdr{
 int len;
 int free;
 char buf[];
}

遵循C字符串以空字符结尾的管理

  • SDS 与C 字符串的区别
    C字符串并不记录自身的长度信息
    SDS 记录自身的长度 (len属性)
    杜绝缓冲溢出
    空间预分配
    惰性空间释放 优化
    二进制安全
    (因为SDS使用len属性的值而不是空字符串来判断字符是否结束)
    通过使用二进制安全的SDS ,而不是C字符串,使得red is 不仅可以保存文本数据,还可以保存任意格式的二进制数据

  • C SDS字符串区别

CSDS
获取字符串长度的复杂度为O(N)获取字符串长度的复杂度为O(1)
API 是不安全的,可能会造成缓冲区溢出API 是安全的,不会造成缓冲区溢出
修改字符串长度为N次必然需要执行N次内存重新分配修改字符串长度为N次最多执行N次内存重新分配
只能保存文本文件可以保存文本文件或者二进制数据
可以使用所有string.h库中的函数可以使用一部分string.h库中的函数

chapter 3 链表

typedef struct listNode{
	struct listNode *prev;
	struct listNode *next;
	void *value
	}listNode
  • 链表提供了高效的节点重排能力,以及顺序性的节点访问方式,并且可以通过增删节点来灵活的调整链表表的长度。
  • 链表被广泛用于实现redis的各种功能,比如列表键,发布与订阅慢查询 监视器等
  • 列表键的底层实现之一是链表
red is 的链表实现的特性
双端链表节点带有prev和next指针,获取某个节点的前置节点和后置节点的复杂度都是O(1)
无环表头节点的prev指针和表尾节点的next指针都指向NULL,对链表的访问以NULL为终点
带表头指针和表尾指针通过list结构的head指针和tail指针,程序获取链表的表头节点和表尾节点的复杂度为O(1)
带链表长度计数器程序使用list结构的len属性来对list持有的链表节点进行计数,程序获取链表中节点数量的复杂度为O(1)
多态链表节点使用void*指针来保存节点值,并且可以通过list结构的dup、free、match三个属性为节点值设置类型特定函数,所以链表可以用于保存各种不同类型的值

chapter4 字典

red is的字典视同哈希表为底层实现,一个哈希表可以有多个哈希表节点,而每个哈希表节点保存了字典中的一个键值对

  • 哈希算法
    当要将一个新的键值对添加到字典里面时,程序需要先根据键值对的键计算出哈希值和索引值,然后再根据索引值,
    将包含新键值对的哈希表节点放到哈希表数组的指定索引上面。
    哈希表使用链地址法来解决键冲突,被分配到同一个索引上的多个键值对会连接成一个单向链表。

chapter 5 跳跃表

跳跃表
skip list 是一种有序数据结构,他通过在每个节点中维持多个指向其他节点的指针,从而达到快递 访问节点的目的。
Redis使用跳跃表作为有序集合键的底层实现之一 (sorted set )

chapter6 整数集合

整数集合(intset) 是集合键的底层实现之一。
整数集合的底层为数组,这个数组以有序无重复的方式保存集合元素

chapter 7 压缩列表

ziplist 是列表键和哈希键的底层实现之一

chapter8 对象

Redis并没有直接使用这些数据结构来实现键值对数据库,而是基于这些数据结构创建了一个对象系统,这个系统包含字符串对象、列表对象、哈希对象、集合对象和有序集合对象这五种类型的对象,每种对象都用到了至少一种我们前面所介绍的数据结构

字符串对象的编码可以是int ,raw,embstr
列表对象的编码可是是ziplist ,linkedlist
ziplist编码的列表对象使用压缩列表作为底层实现,每个压缩列表节点(entry)保存了一个列表元素

另一方面,linkedlist编码的列表对象使用双端链表作为底层实现,每个双端链表节点(node)都保存了一个字符串对象,而每个字符串对象都保存了一个列表元素

哈希对象的编码可是是ziplist hashtable

ziplist编码的哈希对象使用压缩列表作为底层实现,每当有新的键值对要加入到哈希对象时,程序会先将保存了键的压缩列表节点推入到压缩列表表尾,然后再将保存了值的压缩列表节点推入到压缩列表表尾
另一方面,hashtable编码的哈希对象使用字典作为底层实现

集合对象的编码方式可以是intset,hashtable

有序集合的编码方式可以是ziplist skiplist

skiplist编码的有序集合对象使用zset结构作为底层实现,一个zset结构同时包含一个字典和一个跳跃表

  • 内存回收
    因为C语言并不具备自动内存回收功能,所以Redis在自己的对象系统中构建了一个引用计数(reference counting)技术实现的内存回收机制,通过这一机制,程序可以通过跟踪对象的引用计数信息,在适当的时候自动释放对象并进行内存回收。

chapter9

过期键删除策略

  • 定时删除
  • 惰性删除
  • 定期删除

chapter 10 RDB持久化

命令

  • SAVE 阻塞red is服务器进程
  • BGSAVE 派生子进程

RDB持久化既可以手动执行也可以根据服务器的配置选项定期执行,该功能可以将某个时间点上的数据库状态保存到一个RDB文件中。
RDB 持久化功能所生成的RDB文件是一个经过压缩的二进制文件,通过该文件可以还原生成RDB文件时的数据库状态。
对于不同类型的键值对 RDB文件会使用不同的方式来保存他们

chapter 11 AOF 持久化

Append Only File
RDB持久化通过保存数据库中的键值对来记录数据库状态
通过保存redis服务器所执行的写命令来记录数据库状态

步骤

  • append
  • 文件写入
  • 文件同步sync

chapter 16 Sentinel

Sentinel(哨岗、哨兵)是Redis的高可用性(high availability)解决方案:由一个或多个Sentinel实例(instance)组成的Sentinel系统(system)可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器,然后由新的主服务器代替已下线的主服务器继续处理命令请求

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值