Redis底层数据结构

String

redis是基于c语言开发的,但是它并没有沿用c语言的数据结构,而是使用了SDS简单动态字符串(simple dynamic string)这种数据结构

redis 3.2 以前

/*  
 * 保存字符串对象的结构  
 */  
struct sdshdr {  
      
    // buf 中已占用空间的长度  
    int len;  
  
    // buf 中剩余可用空间的长度  
    int free;  
  
    // 数据空间  
    char buf[];  
}; 

在c中对字符串的定义是这样的

char data[]="test\0"

但是在redis中需要适配不通的语言java ,go.php等

在redis中的数据结构是这样的

sds:

free=0

len=4

char data[]="test"

redis中空间换时间

如果把test修改为 test123 redis会自动扩容

(原lengs 4+需要扩容的lengs 2)x 2=12

即变为

sds:

free=12

len=6

char data[]="test123"

用掉2个lengs变为

sds:

free=10

len=6

char data[]="test123"

这种方法可以有效地减少内粗的分配

兼容c语言的函数库

二进制安全

redis是k-v的数据结构,底层使用数据和链表进行数据划分,类似于java中hashmap的实现

默认创建arr[4]的数组来存放数据

假如有三组数据

(k1,v1) (k2,v2) (k3,v3)

通过hash算法运算计算出数组下标位置

假设数据

hash(k1)% 4 = 0

hash(k2)%4 =1

hash(k3)%4 = 1

arr[0]->(k1,v1,next->nul1) 链表指向null

产生hash冲突

arr[1]->(k3,v3,next ->k2 )(k2,v2,next ->null) 链表指向next节点.

redisDB

redis默认15个db 数据库

底层c语言数据结构

dict是redis中的hashtable

dict中的数据结构

dictType 类型 

 hashFunction指定hash的key名称

keyCompare指定hash比较 有可能产生hash冲突

dictht

如果size=used 会进行数组扩容 如arr[4] 变为 arr[8]

 其实就是hashtable的数据结构 有两个[0][1]

arr现长度为4 如果扩容到很大的一个长度 数组结构是需要重新创建一个新的数组 再把原先的数据复制进去,这个过程如果跨度很大的话是很消耗性能的

所以redis定义了一个渐进式的rehash 

每次访问的时候搬过来一点数据 

如果一直没访问的话,redis内部也会有任务去执行 一点点的把数据全部搬过来

在访问的时候如果数据还没完全搬完 会先去[0]中查找 再去[1]中查找

size hashtable的容量

sizemask 实际长度

dictEntry table

 

key就是sds对象

next 是链表结构的指针

 val 是指向的类型 如String list hash set 

类型封装成了object

 type 约束redis命令 如set get 不能超出规则范围

refcount redis中没有垃圾收集器 需要知道对象的有效个数 

ptr 对象类型的真正指向

指向图

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值