带你走进Redis的世界 - Redis的数据结构

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 带你走进Redis的世界 - Redis的数据结构

前言

Redis(Remote Dictionary Server)是一个Key-value存储系统,使用C语言编写,遵守BCD协议(BCD协议提供给使用者很大自由)。

Redis运行于独立的进程,通过网络协议和应用进行交互,将数据保存至内存中,提供多种方式,进行数据的持久化保存。Redis具有跨服务器的水平拆分、复制的分布式特性。Redis不同于一般key-value数据库,value本身具有结构化。


数据结构

image.pngRedis数据结构如上图所示。

Redis是典型的NoSql 非关系型数据库,没有传统的table结构。数据库db以编号作为定义,默认为db0。

/**
* Redis 内部对象数据结构定义
*/
typedef struct redisObject{
unsigned type:4;
unsigned encoding:4;
unsigned 1ru:REDIS_LRU_BITS;
int refcount;
void *ptr;
} robj;

type: redis的数据结构类型,string list map set sorted-set

encoding: redis数据结构具体的实现方式,比如string可以由int、char[] 来实现

lru:表示本对象空转时间,有限内存下长期不访问对象清理

refcount: 应用计数,用于对象的垃圾回收

ptr:指的使用encoding作为实际的实现方式所在实际地址

string

redis的string类型,可以表示以下三种数据

  • 字符串
  • 整数
  • 浮点数

浮点数,限于双精度

整数、浮点数,类型的value,具有自增、自减等数字型操作,并且redis自动识别精度、值域范围,根据精度、值域自动进行类型升级

127.0.0.1:6379> set test 123
OK
127.0.0.1:6379> incr test
(integer) 124

相关的redis命令手册,详见官方网站:https://www.redis.net.cn/order/

image.png

string类型,在内存中,以字节串作为承载的,在内部以int、SDS作为结构存储。

int,存储整数型数据;SDS存放字节、浮点型数据

List

list即列表对象,用于存储string序列

主要操作如下:

RPUSH/LPUSH: 将指定的string内容添加到给定的key的开头或者结尾

127.0.0.1:6379> rpush test "nihao"
(integer) 1

RPOP/LPOP:取出指定的key对应的开头或结尾

127.0.0.1:6379> Rpop test
"nihao"

LINDEX: 取出指定的key的索引下标下的值

127.0.0.1:6379> del test
(integer) 0
127.0.0.1:6379> rpush test "123"
(integer) 1
127.0.0.1:6379> rpush test "456"
(integer) 2
127.0.0.1:6379> rpush test "12312"
(integer) 3
127.0.0.1:6379> lindex test 2
"12312"
127.0.0.1:6379> lindex test 0
"123"

LRANGE: 取出指定的key范围内的值

127.0.0.1:6379> Lrange test 0 -1
1) "123"
2) "456"
3) "12312"
127.0.0.1:6379> Lrange test 0 2
1) "123"
2) "456"
3) "12312"

下标 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。

更多操作,感兴趣的可以去官网了解下。

List类型的value对象,内部以LinkedList或者ziplist实现,当list的元素个数或者单个元素长度很小时,会采用ziplist实现,否则将会使用linkedlist实现。

LinkedList是一个双向链表。ZipList采用的可变长度的压缩方法,针对值较小的整数、较短的string具有很好的压缩效果。

Map

Map又叫hash,维护的是一个hash表。维护了多个key-value ,且key不重复。

Redis本身数据结构为key-value,值也可以是key-value,但是值内的value不能再嵌套map,只能是string类型能表达的内容(整形、字节型、浮点型)。

image.png

map类型的数值,redis提供了以上的操作实现。

HSET: 为指定的key,设置key -value值

HGET:获取指定的key的字段中key的值

127.0.0.1:6379> hset test nihao "123"
(integer) 1
127.0.0.1:6379> hget test nihao
"123"

map在内部实现包括ziplist和hashtable两种,对于数据量比较小的,采用ziplist实现。

哈希表,在Redis中分为三个层级,由低向上:

dictEntry:管理一个key-value对,同时保留同一个桶中的相邻元素的指针

dictht:维护所有的桶链

dict:当桶链需要扩容或者缩容时,管理迁移

大致上,如图所示理解

image.png

Set

类似List,是一个无序集合,元素不重复。

基本操作命令如下图所示,具体使用,照例查找官方说明

image.pngSADD:为指定的key,添加新的值

SMEMBERS:获取指定的key的所有值

127.0.0.1:6379> sadd test "nihaoa"
(integer) 1
127.0.0.1:6379> sadd test "woca"
(integer) 1
127.0.0.1:6379> SMEMBERS test
1) "woca"
2) "nihaoa"

Set在内部以intset或者hashtable来实现。对于采用hashtable实现,其中value永远为null,当set中只包含整形元素,采用intset实现。

intset核心元素是一个字节数组,从小到大有序存放set的元素。

typedef struct intset {
uint32_t encoding;
uint32_t length;
int8_t contents[];
} intset;

intset,由于是有序的整型数据存储,所以采用了二分查找法进行数据的操作。

查找时间复杂度为O(log(N)),插入时间复杂度为O(N)

Sorted-set

Sorted-set 是redis 独有的数据结构,类似map是一个key-value对。但是它是一个有序的key-value对。

key:key-value中的键,在一个sorted-set中不重复

value:是一个浮点数,成为score

有序:sorted-set 内部按照score从小到大排序

image.pngZADD: 为指定的key添加值,注意格式为 ZADD KEY_NAME SCORE1 VALUE1.. SCOREN VALUEN

127.0.0.1:6379> zadd test 1 "nihao"
(integer) 1
127.0.0.1:6379> zadd test 1 "nihaoa"
(integer) 1
127.0.0.1:6379> zrange test 0 1
1) "nihao"
2) "nihaoa"
127.0.0.1:6379> zadd test 4 "woshishui" 3 "hahah"
(integer) 2
127.0.0.1:6379> zrange test 0 -1
1) "nihao"
2) "nihaoa"
3) "hahah"
4) "woshishui"

Sorted-set内部以ziplist或者skiplist+hashtable实现。

感兴趣的可以多了解下,skiplist(跳表)

相关实践学习
基于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
目录
相关文章
|
23天前
|
存储 消息中间件 NoSQL
Redis数据结构:List类型全面解析
Redis数据结构——List类型全面解析:存储多个有序的字符串,列表中每个字符串成为元素 Eelement,最多可以存储 2^32-1 个元素。可对列表两端插入(push)和弹出(pop)、获取指定范围的元素列表等,常见命令。 底层数据结构:3.2版本之前,底层采用**压缩链表ZipList**和**双向链表LinkedList**;3.2版本之后,底层数据结构为**快速链表QuickList** 列表是一种比较灵活的数据结构,可以充当栈、队列、阻塞队列,在实际开发中有很多应用场景。
|
27天前
|
存储 消息中间件 NoSQL
Redis 数据结构与对象
【10月更文挑战第15天】在实际应用中,需要根据具体的业务需求和数据特点来选择合适的数据结构,并合理地设计数据模型,以充分发挥 Redis 的优势。
55 8
|
27天前
|
存储 NoSQL Java
介绍下Redis 的基础数据结构
本文介绍了Redis的基础数据结构,包括动态字符串(SDS)、链表和字典。SDS是Redis自实现的动态字符串,避免了C语言字符串的不足;链表实现了双向链表,提供了高效的操作;字典则类似于Java的HashMap,采用数组加链表的方式存储数据,并支持渐进式rehash,确保高并发下的性能。
介绍下Redis 的基础数据结构
|
1月前
|
消息中间件 存储 缓存
redis支持的数据结构
redis支持的数据结构
32 2
|
22天前
|
存储 NoSQL 关系型数据库
Redis的ZSet底层数据结构,ZSet类型全面解析
Redis的ZSet底层数据结构,ZSet类型全面解析;应用场景、底层结构、常用命令;压缩列表ZipList、跳表SkipList;B+树与跳表对比,MySQL为什么使用B+树;ZSet为什么用跳表,而不是B+树、红黑树、二叉树
|
23天前
|
存储 NoSQL Redis
Redis常见面试题:ZSet底层数据结构,SDS、压缩列表ZipList、跳表SkipList
String类型底层数据结构,List类型全面解析,ZSet底层数据结构;简单动态字符串SDS、压缩列表ZipList、哈希表、跳表SkipList、整数数组IntSet
|
1月前
|
NoSQL Redis C++
Redis的实现五:二叉堆的数据结构和TTL、c,c++的实现
这篇文章详细探讨了二叉堆的数据结构及其在C和C++中的实现,特别强调了二叉堆在Redis中实现TTL(生存时间)功能的重要性,并通过代码示例展示了如何在Redis中使用二叉堆来管理键的过期时间。
41 0
|
存储 NoSQL 算法
「Redis」数据结构与对象
Redis数据结构与对象介绍
|
NoSQL 算法 Java
Redis进阶 - 数据结构:对象机制详解,一文深入底层分析
我们在前文已经阐述了Redis 5种基础数据类型详解,分别是字符串(string)、列表(list)、哈希(hash)、集合(set)、有序集合(zset),以及5.0版本中Redis Stream结构详解;那么这些基础类型的底层是如何实现的呢?Redis的每种对象其实都由对象结构(redisObject) 与 对应编码的数据结构组合而成, 本文主要介绍对象结构(redisObject) 部分。
Redis进阶 - 数据结构:对象机制详解,一文深入底层分析

热门文章

最新文章

下一篇
无影云桌面