4K字详细解析Redis 底层数据结构 listpack

为什么需要 Listpack


  •  Ziplist 会出现 “连锁更新” 的现象,为了解决这个问题,Redis 引入了 QuickList,通过控制 QuicklistNode 结构里的压缩列表的大小或者元素个数,来减少连锁更新带来的性能影响。但是 QuickList 并没有完全解决连锁更新的问题。
  • 为了彻底避免连锁更新的出现,Redis 在 Redis 7 引入了 Listpack ,代替 ZipList 彻底解决连锁更新的问题。

Listpack 是怎么避免连锁更新的?


  • 我们知道,ZipList 会有连锁更新的问题,最根本的原因就是因为 prevlen 的存在,当 ZipList 新增某个元素或修改某个元素时,如果空间不不够,压缩列表占用的内存空间就需要重新分配。而当新插入的元素较大时,可能会导致后续元素的 prevlen 占用空间都发生变化,从而引起连锁更新问题。
  • 既然这样,prelen 是留不得了!那么,Listpack 的结构长什么样子的?没有了 prelen 它又怎么实现遍历操作呢?

Listpack 的底层结构

Listpack

我们先来看看 listpack 整体长什么样子,这里看到 lpNew**(size_t capacity) 这个函数

 

c

复制代码

/* Create a new, empty listpack. * On success the new listpack is returned, otherwise an error is returned. * Pre-allocate at least `capacity` bytes of memory, * over-allocated memory can be shrunk by `lpShrinkToFit`. * */ unsigned char *lpNew(size_t capacity) { unsigned char *lp = lp_malloc(capacity > LP_HDR_SIZE+1 ? capacity : LP_HDR_SIZE+1); if (lp == NULL) return NULL; lpSetTotalBytes(lp,LP_HDR_SIZE+1); lpSetNumElements(lp,0); lp[LP_HDR_SIZE] = LP_EOF; return lp; }

可以看到,这个函数的主要功能是创建一个新的 listpack,其中各个成员变量的值如下:

  • lpSetTotalBytes,用于保存 listpack 的总字节

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值