oracle hast,Redis不同数据类型的的数据结构实现

Redis支持五种数据类型,如字符串、哈希表、列表、集合和有序集合,其底层通过不同的数据结构实现,如简单动态字符串sds、双端链表、字典、跳跃表等。字符串类型可能使用原始字符串或整数存储,列表和哈希表在元素数量较少时使用压缩列表,多时使用双向链表或字典。集合和有序集合也有类似转换。Redis通过redisObject结构体模仿多态,通过type和encoding字段标识数据类型和底层实现。
摘要由CSDN通过智能技术生成

我们知道Redis支持五种数据类型,分别是字符串、哈希表(map)、列表(list)、集合(set)和有序集合,和Java的集合框架类似,不同数据类型的数据结构实也是不一样的。

1.Redis中的redisObject对象

Redis是使用C编写的,内部实现了一个struct结构体redisObject对象,

通过结构体来模仿面向对象编程的“多态”,作为一个底层的数据支持,redisObject代码:

/*

* Redis 对象

*/

typedef struct redisObject {

// 类型

unsigned type:4;

// 对齐位

unsigned notused:2;

// 编码方式

unsigned encoding:4;

// LRU 时间(相对于 server.lruclock)

unsigned lru:22;

// 引用计数

int refcount;

// 指向对象的值

void *ptr;

} robj;

其中type、encoding、ptr3个属性分别表示:

type:redisObject的类型,字符串、列表、集合、有序集、哈希表

encoding:底层实现结构,字符串、整数、跳跃表、压缩列表等

ptr:实际指向保存值的数据结构

如果一个 redisObject 的 type 属性为 REDIS_LIST , encoding 属性为 REDIS_ENCODING_LINKEDLIST ,

那么这个对象就是一个 Redis 列表,它的值保存在一个双端链表内,而 ptr 指针就指向这个双端链表;

如果一个 redisObject 的 type 属性为 REDIS_HASH , encoding 属性为 REDIS_ENCODING_ZIPMAP ,

那么这个对象就是一个 Redis 哈希表,它的值保存在一个 zipmap 里,而 ptr 指针就指向这个 zipmap 。

下面这张图片中的REDIS_STRING/REDIS_LIST/REDIS_ZSET/REDIS_HASH/REDIS_SET针对的是redisObject中的type,

后面指向的REDIS_ENCODING_LINKEDLIST等针对的是encoding字段。

c1bdf1320a309f98ca0305b87751b61a.png

Redis的底层数据结构有以下几种:

Redis的底层数据结构有以下几种:

简单动态字符串sds(Simple Dynamic String)

双端链表(LinkedList)

字典(Map)

跳跃表(SkipList)

下面针对五种数据类型,学习相关的底层数据结构。

2.String

如果一个String类型的value能够保存为整数,则将对应redisObject 对象的encoding修改为REDIS_ENCODING_INT,将对应robj对象的ptr值改为对应的数值。

如果不能转为整数,保持原有encoding为REDIS_ENCODING_RAW。

因此String类型的数据可能使用原始的字符串存储(实际为sds - Simple Dynamic Strings,对应encoding为REDIS_ENCODING_RAW)或者整数存储。

Redis可以直接查看对象的ENCODING值:

redis:6379> set strtest 1

OK

redis:6379> OBJECT ENCODING strtest

"int"

redis:6379> set strtest blog

OK

redis:6379> OBJECT ENCODING strtest

"raw"

3.List

列表的底层实现有2种:

REDIS_ENCODING_ZIPLIST

REDIS_ENCODING_LINKEDLIST

ZIPLIST相比LINKEDLIST可以节省内存,

当创建新的列表时,默认是使用压缩列表作为底层数据结构的。

Redis内部会对相关操作做判断,

当list的elem数小于配置值: hash-max-ziplist-entries 或者elem_value字符串的长度小于 hash-max-ziplist-value, 可以编码成 REDIS_ENCODING_ZIPLIST 类型存储,以节约内存;

但由于在zip list添加和删除元素会涉及到数据移动,

因此当list内容较多时,使用双向链表。

4.Hash

创建新的Hash类型时,默认也使用ziplist存储value,保存数据过多时,使用hast table。

5.Set

集合的底层实现也有两种:

REDIS_ENCODING_INTSET

REDIS_ENCODING_HT(字典)

创建Set类型的key-value时,如果value能够表示为整数,则使用intset类型保存value。

数据量大时,切换为使用hash table保存各个value。

6.Sorted Set

有序集合的底层实现也是2种:

REDIS_ENCODING_ZIPLIST

REDIS_ENCODING_SKIPLIST

下面关于Redis的文章您也可能喜欢,不妨参考下:

0b1331709591d260c1c78e86d0c51c18.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值