redis解析

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 操作。

Set

Redis为什么这么快(io多路复用)

Redis集群(哨兵模式)

你可能感兴趣的:(redis)