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数据结构解析的主要内容,如果未能解决你的问题,请参考以下文章

Redis定期删除和惰性删除

Redis升级

Redis学习笔记之单机实现

redis过期策略和内存淘汰机制

Redis的过期数据会被立马删除吗?

redis 和 memcache 的区别