底层:压缩列表ziplist、intset、紧凑列表listpack

底层:压缩列表ziplist、intset、紧凑列表listpack

ziplist和它的级联更新

当zset(sorted set)和hash在元素个数较少时会采用压缩列表ziplist存储。ziplist是一块连续的内存空间。

ziplist有一些属性:总字节数、最后一个元素距离起始偏移量、元素个数、entry列表、结束标志。其中偏移量是为了定位最后一个元素倒序遍历用的。

entry是ziplist的基本单位,entry有前一个entry的长度、类型编码、实际内容这三个属性。其中前一个entry的长度是为了倒序遍历时快速拿到前一个entry的起始位置,类型编码代表了内容的存储形式,字符串和整数大的时候小的时候都对应不同的编码形式以节省空间。

ziplist没有冗余空间,所以每次增加元素都会导致重新分配内存,可能在原有地址扩展也可能拷贝。

ziplist有一个很大的缺点就是级联更新,因为它的prelen(前一个entry的长度)采用的是动态变化的存储形式,短时采用1字节,长时采用5字节,如果一个entry的长度变了,那么它后面记录它长度的entry的prelen也会变化,可能带来内存的扩展,又重新导致entry的变化,可能导致多个entry级联更新。

intset

intset是set类型元素很少且都是整数时value的存储形式,它可以以16/32/64位存整数,这取决于它自己的类型编码,除了类型编码它还有元素个数、实际内容这两个属性。

listpack

listpack是对ziplist的改进,它比ziplist少了一个定位最后一个元素的属性(最后一个元素距离起始偏移量),listpack无需这个字段辅助逆序遍历。它的entry将长度字段放在了尾部,且记录的是本entry的长度,有了它就可以快速定位前一个entry的末尾,依然可以逆序遍历(在listpack定位到最后一个元素只需要总长度减去最后一个entry的长度即可)。这样本entry的属性不会出现在其他entry中了,消除了级联更新。但listpack目前只用在stream中。

猜你喜欢

转载自www.cnblogs.com/shizhuoping/p/11521385.html