Redis 在生成 RDB 文件时如何处理请求?

Sherwin.Wei Lv7

Redis 在生成 RDB 文件时如何处理请求?

回答重点

在 Redis 生成 RDB 文件时是异步的(使用 bgsave 命令),采用了 fork 子进程的方式来进行快照操作。生成 RDB 文件的过程由子进程执行,主进程继续处理客户端请求,所以可以保证 Redis 在生成快照的过程中依然对外提供服务,不会影响正常请求。

扩展知识

生成 RDB 文件的时候,数据可以修改吗?

当然可以。主进程会正常处理客户端的请求,进行数据的修改。但数据被修改还叫快照吗?

此时就运用了写时复制的技术。

当主进程 fork 出一个子进程后,并不会把主进程的所有内存数据重新复制一份给子进程,而是让主进程和子进程共享相同的内存页面。

底层的实现仅仅复制了页表,但映射的物理内存还是同一个。这样做可以加快 fork 的速度,减少性能损耗(fork会阻塞主进程)。

image.png

此时,主进程收到写命令,需要修改数据,那么主进程会将对应数据所在的页复制一份,对复制的副本进行修改。此时子进程指向的还是老的页,因此数据没有变化,符合快照的概念。

image.png

通过在写的时候才触发内存的复制,可以显著地降低 Redis 实例的性能压力,最大限度的减少 RDB 对服务正常运行的影响。

避免高峰期生成 RDB

如果 RDB 时间长,且写并发高,此时会被系统产生比较大的影响。

原因是因为写时复制时,如果共享的每一页内存都被修改,就会使得内存极速膨胀,最大内存可以膨胀两倍,所以要注意内存的使用量,防止内存过载。

RDB 会产生大量的磁盘 I/O,要注意磁盘性能导致的影响。

还需要注意 CPU 负载,毕竟有大量的数据需要写入。

因此如果 RDB 在高峰期可能会影响到正常业务,需要合理安排生成 RDB 的时机。

Comments