Redis数据结构解析
Posted lisin-lee-cooper
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis数据结构解析相关的知识,希望对你有一定的参考价值。
一.五种数据结构
String:字符串类型
List:列表类型
Set:无序集合类型
ZSet:有序集合类型
Hash:哈希表类型
二.RedisObject
redisObject 用来表示所有的key 和 value ,用redisObject 结构体来表示String 、Hash、
List、Set、ZSet;
redisObject 结构:
数据类型(type)
编码方式(encoding)
数据指针 (ptr)
虚拟内存(vm)
其他信息
三.数据的编码方式和应用场景
3.1 String
String类型的数据结构存储方式有三种 :
int:存储整数型值,ptr直接保存整数值
raw :长度大于32个字节的字符串,使用SDS(simple dynamic string)方式来存储,
embstr:长度小于32个字节
简单动态字符串(SDS)有三个属性
int len :保存了字符串的长度 ,获取字符串长度时,时间复杂度O(1)
int free: 表示buf数组中未使用的字节数量
char buf[] :保存字符串的每一个字符元素
SDS:可动态扩容和惰性空间释放,通过free记录不使用的空间,下次使用时再释放
3.2 Hash
Hash对象实现方式有hashtable 和 ziplist 两种
hashtable:同HashMap ,链地址法解决冲突, key 是String类型,value 是 key-value 的entry结构
dictEntry **table: 哈希表数组
unsigned long size: hash表大小
unsigned long sizemask: 用于计算索引值,==size-1,
unsigned long used: hash表中已有节点数
ziplist(压缩列表):是一组连续内存块组成的顺序的数据结构,其结构如下:
zlbytes:4个字节的大小,记录压缩列表占用内存的字节数。
zltail:4个字节大小,记录表尾节点距离起始地址的偏移量,用于快速定位到尾节点的地址。
zllen:2个字节的大小,记录压缩列表中的节点数。
entry:表示列表中的每一个节点。
zlend:表示压缩列表的特殊结束符号’0xFF’
其中entry的结构如下:
previous_entry_ength表示前一个节点entry的长度,可用于计算前一个节点的起始地址
encoding:这里保存的是content的内容类型和长度。
content:content保存的是每一个节点的内容。
应用场景:保存实体对象,key为实体对象id ,value为实体对象属性和值;
如:会计科目,供应商实体等
3.3 list
Redis中的列表在3.2之前的版本是使用ziplist和linkedlist进行实现的。在3.2之后的版本就是引入了quicklist;
linkedlist和quicklist的底层实现是采用双向链表进行实现,结构如下:
每一个节点都有指向前一个节点和后一个节点的指针。
头节点和尾节点的prev和next指针指向为null,所以链表是无环的。
链表有自己长度的信息,获取长度的时间复杂度为O(1)。
应用场景:「阻塞队列」, 生产者使用lupsh从列表的左侧插入元素,消费者使用brpop命令从队列的右侧获取元素进行消费;
3.4 set
Set的底层实现是hashtable 和 intset
intset 用来存储整数值得数据结构,其结构如下:
encoding:编码方式
length:整数集合的长度
contents[]:元素内容
应用场景:去重、活动id,优惠券id
3.5 ZSet
底层实现是ziplist和skiplist
skiplist也叫做「跳跃表」,跳跃表是一种有序的数据结构,它通过每一个节点维持多个指向其它节点的指针,从而达到快速访问的目的。
跳跃表节点结构如下:
head和tail表示指向头节点和尾节点的指针,能快速的实现定位
level表示层数,
len表示跳跃表的长度,
BW表示后退指针,在从尾向前遍历的时候使用
应用场景:历史搜索记录,演出常见问题
以上是关于Redis数据结构解析的主要内容,如果未能解决你的问题,请参考以下文章