1. 引言
Redis作为一个内存数据库,其内存管理和持久化机制直接影响性能和数据可靠性。Redis通过自定义内存分配器优化内存使用,同时提供RDB和AOF两种持久化方式保证数据不丢失。本篇将深入剖析Redis的内存管理(zmalloc.c
)以及RDB(rdb.c
)和AOF(aof.c
)的实现细节。
2. 内存管理
2.1 Redis的内存分配器
Redis默认使用jemalloc
(可在deps/
中找到),也支持tcmalloc
或标准libc
。自定义封装在zmalloc.c
中。
代码片段(zmalloc.h
):
void *zmalloc(size_t size);
void *zrealloc(void *ptr, size_t size);
void zfree(void *ptr);
size_t zmalloc_size(void *ptr);
硬核解析:
zmalloc()
:调用jemalloc
分配内存,记录使用量。zmalloc_size()
:返回实际分配块大小,用于内存统计。- 优势:减少碎片,提升分配效率。
代码片段(zmalloc.c
):
void *zmalloc(size_t size) {
void *ptr = je_malloc(size + PREFIX_SIZE);
if (!ptr) zmalloc_oom_handler(size);
*((size_t*)ptr) = size; // 记录大小
update_zmalloc_stat_alloc(size + PREFIX_SIZE);
return (char*)ptr + PREFIX_SIZE;
}
硬核解析:
PREFIX_SIZE
:额外空间存储元数据(通常8字节)。update_zmalloc_stat_alloc()
:更新全局内存统计。
3. 持久化机制
Redis提供两种持久化方式:RDB(快照)和AOF(日志)。
3.1 RDB持久化(rdb.c
)
RDB通过生成内存数据的快照保存到磁盘。
代码片段(rdbSave()
):
int rdbSave(char *filename, rdbSaveInfo *rsi) {
rio rdb;
rioInitWithFile(&rdb, fopen(filename, "w"));
rdbSaveRio(&rdb, rsi);
return C_OK;
}
硬核解析:
rio
:Redis的I/O抽象层,支持缓冲写。- 格式:RDB文件包含版本号、数据库键值对和校验和。
后台保存(rdbSaveBackground()
):
int rdbSaveBackground(char *filename, rdbSaveInfo *rsi) {
pid_t childpid = fork();
if (childpid == 0) {
rdbSave(filename, rsi);
exit(0);
}
return C_OK;
}
硬核解析:
- fork():创建子进程,避免阻塞主线程。
- COW(Copy-On-Write):子进程共享内存,快照时仅复制修改页面。
Mermaid RDB流程: