redis 面试
数据结构(数据类型和数据结构:sds,zipList,quickList,skipList)
String
String:String 是 redis 最根本的类型, 一个 key 对应一个 value。redis 的 string 类型能够蕴含任何数据,比方 jpg 图片或者序列化的对象。string 类型的值最大能存储 512M。
String 底层采纳了 SDS 设计。
SDS 结构设计:
len:SDS 所保留的字符串长度。
alloc:调配给字符数组的空间长度。批改字符串的时候,能够通过 alloc – len 计算 察看是否须要对空间扩容。
flags:数据类型。
buf[]:保留理论数据。
SDS 理论益处:
1、SDS 保留了数据长度,所以工夫复杂度就是 O(1)。
2、空间预调配:SDS 被批改后,程序不仅会为 SDS 调配所须要的必须空间,还会调配额定的未应用空间。
3、惰性空间开释:当数据进行缩短操作,多余空间不会被回收,前面须要增长时,就不必额定去拓展空间。
List
List: 是一个链表。一个 key 对应一个链表。先入先出,能够通过索引查问,不便新增和删除。
List 底层数据结构又两种:
ZipList(压缩表):列表对象保留的所有字符串元素的长度都小于 64 字节并且保留的元素数量小于 512 个。
QuickList(疾速表):应用 quicklist,它是一个双向链表,而且是一个基于 ziplist 的双向链表,quicklist 的每个节点都是一个 ziplist。
ZipList 数据结构:
zlbytes,记录整个压缩列表占用对内存字节数;
zltail,记录压缩列表「尾部」节点间隔起始地址由多少字节,也就是列表尾的偏移量;
zllen,记录压缩列表蕴含的节点数量;
zlend,标记压缩列表的完结点,非凡值 OxFF(十进制 255)。
Entry 节点形成:
prevlen,记录了前一个节点的长度;
encoding,记录了以后节点理论数据的类型以及长度;
data,记录了以后节点的理论数据;
压缩表长处:将长度较短的数据用压缩链表,可能时内存更紧凑,节约内存。
为什么数据量较大和数据长度较长不适宜应用 ZipList?
压缩表每个 Entry 的 prevlen 都记录了上一个节点的长度。
如果前一个节点的长度小于 254 字节,那么 prevlen 属性须要用 1 字节的空间来保留这个长度值;
如果前一个节点的长度大于等于 254 字节,那么 prevlen 属性须要用 5 字节的空间来保留这个长度值;
假如呈现了间断多个节点长度在 250~253 字节的数据,忽然新增了也该字节长度超过了 254 数据,会导致后续节点的 prevlen 都
从原来的 1 个字节拓展到 4 个字节,该节点就须要拓展空间。而后又导致了该节点的后续节点的 prevlen 长度变更 …… 而后始终继续上来,这种就叫连锁更新。
quickList 长处:
quicklist 是 ziplist 和 linkedlist 的混合体,它将 linkedlist 按段切分,每一段应用 ziplist 来紧凑存储,多个 ziplist 之间应用双向指针串接起来。
对于 quickList 曾经将 ZipList 分成了很多小片区,在小片区内产生连锁更新也是能够承受的。
Hash
相似 Java 的 HashMap,数组 + 链表。
1:当 Hash 抵触时将具备雷同哈希值的数据链接起来,以便这些数据在表中依然能够被查问到。
2:当 Hash 抵触过多,导致数据链表太长就会产生 rehash.
渐进式 Rehash:
为了防止 rehash 在数据迁徙过程中,因拷贝数据的耗时,影响 Redis 性能的状况,所以 Redis 采纳了渐进式 rehash,也就是将数据的迁徙的工作不再是一次性迁徙实现,而是分屡次迁徙。
渐进式 rehash 步骤如下:
给「哈希表 2」调配空间;
在 rehash 进行期间,每次哈希表元素进行新增、删除、查找或者更新操作时,Redis 除了会执行对应的操作之外,还会程序将「哈希表 1」中索引地位上的所有 key-value 迁徙到「哈希表 2」上;
随着解决客户端发动的哈希表操作申请数量越多,最终会把「哈希表 1」的所有 key-value 迁徙到「哈希表 2」,从而实现 rehash 操作。
rehash 触发条件:
负载因子 = 保留节点数 / 哈希表大小
当负载因子大于等于 1,并且 Redis 没有在执行 bgsave 命令或者 bgrewiteaof 命令,也就是没有执行 RDB 快照或没有进行 AOF 重写的时候,就会进行 rehash 操作。
当负载因子大于等于 5 时,此时阐明哈希抵触十分重大了,不论有没有有在执行 RDB 快照或 AOF 重写,都会强制进行 rehash 操作。