Redis 的五种数据结构分析

Redis 本身是一个 Map,其中所有的数据都是采用 key:value 的形式存储

这里的数据类型主要是指存储的,也即是 value 的数据类型,key 的数据类型永远都是 String

redis 中 value 使用的数据结构有:

  1. String:字符串类型

  2. List:列表类型

  3. Hash:哈希表类型

  4. Set:无序集合类型

  5. sorted set:有序集合类型

下面我们来一个一个分别来了解一下:

一、String:字符串类型

redis 是使用 C 语言开发,但 C 中并没有 String 类型,只能使用指针或字符数组的形式表示一个字符串,所以 redis 设计了一种简单动态字符串(SDS[Simple Dynamic String])作为底层实现。

这个 SDS 的内部结构更像是一个 ArrayList,内部维护着一个字节数组,并且在其内部预分配了一定的空间,以减少内存的频繁分配。

Redis 的内存分配机制是这样:

当字符串的长度小于 1MB 时,每次扩容都是加倍现有的空间。

如果字符串长度超过 1MB 时,每次扩容时只会扩展 1MB 的空间。

这样既保证了内存空间够用,还不至于造成内存的浪费,字符串最大长度为 512MB。

​上图就是字符串的基本结构,其中 content 里面保存的是字符串内容,0x\0 作为结束字符不会被计算 len 中。

SDS 的数据结构:

capacity 和 len 两个属性都是泛型,为什么不直接用 int 类型?因为 Redis 内部有很多优化方案,为更合理的使用内存,不同长度的字符串采用不同的数据类型表示,且在创建字符串的时候 len 会和 capacity 一样大,不产生冗余的空间,所以 String 值可以是字符串、数字(整数、浮点数) 或者二进制。

redis 中 SDS 和 C 语言字符串对比:

1)C 语言中的字符串,遇到'\0'则结尾,用长度 N+1 的数组维护长度为 N 的字符串。

Redis 的 SDS 是:

len 表示字符串的长度;

free 表示空闲的,未分配的空间;

buffer 数组是真正的字符串,并且以'\0'结尾。

2)C 字符串并不记录自身的长度信息,获取一个 C 字符串的长度,必须遍历整个字符串,对遇到的字符进行计数,直到遇到代表字符串结尾的空字符为止,复杂度为 O(n)

SDS 在 len 属性中记录了 SDS 的本身长度,复杂度为 O(1)

3)C 字符串不记录自身长度容易造成缓冲区溢出

SDS 的空间分配策略完全杜绝了发生缓冲区的可能性:当 SDS API 需要对 SDS 进行修改时,API 会先检查 SDS 的空间是否满足修改所需的要求,如果不满足的话,API 会自动将 SDS 的空间扩展至执行修改所需的大小,然后才执行实际的修改操作,所以使用 SDS 既不需要修改 SDS 的空间大小,也不会出现前面所说的缓冲区溢出问题

4)减少修改字符串时带来的内存重分配次数

C 字符串的长度和底层数组的长度之间存在这种关联性,所以每次增长或者缩短一个 C 字符串,总要对保存 C 字符串的数组进行一次内存重分配操作

在 SDS 中,buf 数组的长度不一定就是字符数量加一,数组里面可以包含为使用的字节,而这些字节的数量就由 SDS 的 free 属性记录。通过未使用空间,SDS 实现了空间预分配和惰性空间释放两种优化策略

5)二级制安全

C 字符串必须符合某种编码,并且除了字符串的末尾之外,字符串里面不能包含空字符

SDS 的 API 都是二进制安全的,所有 SDS API 都会以处理二进制的方式来处理 SDS 存放在 buf 数组里的数据

6)C 兼容所有字符串函数

SDS 兼容部分 C 字符串函数

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Redis支持五种数据结构类型:字符串(string)、列表(list)、哈希(hash)、集合(sets)、有序集合(sorted sets)。它们可以用于实现缓存、消息队列、计数器、在线聊天室、投票系统、排行榜等应用场景。 ### 回答2: Redis支持多种数据结构类型,常用的有字符串、哈希、列表、集合和有序集合。 1. 字符串(strings):最基本的数据结构类型,可以存储字符串、整数或浮点数等。常用场景包括缓存、计数器和分布式锁等。 2. 哈希(hashes):类似于一个关联数组,可以存储多个字段和值的映射关系。适用于存储对象的各个属性,例如用户信息、商品详情等。 3. 列表(lists):支持在头部或尾部添加或删除元素,保持了元素的插入顺序。常用于消息队列、发布订阅系统和任务队列等场景。 4. 集合(sets):无序且唯一的元素集合。适用于需要对元素进行去重或集合操作的场景,例如标签云、社交关系等。 5. 有序集合(sorted sets):元素集合,每个元素都关联了一个分数,用于排序和获取范围内的元素。常见应用包括排行榜、热门文章等。 这些数据结构类型提供了丰富的功能和灵活性,可以根据不同的场景选择适合的数据结构Redis 的快速读写性能和丰富的数据类型使得它成为了很多应用场景的首选,包括缓存、计数器、消息队列、排行榜、实时数据分析等。 ### 回答3: Redis是一款开源的、高性能的非关系型内存数据库,支持多种数据结构类型。常用的Redis数据结构类型有字符串(String)、哈希(Hash)、列表(List)、集合(Set)和有序集合(Sorted Set)。 字符串类型是Redis最基本的数据结构类型,可以存储字符串和整数。它常用于缓存、计数器、共享会话等场景。 哈希类型可以存储多个字段和值的映射关系,类似于关联数组或字典。它适用于存储用户信息、商品信息等结构化的数据。 列表类型是有序的字符串列表,可以在列表的两端进行插入、删除和查找操作。它适合做消息队列、最新消息排行等场景。 集合类型是无序的字符串集合,可以对集合进行交集、并集和差集等操作,也支持添加、删除和查找元素。常用的场景包括社交关系、标签系统等。 有序集合类型是在集合类型的基础上,为每个元素关联一个分数,可以根据分数进行元素排序。它适用于排行榜、按照分数范围查找等场景。 除了以上几种数据结构类型,Redis还提供了位图、地理位置等特殊类型,可以应用于统计用户在线时长、地理位置检索等特定需求。 总而言之,Redis提供了多种数据结构类型,每种类型都有其独特的使用场景。根据具体的业务需求,选择适合的数据结构类型可以提升数据处理效率和灵活性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值