Redis数据结构 — Listpack

目录

listpack 结构

listpack 节点结构


quicklist 虽然通过控制 quicklistNode 结构里的压缩列表的大小或者元素个数,来减少连锁更新带来的性能影响,但是并没有完全解决连锁更新的问题。

于是,Redis 在 5.0 新设计一个数据结构叫 listpack,目的是替代压缩列表,它最大特点是 listpack 中每个节点不再包含前一个节点的长度,而是记录当前节点的长度。

Listpack源码icon-default.png?t=N6B9https://github.com/redis/redis/blob/unstable/src/listpack.clistpack 结构

listpack 头包含两个属性,分别记录了 listpack 总字节数和元素数量,然后 listpack 末尾也有个结尾标识。图中的 listpack entry 就是 listpack 的节点了,相对于ZipList没有记录,距离尾节点的偏移量,Listpack节省了这部分内存空间

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 节点结构

Redis数据结构 — Listpack_第1张图片

 listpack entry主要包含三个方面内容:

  • encoding,定义该元素的编码类型,会对不同长度的整数和字符串进行编码;
  • data,实际存放的数据;
  • len,encoding+data的总长度;

可以看到,listpack 没有压缩列表中记录前一个节点长度的字段了,listpack 只记录当前节点的长度,当我们向 listpack 加入一个新元素的时候,不会影响其他节点的长度字段的变化,从而避免了压缩列表的连锁更新问题

listpackEntry中的改进 :
不同于ziplist,listpackEntry中的len记录的是当前entry的长度,而非上一个entry的长度。listpackEntry中可存储的为字符串或整型。

  • 当存储的为字符串,那么lsentry的sval不为空,slen记录大小。
  • 当存储的为整型,那么lval记录整型,sval字段为空

你可能感兴趣的:(Redis,redis,数据结构,数据库)