Redis基础(数据结构和内部编码)
目录
前言
Redis的数据结构和内部编码
string结构和内部编码
string数据机构的特点
string数据结构的内部编码
list结构和内部编码
List 数据结构的特点
List 的内部编码
1. ziplist(压缩列表)
2. quicklist
hash结构和内部编码
hash数据结构的特点
hash数据结构的内部编码
1.ziplist 压缩列表
2. hashtable 哈希表
set结构和内部编码
set数据结构的特点
set数据结构和内部编码
1. intset(整数集合)
2. hashtable(哈希表)
zset结构和内部编码
zset数据结构的特点
zset数据结构和内部编码
总结
前言
这篇文章主要介绍了redis的基础使用,包括在服务器上安装redis,配置redis,以及一些使用的基础命令.
Redis入门https://blog.csdn.net/qq_63525426/article/details/134705665?spm=1001.2014.3001.5502接下来我们将继续介绍关于redis的更多知识以及使用.
Redis的数据结构和内部编码
在学习redis的数据结构和内部编码之前,我们先介绍一个命令.
type命令: type命令就是返回当前键的数据结构类型,redis中有5种数据结构,他们分别是string(字符串),list(列表),hash(哈希),set(集合),zset(有序集合).这些结构只是redis对外的数据结构.
上述的图片时redis提供给外部的数据结构,其实redis针对每种数据结构在内部都有自己的底层编码实现,而且是多种实现.这样做的目的就是来应对不同场景的需求.
可以看到每种数据结构都至少有两种以上的实现.比如list就有linkedList和ziplist两种内部编码.
同时有些内部编码,比如ziplist就作为多种数据结构的内部编码.
在redis中可以通过object encoding命令来查询内部编码.使用type来查询外部编码
可以看到我们设置的键的数据结构,hello键的结构是embstr,mylist的键是quickList
string结构和内部编码
string是redis中最基本的数据结构,也是使用最频繁的一个数据结构,不仅可以存储普通字符串,还可以存储二进制数据(序列化对象,图片)等数据,redis也是针对string在不同场景进行不同编码和优化.
string数据机构的特点
- 简单灵活 可以存储任意格式的数据,包括二进制数据,整数,浮点数等
- 最大长度 字符串最大长度可以达到512MB
- 高效 大多数string类型的操作时间复杂度为O(1).
string数据结构的内部编码
redis针对不同字符串的长度和类型,采用不同的内部编码来优化和节省内存,主要有三种编码方式.
- int(整数编码)
- embsrt(紧凑型字符串编码)
- raw(普通字符串编码)
当字符串被解析为64位有符号整数时,redis会将其以整数的形式存储,
当字符串的长度小于44字节时,redis会使用embstr编码,这种编码方式会将对象和实际字符串存储在同一块连续的内存中.降低了内存碎片和分配的开销.
当字符串长度超过44字节时,就会使用raw编码,这种方式将对象和实际字符串分开存储,适用于比较大的字符串.
list结构和内部编码
注意:quickList其实是ziplist和linkedList两种数据结构的结合,结构和这两种数据机构的优点,为列表类型提供了一种更优质的内部编码,而用户是感知不到的.也就是redis可以随时的改进自己的内部编码.而不用考虑外部编码.
多种不同的内部编码可以在不同场景下发挥各自的优势,例如ziplist比较节省内存,但是在列表元素变多的时候,性能就会下降,这时redis会根据配置选项进行切换,从而将列表类型的内部结构转换为linkedList.整个转换的过程用户是无感知的.
在 Redis 中,List(列表) 是一种有序的集合,支持在头部或尾部插入、删除元素,同时可以通过索引来访问元素。Redis 中的列表结构非常灵活,适合多种场景,如消息队列、任务调度等。
List 数据结构的特点
- 有序性:列表中的元素按插入顺序排序。
- 双向操作:可以从列表的头部或尾部进行操作。
- 高效:列表操作的时间复杂度通常是 O(1),特别适合大量数据的插入和删除操作。
List 的内部编码
Redis 中,List 有两种内部实现编码,Redis 会根据列表的长度及元素大小在两者之间进行切换:
- ziplist(压缩列表):当列表元素较少且每个元素都较小时使用。
- quicklist:用于存储较大的列表数据,这是 Redis 3.2 版本后引入的结构,用于替代之前的
linkedlist
。
1. ziplist(压缩列表)
- 简介:
ziplist
是一种内存紧凑的数据结构,专门用于存储小量数据,它将数据存储在一个连续的内存块中,减少了内存开销。 - 特性:
- 数据以连续的方式存储,节省了指针和额外的元数据占用的空间。
- 适合存储小型列表,避免内存碎片问题。
- 插入和删除操作的性能会随着列表的长度变大而下降,时间复杂度为 O(n)。
- 使用场景:当列表的长度小于配置参数
list-max-ziplist-entries
,默认512个 , 且列表中每个元素的大小小于list-max-ziplist-value
默认64字节 时,Redis 会使用 ziplist 作为编码方式。
2. quicklist
- 简介:
quicklist
是 Redis 3.2 之后引入的新的 List 实现方式,结合了压缩列表(ziplist)和双向链表(linkedlist)的优势。 - 结构:
quicklist
是由多个ziplist
片段通过双向链表连接起来的。- 每个
quicklist
节点是一个ziplist
,这种设计既保证了存储密度(通过ziplist
节省内存),又提升了操作效率(通过双向链表提供高效的插入和删除)。 quicklist
使得即使在处理较大的列表时,内存效率也更高。
- 优势:
- 插入、删除等操作仍然是 O(1) 的复杂度,因为操作可以发生在
ziplist
的头部或尾部。 - 避免了纯链表带来的内存碎片问题,降低了内存开销。
- 插入、删除等操作仍然是 O(1) 的复杂度,因为操作可以发生在
Redis 会根据列表的元素个数和元素的大小自动在
ziplist
和quicklist
之间切换:
- 当列表较小时,使用
ziplist
,以节省内存。- 当列表变大或其中有大元素时,自动切换为
quicklist
以提高操作效率。
Redis 中 List 的实现主要有两种编码方式:
- ziplist:用于存储小型列表,内存紧凑,但插入、删除操作效率较低。
- quicklist:结合了
ziplist
和linkedlist
的优势,适合存储较大的列表,且插入、删除操作效率高。
hash结构和内部编码
hash数据结构的特点
在 Redis 中,hash(哈希) 是一种用于存储键值对的集合。每个 Hash 本质上是一个键(key),这个键对应的是一个映射表(类似于一个小型的数据库)。Redis 的 Hash 适合用于存储对象的属性,比如可以用来存储用户信息,属性包括用户名、年龄、邮箱等。
hash数据结构的内部编码
redis为了提高内存使用率和性能,针对不同大小的hash和场景设置了两种不同内部编码.
1.ziplist 压缩列表
当hash中字段数量较少,每个字段的长度值较小时,redis使用ziplist作为底层实现, ziplist作为一种连续内存块的数据结构,存储元素紧凑并节省内存.适用于小型hash表,插入和查找的性能随着数据增加而下降,因为需要遍历整个ziplist.每个字段的值以顺序的方式存储(有序的).
当满足以下条件时,使用ziplist存储,反之使用Hashtable存储:
哈希表中每个元素的数量小于512(默认)
哈希表中每个字段的值和长度小于64字节(默认)
2. hashtable 哈希表
当 hash 中的字段数量或字段/值的大小超过一定阈值时,Redis 会切换到 hashtable
编码。这种编码方式是标准的哈希表实现,具有快速的查找、插入和删除性能
- 插入和查找的时间复杂度为 O(1),非常高效。
- 相较于
ziplist
,它消耗更多的内存,但性能更高,适用于大规模的哈希表。 - 使用条件:当哈希表不满足
ziplist
编码的条件时,Redis 自动切换为hashtable
编码。
set结构和内部编码
在 Redis 中,Set(集合) 是一种无序的集合数据结构,用于存储唯一的值。集合中的每个元素都是唯一的,且不允许重复。在 Redis 中,Set 是一种非常灵活且常用的数据类型,适合用于处理不需要重复值的场景,如标签系统、好友关系、共同爱好等。
set数据结构的特点
- 无序性:集合中的元素是无序的,不能通过索引来获取特定元素。
- 唯一性:集合中的所有元素都是唯一的,重复元素会自动去重。
- 高效的操作:集合支持常见的集合运算,如交集、并集和差集,并且这些操作的时间复杂度通常为 O(1) 或 O(N),其中 N 是集合的大小。
set数据结构和内部编码
Redis 中的 Set 使用两种不同的内部编码来优化性能和内存使用,这两种编码分别是:
- intset(整数集合)
- hashtable(哈希表)
1. intset(整数集合)
- 简介:当 Set 中的元素都是整数且数量较少时,Redis 使用
intset
编码。intset
是一种紧凑的结构,用于存储整数类型的集合。 - 特点:
- 节省内存:
intset
使用连续的内存块来存储整数,非常紧凑。 - 操作效率:由于
intset
是有序的,Redis 在插入、删除、查找时会进行二分查找,性能较好。
- 节省内存:
- 使用条件:如果 Set 中所有元素都是整数且集合的大小不超过一定阈值(默认 512 个),则 Redis 会使用
intset
编码。
2. hashtable(哈希表)
- 简介:当 Set 中的元素不是整数或元素数量超过一定阈值时,Redis 会切换到
hashtable
编码。hashtable
是常见的哈希表实现,用于存储任意类型的元素。 - 特点:
- 插入、删除、查找的时间复杂度为 O(1),非常高效。
- 相较于
intset
,hashtable
编码占用更多的内存。
- 使用条件:如果 Set 中包含非整数元素,或者元素的数量超过阈值(默认 512 个),则 Redis 会使用
hashtable
编码。
zset结构和内部编码
在 Redis 中,Zset(Sorted Set, 有序集合) 是一种带有排序的集合类型,类似于 Set 但每个元素都会关联一个分值(score)。Zset 中的元素仍然是唯一的,但元素会根据分值从小到大进行排序,允许进行快速的范围查找和排序操作。
应用场景:
- 排行榜系统:Zset 可以根据分值对元素进行排序,非常适合实现排行榜、积分榜、排名系统等场景。例如,游戏中可以使用 Zset 实现玩家的积分排名。
- 按时间排序的数据:可以使用 Zset 存储按时间戳排序的消息、事件、日志等,支持按时间范围快速查询。
- 优先队列:由于 Zset 提供了分值的排序功能,它可以实现优先级队列,按照任务的优先级进行调度。
zset数据结构的特点
- 元素唯一:Zset 中的每个元素(member)都是唯一的,但分值(score)可以重复。
- 有序性:Zset 中的元素按照分值进行排序,支持按分值或按元素的插入顺序进行操作。
- 分值可以重复:虽然 Zset 中的元素是唯一的,但不同元素可以有相同的分值。
- 支持范围查询:可以根据分值范围来获取集合中的元素,适合实现排行榜、排名等功能。
- 高效的插入、删除、查找:Zset 使用跳表(SkipList)实现,保证在 O(log N) 的时间复杂度下进行插入、删除、更新和范围查询操作。
zset数据结构和内部编码
当zset中数据较少时,使用ziplist存储,反之使用跳表存储(SkipList).
ziplist(压缩列表)
当有序集合的元素个数⼩于 zset-max-ziplist-entries 配置(默认 128 个), 同时每个元素的值都⼩于 zset-max-ziplist-value 配置(默认 64 字节)时,Redis 会⽤ ziplist 来作 为有序集合的内部实现,ziplist 可以有效减少内存的使.
跳表(SkipList)
- 简介:跳表是一种可以替代平衡树的有序数据结构,具有多层链表结构。通过为链表增加多级索引,跳表能够在 O(log N) 时间内进行插入、删除和查找操作。
- 作用:跳表用于按照分值顺序存储 Zset 中的元素,并支持范围查询、排序等操作。
- 优点:插入和删除的效率稳定,能够处理大量数据,且实现较为简单。
总结
这篇文章主要介绍了redis中外部的数据结构和内部数据结构的编码.
下篇将主要对这些数据结构进行操作以及操作命令讲解.