Redis学习笔记数据结构(一)

Redis学习笔记数据结构(一)

一、简单动态字符串(simple dynammic string 简称SDS)
redis字符串值的键值对、AOF缓冲区、客户端状态输入缓存区在底层都是由SDS实现的。
1、SDS结构:char字节数组 (buf[]) 、数组中已使用字节数量等于SDS所保存字符串的长度 (len) 、及数组中未使用字节的数量(free)
由于SDS重用了C字符串函数库,故遵循了C字符串以空字符结尾的惯例,空字符串所占的这一字节空间不计算在SDS的len属性当中。实际上buf[]空间分配大小可以等于 len+free+空字符串。
2、SDS内存重分配
空间预分配:用于优化SDS字符串增长操作,在分配增长所需要的空间外会额外分配未使用空间。实际空间大小通常取决于修改之后的len属性,当修改后的len属性值小于1MB时,程序会额外分配len相同的未使用字节空间,这时free属性值与len属性值相同。当修改后len属性值大于1MB时,程序会分配1MB未使用空间,则free属性值为1MB。redis通过使用空间预分配策略减少连续字符串增长操作所需的内存重分配次数。
惰性空间释放:用于优化SDS字符串缩短操作,在需要缩短SDS字符串时,程序不会立即回收多余空间,而是将多余空间记录到free属性中,SDS提供了相应API用以真正释放未使用空间,以免惰性空间释放造成的内存浪费。
3、SDS二进制安全:
redis使用二进制的方式处理SDS保存在buf[]中的数据,不会在处理过程中做任何修改。
二、链表
redis内置了自己的链表实现,列表键、发布订阅、慢查询、监视器都有用到。
1、链表结构:链表与链表节点。
链表节点保存了前置节点指针、后置节点指针、当前节点值。通过前置节点与后置节点构成双端无环链表。
链表由表头节点指针、表尾节点指针、节点数量、节点值复制函数、节点值释放函数、节点值比较函数构成。

三、字典
redis构建了自己的字典实现,redis数据库和哈希键底层就由字典实现。
1、字典结构:哈希表数组、类型特定函数、私有数据、rehash索引。
哈希表数组存在两个哈希表,一般只使用第一个hash表ht[0],第二个ht[1]只会在对第一个hash表进行rehash时使用。普通状态下(未进行rehash时)rehash索引值为-1。
哈希表结构:哈希表数组(指向哈希表节点的指针)、哈希表大小、哈希表大小掩码、已有哈希节点数量。
哈希表节点结构:键、值、指向下哈希表节点指针。
当新的键值对添加到字典中时,程序根据键值对的键通过MurmurHash2算法计算出哈希值和索引,然后根据索引将新的键值对放到哈希表数组的指定索引上面。
当两个或以上的键分配到同一个索引上面时,哈希表使用链地址法来解决键冲突,通过哈希表节点的下节点指针构成一个单向链表,将新节点添加到链表表头位置。
2、rehash重新散列
当需要重新散列时,首先会为第二个哈希表ht[1]进行空间分配,如果执行的是扩展操作那么ht[1]哈希表大小将是第一个大于等于ht[0]哈希表的已有哈希节点数量属性*2的2的n次方幂(有点绕),如果执行的是收缩操作,那么ht[1]哈希表大小为第一个大于等于ht[0]哈希表的已有哈希节点数量属性的2的n次方幂。
第二步,将保存在ht[0]中所有键值采用渐进式rehash到ht[1],rehash将从新计算hash值和索引
第三步,释放ht[0],将ht[1]设置为ht[0],并在新的ht[1]创建空白hash表为下一次rehash做准备。
3、哈希表的扩展与收缩
当满足下面条件时程序会自动对哈希表进行扩展操作
1)负载因子大于等于1,并且服务器当前未在执行bgsave或者bgrewriteaof操作。
2)服务器当前正在执行bgsave或者bgrewriteaof操作并且负载因子大于等于5.。

四、跳跃表
redis有序集合键,集群环境中使用了跳跃表作为底层实现
1、跳跃表结构:表头节点指针、表尾节点指针、最高层节点层数(不包括表头节点)、跳跃表节点数量(不包括表头节点)
跳跃表节点结构:层(包含前进指针与跨度)、后退指针、分值、成员对象,各节点按分值从小到大排序。

五、整数集合
当集合中只包含整形数值元素并且数量不多的情况下会采用整形集合作为集合键的底层实现。
1、整数集合结构:编码方式、元素数量、保存元素的数组。
底层数组中元素按值从小到大排序,不包含重复项,数组中的元素类型由编码方式决定,当有新元素新增到数组中时,程序会根据新元素的类型长度来决定是否需要进行升级,当类型长度大于现有编码长度时将会对数组中的所有元素进行升级操作,并保持数组的有序性,随后相应改变整数集合结构中的编码方式。当类型长度小于现有编码长度时会将新元素类型转为当期编码类型,原数组中类型不变。

六、压缩列表
列表键与哈希键的底层实现之一,由一系列特殊编码的连续内存块组成、当列表项属于小整数值或者长度较短字符串并且列表项较少时采用压缩列表。
压缩列表结构:占用内存字节数、表尾节点距离起始地址的字节数、包含的节点数量、保存的节点(连续保存所有节点),特殊值0xFF(表示压缩节点末端)
压缩列表节点结构:前一节点的长度、节点值数据类型与长度、节点值。

总结:实际上redis底层数据结构中除了跳跃表与压缩列表外,其他的都比较好理解,都是一些常规数据类型再经过特殊处理和优化。个人感觉大概了解一下就可以了,没必要深入理解!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值