Redis 版本:7.0.15
1.概述
Redis 是一个基于内存的数据库,这意味着其主要数据存储和操作均在内存中进行。这种设计使得 Redis 能够提供极快的读写速度(通常达到微秒级别),适用于高性能场景,如缓存。
然而,由于内存的易失性(断电后数据会丢失),Redis 提供了持久化机制:将内存中的数据保存到磁盘中,确保数据在 Redis 服务重启或崩溃后能够恢复。通过持久化,可以避免数据丢失,提高数据的可靠性。
Redis 提供两种持久化方式:
- RDB (Redis Database):生成数据集的快照实现持久化
- AOF (Append Only File):记录所有写操作命令,以追加方式写入文件
2.RDB
RDB 指的是 Redis 的一种持久化机制,其核心是生成 Redis 数据在某个时间点的快照。
2.1 快照原理
由于 Redis 是单线程应用程序,在线上环境时,不仅要处理来自客户端的请求,还要执行内存快照操作(进行文件 IO)。单线程同时处理客户端请求和文件 IO 时会严重降低服务器性能,甚至阻塞客户端请求。因此,Redis 使用 fork 和写实拷贝(Copy On Write)机制来实现快照持久化。
![图片]
fork
Redis 在进行 RDB 持久化时会调用 fork 函数来创建一个子进程负责完成,父进程则继续处理客户端请求。子进程在创建之初和父进程共享同一数据段。
Linux 操作系统的内存空间被分为很多种片段,每个片段又被分为很多个页面,每个页面 4KB。
![图片]
写实拷贝
当父进程对数据段中的某一数据页面进行修改操作时,Linux 操作系统会将该数据页面复制一份分离出来,然后对该页面进行修改,最后父进程指向修改后的页面。随着被修改的页面越来越多,内存空间不断膨胀,最多达到原来的两倍。
![图片]
从子进程被创建出来的那一刻起,直至拷贝结束,子进程始终指向原始的数据段且所有原数据段不会被修改。所以,在整个拷贝过程中 RDB 快照 = 子进程看到的所有数据页面的瞬间状态集合。
拷贝完成后,子进程会被销毁,同时没有指针指向的数据页面也会被销毁。
![图片]
2.2 触发机制
Redis RDB 的触发机制分为自动触发和手动触发两种方式。
- 自动触发:在 redis.conf 中通过 save 指令配置阈值。当在指定时间内发生足够数量的键修改时自动触发 bgsave。
- 手动触发:
- save 命令:同步阻塞式触发,执行期间 Redis 服务器不处理任何请求,直到 RDB 文件创建完成(不推荐)。
- bgsave 命令:异步非阻塞式触发,Redis 会 fork 一个子进程执行持久化操作,主进程继续处理请求。
正常关闭 Redis:
# 默认执行 save(阻塞式)
shutdown
# 或
shutdown save # 触发流程:1. 停止接受新连接 2. 执行 save(不是 bgsave) 3. 保存完成后退出
2.3 文件处理
RDB 文件保存在 dir 配置指定的目录下(默认/var/lib/redis),文件名通过 dbfilename 配置指定(默认 dump.rdb)。
![图片]
在 RDB 备份过程中,fork 出的子进程会将内存数据写入临时文件,临时文件默认命名规则为 temp-< pid >.rdb,其中 < pid > 是子进程的进程 ID。当子进程完成 RDB 文件写入后,Redis 会用原子性的 rename 操作将临时文件重命名为正式 RDB 文件并删除原文件。
![图片]
2.4 优缺点
优点
- 恢复速度快:RDB 是数据的二进制快照,恢复时直接加载到内存。


