Redis五种数据结构整理

本文深入解析Redis中常用的数据结构,包括简单动态字符串(SDS)的优化特性,链表的双端无环特性,字典的哈希表实现及哈希冲突解决,跳跃表的高效查找以及压缩列表的内存节省策略。这些数据结构在Redis中扮演关键角色,支撑着其高性能和灵活性。
摘要由CSDN通过智能技术生成

简单动态字符串(SDS)

struct sdshdr {
	// 记录buf数组中已使用字节的数量
	int len;
	// 记录buf数组中未使用字节的数量
	int free;
	// 字节数组,用于保存字符串
	char buf[];
};

优点:

  • 获取字符串长度时间复杂度O(1)
  • 杜绝了缓冲区溢出
  • 减少修改字符串长度所需要的内存重分配次数
  • 二进制安全
  • 兼容部分C字符串函数

链表

//节点数据结构
typedef struct listNode {
	struct listNode *prev;
	struct listNode *next;

	void *value;
}listNode;
//list底层数据结构
typedef struct list {
	//表头、表尾
	listNode *head;
	listNode *tail;
	// 链表所包含的节点数量
	unsigned long len;
	// 节点值复制函数
	void *(*dup)(void *ptr);
	// 节点值是放过函数
	void (*free)(void *ptr);
	// 节点值对比函数
	int (*match)(void *ptr,void *key);
}list;

特点

  • 链表被广泛用于实现Redis的各种功能,比如列表建、发布与订阅、慢查询、监视器等。
  • 每个链表节点由一个listNode结构来表示,每个节点都有一个指向前置节点和后置节点的指针,所以Redis的链表实现是双端链表。
  • 每个链表使用一个list结构表示,这个结构带有表头节点指针、表尾节点指针,以及链表长度等信息。
  • 因为链表表头的前置节点和表尾节点的后置节点都指向NULL,所以Redis的链表实现是无环链表。
  • 通过为链表设置不同的类型特定函数,Redis的链表可以用于保存各种不同类型的值。

字典

字典的底层是哈希表,类似 C++中的 map ,也就是键值对。

//哈希表
typedef struct dictht {
	 // 哈希表数组
	 dictEntry **table;
	 // 哈希表大小
	 unsigned long size;
	 // 哈希表大小掩码,用于计算索引值
	 // 总是等于size-1
	 unsigned long sizemark;
	 // 该哈希表已有节点的数量
	 unsigned long used;
} dichht;

特点

  • 字典被广泛用于实现Redis的各种功能,其中包括数据库和哈希键。
  • Redis中的字典使用哈希表作为底层结构实现,每个字典带有两个哈希表,一个平时使用,另一个仅
    在进行rehash时使用。
  • Redis使用MurmurHash2算法来计算键的哈希值。
  • 哈希表使用链地址法来解决键冲突。

哈希冲突的解决方式

Redis的哈希表使用链地址法来解决键冲突,每个哈希表节点都有一个next指针,多个哈希表节点可以用这个单向链表连接起来,这就解决了键冲突的问题。

跳跃表

typedef struct zskiplistNode {
	 // 后退指针
	 struct zskiplistNode *backward;
	 // 分值 权重
	 double score;
	 // 成员对象
	 robj *obj;
	 // 层
	 struct zskiplistLevel {
		 // 前进指针
		 struct zskiplistNode *forward;
		 // 跨度
		 unsigned int span;
 	} leval[];
} zskiplistNode;
typedef struct zskiplist {
	 // 表头节点和表尾节点
	 struct zskiplistNode *header, *tail;
	 // 表中节点的数量
	 unsigned long length;
	 // 表中层数最大的节点的层数
	 int leval;
} zskiplist;

特点

  • 跳跃表是有序集合的底层实现之一
  • Redis的跳跃表实现由zskiplist和zskiplistNode两个结构组成,其中zskiplist用于保存跳跃表信息(比如表头节点、表尾节点、长度),而zskiplistNode则用于表示跳跃表节点每个跳跃表节点的层高都是1至32之间的随机数在同一个跳跃表中,多个节点可以包含相同的分值,但每个节点的成员对象必须是唯一的。
  • 跳跃表中的节点按照分值大小进行排序,当分值相同时,节点按照成员对象的大小进行排序。
  • 跳表是一种实现起来很简单,单层多指针的链表,它查找效率很高,堪比优化过的二叉平衡树,且比平衡树的实现。

压缩列表

压缩列表(ziplist)是列表键和哈希键的底层实现之一。当一个列表键只包含少量列表项,并且每个列表项要么就是小整数值,要么就是长度比较短的字符串,那么Redis就会使用压缩列表来做列表键的底层实现。

特点

看他的名字就能看出来,是为了节省内存造的列表结构。

来源:拓跋阿秀整理的pdf

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值