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

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介:

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

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

>>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的底层数据结构有以下几种:
简单动态字符串sds(Simple Dynamic String)
双端链表(LinkedList)
字典(Map)
跳跃表(SkipList)

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

>>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"

  

>>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内容较多时,使用双向链表。

>>Hash

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

>>Set

集合的底层实现也有两种:
REDIS_ENCODING_INTSET
REDIS_ENCODING_HT(字典)
创建Set类型的key-value时,如果value能够表示为整数,则使用intset类型保存value。
数据量大时,切换为使用hash table保存各个value。

>>Sorted Set

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

关于Redis中的跳跃表,查看这篇文章:跳跃表
跳跃表在 Redis中的使用,就是实现有序集合数据类型。

 


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
6月前
|
存储 NoSQL Redis
Redis-数据结构
Redis 共有 5 种基本数据结构:String(字符串)、List(列表)、Set(集合)、Hash(散列)、Zset(有序集合)。 这 5 种数据结构是直接提供给用户使用的,是数据的保存形式,其底层实现主要依赖这 8 种数据结构:简单动态字符串(SDS)、LinkedList(双向链表)、Hash Table(哈希表)、SkipList(跳跃表)、Intset(整数集合)、ZipList(压缩列表)、QuickList(快速列表)。 Redis 基本数据结构的底层数据结构实现如下: Redis 3.2 之前,List 底层实现是 LinkedList 或者 ZipList。 Re
24 0
|
7月前
|
存储 监控 NoSQL
Redis系列(一):深入了解Redis数据类型和底层数据结构(三)
Redis系列(一):深入了解Redis数据类型和底层数据结构(三)
|
7月前
|
存储 缓存 NoSQL
Redis系列(一):深入了解Redis数据类型和底层数据结构(四)
Redis系列(一):深入了解Redis数据类型和底层数据结构(四)
|
7天前
|
NoSQL Redis
Redis的常用数据结构之哈希类型
Redis的常用数据结构之哈希类型
12 0
|
7月前
|
存储 缓存 NoSQL
Redis系列(一):深入了解Redis数据类型和底层数据结构(一)
Redis系列(一):深入了解Redis数据类型和底层数据结构
|
3月前
|
存储 NoSQL 定位技术
常见的Redis数据结构
常见的Redis数据结构
|
3月前
|
存储 NoSQL Redis
|
7月前
|
存储 消息中间件 NoSQL
Redis系列(一):深入了解Redis数据类型和底层数据结构(二)
Redis系列(一):深入了解Redis数据类型和底层数据结构(二)
|
8月前
|
存储 NoSQL Redis
Redis系列(一):深入了解Redis数据类型和底层数据结构
Redis系列(一):深入了解Redis数据类型和底层数据结构
Redis系列(一):深入了解Redis数据类型和底层数据结构
|
8月前
|
存储 NoSQL 定位技术
redis数据结构
redis数据结构
53 0