(转帖)大厂面试:Redis中的ziplist为什么会节省内存?能节省多少内存

发布时间:2024-11-06 17:29

最新推荐文章于 2024-04-21 19:45:44 发布

cleble 于 2022-02-20 17:22:23 发布

大家好,今天我们来聊一下在ziplist(压缩列表)中两个有趣的知识点。

先说两个结论:

ziplist使用紧凑的连续内存块顺序存储数据,在list或者hash结构中,未使用listNode(24字节)和dictEntry(24字节)结构体来存储元素项,因此会节省内存。ziplist结构元素访问采用的是后向遍历(从后往前),因此在hash中可将热点的key或者在list中将热点的元素项放在最后,可以提升性能。

ziplist存储结构

| zlbytes | zltail | zllen | entry1 | entry2 | ... | entryN | zlend |

zlbytes:占4字节,记录整个压缩列表长度。

zltail:占4字节,记录压缩列表表尾节点距离压缩列表的起始地址有多少字节,通过偏移量,可以确定表尾节点的地址,用于后向遍历。

zllen:占2字节,记录了压缩列表包含的元素数量。

entryN:列表节点,长度由节点内容决定。

zlend:1字节,用于标记压缩列表的末端。

在以上ziplist的内存结构中,仅仅只使用了额外的11个字节来存储ziplist的属性,另外很重要的是ziplist使用后向遍历,当list或者hash中的元素较多时,可以根据元素的冷热性调整元素存储顺序。

listNode、dictEntry

Redis中,未使用ziplist存储数据时,list的元素项以listNode结构体存储,hash以dictEntry结构体存储,下面我们用几行代码来测试一下在64位机器上这两个结构体的内存占用情况:

typedef struct dictEntry {

void *key;

union {

void *val;

int64_t u64;

int64_t s64;

} v;

struct dictEntry *next;

} dictEntry;

typedef struct listNode {

struct listNode *prev;

struct listNode *next;

void *value;

} listNode;

int main(){

printf("dictEntry size: %lu \n", sizeof(dictEntry));

printf("listNode size: %lu \n", sizeof(listNode));

return 0;

}

输出如下:

dictEntry size: 24

listNode size: 24

从输出来看,以上两个结构体都是占用24个字节的长度,在这24个字节中,元素的内容(上面结构体中的key、val)都是以指针声明形式存储在结构体中,也就是在结构体所占用的24字节中并未存储实际的元素内容。假设当你采用listNode来存储一个4字节的字符串时,你至少需要24+4=28字节的内存长度。而用ziplist的话,只需要6个字节就可以了

网址:(转帖)大厂面试:Redis中的ziplist为什么会节省内存?能节省多少内存 https://www.yuejiaxmz.com/news/view/11024

相关内容

如何有效压缩图片内存以节省存储空间
const可以节省空间,避免不必要的内存分配
节能减排意义和内容 节能减排措施有哪些?
有哪些存钱或省钱的小技巧?
华为云11.11终极攻略,Web及移动App上云省时省心更省钱
如何在 PostgreSQL 中实现数据的压缩存储以节省空间?
生活中使用冰箱时怎么才能节能省电 快来瞧瞧吧
生活中怎样才能节省开支?
求助 iCloud存照片不是能节省空间吗
月薪5000,两年存80000!百万年轻人在线交流省钱之道

随便看看