Redis 速度快的原因

Redis作为内存数据库,其高速性能源于基于内存实现、高效数据结构如SDS、双端链表和字典,以及合理的数据编码策略。采用I/O多路复用模型避免上下文切换,单线程模型保证高并发处理。Redis中embstr和raw编码的界限在不同版本中有变化,影响内存管理效率。
摘要由CSDN通过智能技术生成

基于内存实现

由于是存储在内存中的数据库, 不会被磁盘 IO 影响到数据读写的效率, 也就是说减少了磁盘 IO 的开销

高效的数据结构

SDS

1. 字符串长度处理

存储了 len 这个字段以快速获取长度

2. 内存重新分配

  • 空间预分配

    分配必须的空间之外, 还会额外分配未使用空间

    len < 1M, 额外分配 len 长度的空间

    len > 1M, 额外分配 1M 长度的空间

  • 惰性空间释放

    使用完毕的空间, 不会直接进行回收, 而是使用 free 字段将多余的空间存储下来, 后续使用空间可以先从 free 中获取, 减少内存分配

3. 不需要处理二进制安全 ‘\0’

根据 len 来判断 字符串 结束, 不需要额外的处理来判断字符串结束

双端链表

1. 前后节点

listNode 中存储 prev 和 next 加快获取前后节点的速度

2. 头尾节点

list 中存储 head 和 tail 方便正序或者逆序遍历链表

同时双端节点的处理时间降至 O(1)

3. 链表长度

同 SDS 的 len, O(1) 获取长度

压缩列表

优化链表存储时, 每次都需要存储是都需要保存一些重复的信息, 如头节点, 前后节点, 这样会浪费空间, 反复申请释放也容易导致内存碎片化

而压缩列表操作是通过指针与解码出的偏移量进行的, 效率更高

同时内存是连续分布的, 遍历速度快

字典

哈希表原理, O(1)时间查找和插入

跳表

多级索引加快效率

合理的数据编码

image-20220525205234235

embstr 和 raw 的区别

embstr: 保存比较短的字符串, 只需要申请一次内存分配函数, 因为在创建 RedisObject 和 sdshdr 时是直接一起创建的连续内存, 释放一次内存

raw: 保存比较长的字符串, 使用时需要为 RedisObject 和 sdshdr 都申请一次内存分配函数, 需要释放两次内存

Redis 中 embstr 和 raw 编码的界限

1. 结论

在 redis 4.0 之前, 代码创建的逻辑是与REDIS_ENCODING_EMBSTR_SIZE_LIMIT = 39 进行比较,如果小于 39 的话创建的是 embstr ,否则为 raw

但在 5.0 中 修改成了当小于 44 个字节的时候使用 embstr,大于 44 的时候为 raw

2. 原因创建 stringObject 的逻辑

redisObject, 需要占据 16 个字节

typedef struct redisObject {
   
    unsigned type:4;	  //对象类型(4位=0.5字节)
    unsigned encoding:4;  //编码(4位=0.5字节)
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值