redis的底层数据结构
Redis 常用的底层数据结构包括:
- 字符串(SDS):简单动态字符串,用于存储字符串值。
- 链表:用于实现列表数据结构。
- 字典(哈希表):高效的键值对存储结构。
- 跳跃表:用于有序集合的实现。
- 整数集合:用于存储整数类型的集合。
- 压缩列表:节省内存的一种数据结构。
这些底层数据结构使得 Redis 能够高效地支持各种数据类型和操作。
什么是跳表
跳表是 Redis 中一种数据结构。它是在有序链表基础上增加多层索引的结构。通过建立多层索引,加快了查找、插入和删除操作的效率。
在查找时,通过在索引层跳跃式查找,快速缩小查找范围,从而降低时间复杂度,通常能达到 O(log n)的平均复杂度。
与平衡树等数据结构相比,跳表实现更简单,更易理解和实现。
什么是双向链表
双向链表是一种常见的数据结构。它由一系列节点组成,每个节点包含数据和两个指针,分别指向链表中的前一个节点和后一个节点。这样使得链表的遍历既可以向前也可以向后,相比单向链表,在某些操作(如删除节点)时更加方便和高效。
什么是 ziplist 压缩列表及怎么实现
ziplist(压缩列表)是 Redis 为了节约内存而开发的一种特殊编码的双向链表数据结构,它由一系列特殊编码的连续内存块组成。ziplist 可以包含任意多个节点,每个节点可以保存一个字节数组或整数值。
在实现上,ziplist 通过记录前一个节点的长度和当前节点的编码方式及数据内容,来实现节点之间的关联。它具有内存占用低、读写效率高等优点,适用于存储长度较小的值。
同时,需要注意 ziplist 可能存在连锁更新问题,即在特定情况下,插入或删除节点可能导致后续节点的长度更新,从而影响性能。为了避免这种情况,Redis 对 ziplist 的长度和元素数量进行了限制,并提供了相应的配置选项。
什么是SDS简单动态字符
SDS 是 Redis 中的一种字符串类型,它是一种二进制安全的字符串,由简单动态字符串(SDS)实现。相比于 C 语言中的字符串,SDS 具有以下优点:
- 动态扩容:SDS 可以动态增加内存空间,避免了静态数组的大小限制。
- 常数复杂度获取字符串长度:SDS 中的 len 属性表示字符串长度,可以在常数时间内获取字符串长度。
- 杜绝缓冲区溢出:SDS 会检查内存是否足够,避免了缓冲区溢出的问题。
- 减少修改字符串的内存重新分配次数:SDS 采用惰性空间释放和空间预分配的策略,可以减少修改字符串的内存重新分配次数。
- 二进制安全:SDS 不以空字符串来判断字符串是否结束,而是以 len 属性表示的长度来判断字符串是否结束,所以支持存储任何二进制数据。
- 兼容部分 C 字符串函数:SDS 可以重用 C 语言库中的一部分函数。
整数数组和压缩列表在查找时间复杂度方面并没有很大的优势,那为什么 Redis还会把它们作为底层数据结构呢?
Redis 使用整数数组和压缩列表作为底层数据结构,尽管在查找时间复杂度上优势不大,但它们在内存占用和序列化方面有显著优点。
整数数组能紧凑存储整数,节省内存空间,适用于元素数量固定且较少的场景。
压缩列表能有效减少内存碎片,对于短且连续的小数据元素集合,能降低内存开销。
而且在一些特定场景,如元素更新不频繁、数据规模较小,它们的性能足以满足需求,同时能更好地优化内存使用,提高系统的整体性能和资源利用率。
Redis过期删除策略
Redis 有以下过期删除策略:
- 定时删除:在设置键的过期时间时,创建一个定时器,当过期时间到达时,立即删除该键。这种方式能保证内存被及时释放,但会耗费较多的 CPU 资源。
- 惰性删除:在获取键时,检查键是否过期,如果过期则删除。优点是节省 CPU 资源,但可能导致内存无法及时释放。
- 定期删除:Redis 每隔一段时间,随机抽取一定数量的设置了过期时间的键,检查并删除其中的过期键。是定时删除和惰性删除的一种平衡策略。
综合使用这三种策略,以达到在合理利用资源的情况下&#x