开发者社区> 杰克.陈> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

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

简介: 原文:Redis不同数据类型的的数据结构实现 我们知道Redis支持五种数据类型, 分别是字符串、哈希表(map)、列表(list)、集合(set)和有序集合,和Java的集合框架类似,不同数据类型的数据结构实也是不一样的。
+关注继续查看
原文:Redis不同数据类型的的数据结构实现

我们知道Redis支持五种数据类型,

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

1.Redis中的redisObject对象

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*
 * 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字段。

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值:

1
2
3
4
5
6
7
8
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中的跳跃表,查看这篇文章:跳跃表
跳跃表在 Redis中的使用,就是实现有序集合数据类型。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Redis 数据类型sorted_set以及使用场景
Redis 数据类型sorted_set以及使用场景
29 0
redis各数据类型使用场景
redis各数据类型使用场景
48 0
Redis全方位详解--数据类型使用场景和redis分布式锁的正确姿势
原文:Redis全方位详解--数据类型使用场景和redis分布式锁的正确姿势   一、Redis数据类型   1.string     string是Redis的最基本数据类型,一个key对应一个value,每个value最大可存储512M。
1346 0
Redis数据类型及使用场景
redis支持常见的数据类型,现在是被广泛用在各大公司的内部,它可以做的东西很多,不过要先了解下他提供的基本数据类型与常见操作。接下来一起看看把。 字符串 最基础的数据类型,首先key是字符串类型,其它的数据类型都是在字符串的基础之上构建的。
760 0
突破Java面试(24)-Redis的持久化机制
Redis的持久化有哪几种方式?不同的持久化机制都有什么优缺点?持久化机制具体底层是如何实现的?
5112 0
面试时经常会被问到的Redis问题,持久化,存储结构,架构模式
介绍:Redis 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API的非关系型数据库。 传统数据库遵循 ACID 规则。
1426 0
Redis探寻(第二话)零基础理解Redis持久化机制
写在前面:        开这个系列是希望随着自己的学习成长尝试总结一些容易有坑或理解上可能有一定难度的课题,期许其他有兴趣的同学阅读能够直观的理解并快速掌握;所以本系列主要目标读者为Redis入门或非技术同学,其他资深同学如已有一定理解,可以直接略过;该系列中任何讲解不当之处欢迎指正。 Redis本身作为一个内存KV Store,本篇暂不探讨其性能如何强
626 0
Redis客户端连接以及持久化数据(三)
0、Redis目录结构       1)Redis介绍及部署在CentOS7上(一)       2)Redis指令与数据结构(二)       3)Redis客户端连接以及持久化数据(三)       4)Redis高可用之主从复制实践(四)       5)Redis高可用之哨兵模式Sentinel配置与启动(五)       6)Redis高可用之集群配置(六)   一、介绍 上篇文章我们讲解了Redis的结构与指令,其实很简单,我也没有过多的讲解,这次我们讲解一下Redis连接客户端以及持久化方案。
962 0
+关注
杰克.陈
一个安静的程序猿~
10424
文章
2
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载