Skip to content

Redis持久化

Redis提供了两种持久化方法用于将数据存储到硬盘:快照(rdb)和只追加文件(aof)

这两种方法和可以同时使用,也可以单独使用。

快照

Redis可以通过创建快照(snapshotting)来获得存储在内存里面的数据在某个时间点上的副本。若在新的快照文件创建完毕之前,系统、redis或硬件中任意一个崩溃,那么Redis将会丢失最近一次创建快照之后写入的所有数据。

快照的持久化方式适合即使丢了一部分数据也不会造成问题的应用程序,redis中是默认开启的。

快照的创建方式

  • BGSAVE命令创建快照,Redis会调用fork来创建一个子进程,然后子进程负责将快照写入磁盘,而父进程负责继续处理命令请求。

    当一个线程创建子进程时,系统底层会创建该进程的一个副本。在unix系统中,刚开始时,父子进程共享相同的内存`,直到父或子进程对内存进行写入后,对被写入内存的共享才会结束

  • SAVE命令创建快照,Redis服务器接收到此请求后,在快照创建完成之前不会响应任何其他命令。该命令一般只在没有足够内存执行BGSAVE命令时才会使用。

  • SAVE 60 1000命令,从Redis最近一次创建快照之后算起,当60s内有1000次写入这个条件被满足,Redis会自动触发BGSAVE命令。任意一个SAVE ? ?命令满足时就会触发一次BGSAVE命令。

    假如我们能接受一个小时数据的丢失,可以使用SAVE 3600 1。即3600s内有一次写入就创建快照。

  • Redis接收到SHUTDOWN命令或TERM命令时,就会执行SAVE命令,阻塞所有客户端,不执行任何客户端发送的命令,并在SAVE命令执行完毕后关闭服务器。

  • 当一台Redis服务器连接另一台Redis服务器时,通过SYNC命令开始一次复制操作的时候,若主服务器没有正在执行或刚执行过BGSAVE命令,那么主服务器就会执行BGSAVE命令。

    配置作用
    save 60 100060s内有1000次写入就会触发BGSAVE命令
    stop-writes-on-bgsave-error noBGSAVE命令执行发生错误时是否停止写入
    rdbcompression yesredis通过快照存储数据至本地数据库是否压缩
    dbfilename dump.rdb快照存储的文件名

SAVE or BGSAVE

我们知道SAVE生成快照期间会阻塞所有的客户端命令,而BGSAVE通过创建子进程实现的快照生成会带来短暂的停顿,这种情况在Redis进程占用的内存越大的情况下越明显。一般来说Redis进程每多占用1GB内存,创建该进程的子进程的耗时就增加10-20ms

为了防止创建子进程而出现的停顿,我们可以考虑关闭自动保存,通过手动发送BGSAVE命令控制停顿出现的时间。虽然SAVE会一直阻塞Redis直到快照生成完毕,但因为SAVE不需要创建子进程,不会导致Redis停顿且没有子进程竞争,所以SAVE创建快照的速度会比BGSAVE创建快照的时候更短


只追加文件

AOF持久化会将被执行的写命令写到AOF文件的末尾,以此来记录数据发生的变化。只需要从头执行一次AOF文件包含的所有写命令,就可以恢复AOF文件所记录的数据集。

开启AOF

bash
appendonly yes # 开启AOF
appendfsync always/everysec/no

AOF模式是默认关闭的,需要手动开启

选项同步频率
always每个Redis写命令都要同步写入磁盘,会严重降低redis速度
everysec每秒执行一次同步,显式的将多个写命令同步到磁盘
no让系统决定何时来进行同步

AOF文件压缩/重写

AOF持久化不易丢失数据的优势下,存在着体积过大的问题。因为Redis不断将被执行的写命令记录到AOF文件中,随着Redis不断运行,AOF文件体积会越来越大。并且Redis重启后通过执行AOF文件还原数据集的时间也会随着体积的增大越来越长。

我们可以通过BGREWRITEAOF重写命令,该命令会移除AOF文件中冗余的命令来重写(Rewrite)AOF文件。该命令原理与BGSAVE类似,都是创建子进程,并由子进程进行重写(也会带来性能和内存占用问题)。

且我们可以通过auto-aof-rewrite-percentageauto-aof-rewrite-min-size来控制BGREWRITEAOF命令的触发时机。

auto-aof-rewrite-percentage 100; auto-aof-rewrite-min-size 64mb表明当AOF文件体积大于64MB且AOF文件体积比上一次重写的体积大了100%时,redis会执行BGREWRITEAOF命令。


主从复制

对于多台机器之间的数据同步可以通过复制实现:一台主服务器(master)处理写命令,并向多台从服务器(slave)发送更新,从服务器处理读请求

配置

默认情况下快照开启,当从服务器连接主服务器的时候,主服务器会自动执行BGSAVE命令,此时需要保证已经设置了如下参数:

bash

# 快照的文件名
dbfilename dump.rdb

# 文件默认存放到当前目录下
dir ./

也可以通过SLAVEOF ${host} ${port}命令手动开启复制。

复制流程

注意事项:

  1. 从服务器的旧数据会被全部清空。
  2. 需要保留部分内存作为缓冲区,存放写命令使用。

多台从服务器

  • 如果多台从服务器连接一台主服务器,那么所有的从服务器都会收到相同的快照文件和缓冲区写命令
  • 如果一台从服务器C连接时,恰好有一台从服务器B正在复制,那么会等B执行完上图步骤后再由C执行上图步骤。

验证工具

bash
# 验证/修复AOF文件
redis-check-aof [--fix] <file.aof>

# 验证快照文件
redis-check-dump <dump.rdb>

修复AOF文件会将错误或不完整的命令删除,只保留正确的命令。 目前出错的快照文件为u发删除(因为快照本身经过了压缩)。