Redis 是 内存数据库,但是它也能够将存储的数据保存在硬盘上,这是由于它的持久化机制。
Redis 官方提供了两种不同的持久化方法来将数据存储到硬盘里面分别是:
这种方式可以将某一时刻的所有数据都写入硬盘中,这也是Redis 的默认开启持久化方式,保存的文件是以 .rdb
形式结尾的文件,因此这种方式也称之为 RDB方式。
快照生成方式:
BGSAVE
和 SAVE
指令SHUTDOWN
自动触发客户端可以使用 BGSAVE
命令来创建一个快照,当接收到客户端的 BGSAVE
命令时,Redis 会调用 fork
来创建一个子进程,然后子进程负责将快照写入磁盘中,而父进程则继续处理命令请求。
fork:当一个进程创建子进程的时候,底层的操作系统会创建该进程的一个副本,在类unix系统中创建子进程的操作会进行优化:在刚开始的时候,父子进程共享相同内存,直到父进程或子进程对内存进行了写之后,对被写入的内存的共享才会结束服务。
客户端还可以使用 SAVE
命令来创建一个快照,接收到 SAVE
命令的 Redis服务器在快照创建完毕之前将不再响应任何其他的命令;
注意:SAVE
命令并不常用,使用 SAVE
命令在快照创建完毕之前,Redis处于阻塞状态,无法对外服务。
如果用户在 redis.conf 中设置了 save 配置选项,Redis 会在 save 选项条件满足之后自动触发一次 BGSAVE
命令;如果设置多个 save 配置选项,当任意一个 save 配置选项条件满足,Redis 也会触发一次 BGSAVE
命令。
save 900 1 表示 900s 内,执行了 1次 数据库操作则自动创建快照,以此类推。
当 Redis 通过 SHUTDOWN
指令接收到关闭服务器的请求时,会执行一个 SAVE
命令,阻塞所有的客户端,不再执行客户端执行发送的任何命令,并且在 SAVE
命令执行完毕之后关闭服务器。
配置文件中可以修改生成快照名称以及快照保存位置:
# 生成快照名字, 默认为 dump.rdb
dbfilename dump.rdb
# 快照保存位置, 默认保存在 redis-cli 同级目录
dir ./
在 Redis 的默认配置中 AOF持久化机制是没有开启的,需要在配置中开启;
# 开启 AOF持久化
appendonly yes
# 生成的日志文件名称
appendfilename "appendonly.aof"
# aof日志文件路径与快照保存位置设置的是同一个
dir ./
# appendfsync always
appendfsync everysec
# appendfsync no
AOF的方式也同时带来了另一个问题:持久化文件会变的越来越大。
例如我们调用 incr test
命令 100 次,文件中必须保存全部的 100 条命令,其实有 99 条都是多余的,因为要恢复数据库的状态其实文件中保存一条 set test 100
就够了。为了压缩 AOF 的持久化文件,Redis 提供了 AOF重写(ReWriter)机制。
AOF 重写机制 在一定程度下减少 aof 文件的体积。
触发重写方式有两种:
执行 BGREWRITEAOF
命令,这种方式不会阻塞 redis 的服务;
配置 redis.conf 中的 auto-aof-rewrite-percentage 选项:
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
如果开启了 AOF持久化,以上配置代表:当AOF文件体积大于 64M,并且AOF文件的体积比上一次重写之后体积大了 100%(1倍) 时,自动触发重写。 如果重写过于频繁,可以考虑将 auto-aof-rewrite-percentage 设置的更大。
注意:重写 aof文件 的操作,并没有读取旧的 aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的 aof文件,替换原有的文件,这点和快照有点类似。
重写流程:
fork
,现在有父子两个进程,子进程根据内存中的数据库快照,往临时文件中写入重建数据库状态的命令;两种持久化方案既可以同时使用,又可以单独使用,在某种情况下也可以都不使用,具体使用那种持久化方案取决于用户的数据和应用决定。
无论使用 AOF 还是 快照机制持久化,将数据持久化到硬盘都是有必要的,除了持久化外,用户还应该对持久化的文件进行备份(最好备份在多个不同地方)。