Redis五大数据结构的底层实现
Redis五大数据结构的底层实现
String
String是Redis最常见的数据存储类型
其基本编码方式是RAW,例如上图,基于简单动态字符串SDS实现,存储上限为512mb
如果存储的SDS长度小于44字节,则会采用EMBSTR编码,此时ObjectHead与SDS是一段连续的空间,申请内存时只需要调用一次内存分配函数,效率更好,如下图
这里为什么是44字节呢,因为它加上SDS头信息,RedisObject的头信息合起来刚好64字节,底层调用分配空间就是按照2的幂次进行分配的
如果存储的字符串是整数,并且大小在LONG_MAX范围内,则会采用INT编码,直接将数据保存在RedisObject的ptr指针位置,这样就不需要SDS了
List
list用于首尾操作列表中的元素
- 在3.2版本之前,Redis采用ZipList和LinkedList来实现List,当元素数量小于512并且元素大小小于64字节时采用ZipList,否则用LinkedList编码
- 在3.2版本之后,Redis统一采用QuickList来实现List
Set
单列集合,不保证有序,保证元素唯一,求交集,并集,差集
使用的Dict,key存储元素,value统一为null
当存储的所有数据都是整数,并且元素数量不超过set-max-intset-entries时,Set就会采用IntSet编码,以节省内存
只保存数字的结构图
如果又要插入字符串,编码方式就会发生变化 # ZSet
sortedSet,每个元素都需要指定一个score和member,可以根据score值进行排序,member必须唯一,可以根据member查询分数
实现方式结合了dict和skipList
可以看出ZSET很耗费空间,所以,当元素数量不多时,Hash和SkipList的优势不明显,而且更耗费内存,因此ZSET还会采用ZIPList结构来节省内存,需要满足如下条件
- 元素数量小于zset_max_ziplist_entries,默认值128
- 每个元素都小于zset_max_ziplist_value,默认值64
如果满足条件,默认使用zipList
zipList本身没有排序功能,也没有键值对概念,所以需要业务逻辑来实现
- socre和element时紧挨在一起的两个netry,element在前
- score越小越接近队首,按照socre升序排列
Hash
与Zset非常类似,都是键值存储,都需要根据键获取值,键必须唯一
Hash底层与Zset基本一致,只需要把排序有关的SkipList去掉
元素较少时
元素较多时就会转换成Dict
开发者涨薪指南 48位大咖的思考法则、工作方式、逻辑体系