Redis 的持久化
1. Redis 的持久化
Redis 是内存数据库,它把数据存储在内存中,这样在加快读取速度的同时也对数据安全性产生了新的问题,即当 Redis 所在服务器发生宕机后,Redis 数据库里的所有数据将会全部丢失。为了解决这个问题,Redis 提供了持久化功能 RDB(Redis DataBase)
和 AOF(Append Only File)
。
Redis 有两种持久化策略
RDB 策略
AOF 策略
1.1. RDB 策略
RDB(Redis DataBase)
是 Redis 默认的持久化方案。就是在指定时间间隔内,Redis 服务已执行了指定次数的写操作后,就会自动触发一次持久化操作,将内存中的数据快照保存到磁盘上。快照文件是一个二进制文件,包含了 Redis 在某个时间点上的所有数据。即在指定目录下生成一个 dump.rdb
文件。Redis 重启会通过加载 dump.rdb
文件来恢复数据。
1.1.1. RDB 原理
Redis 会复制一个与当前进程一样的进程。新进程的所有数据(变量、环境变量、程序计数器等)数值都和原进程一致,但是是一个全新的进程,并作为原进程的子进程,来进行持久化。
整个过程中,主进程是不进行任何 IO
操作的,这就确保了极高的性能。
如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那 RDB
方式要比 AOF
方式更加的高效。RDB
的缺点是最后一次持久化后的数据可能丢失。
1.1.2. RDB 保存的文件
RDB
保存的文件是 dump.rdb
文件,位置保存在 Redis 的启动目录。Redis 每次同步数据到磁盘都会生成一个 dump.rdb
文件,新的 dump.rdb
会覆盖旧的 dump.rdb
文件。
1.1.3. 配置 RDB 持久化策略
在 redis.conf
的快照配置中,配置 RDB
保存的策略。
在客户端执行 FLUSHDB
或者 FLUSHALL
或者 SHUTDOWN
时,也会把快照中的数据保存到 dump.rdb
,只不过这种操作已经把数据清空了,保存的也是空文件,没有意义。
1.1.4. 手动保存 RDB 快照
save
命令执行一个同步保存操作,将当前 Redis 实例的所有数据快照 (snapshot)
以 RDB
文件的形式保存到硬盘。
由于 save
指令会阻塞所有客户端,所以保存数据库的任务通常由 BGSAVE
命令异步地执行,而 save
作为保存数据的最后手段来使用,当负责保存数据的后台子进程不幸出现问题时使用。
1.1.5. RDB 数据恢复
通过脚本将 Redis 产生的 dump.rdb
文件备份(cp dump.rdb dump_bak.rdb
),每次启动 Redis 前,把备份的 dump.rdb
文件替换到 Redis 相应的目录(在 redis.conf
中配的的 dir
目录)下,Redis 启动时会加载 dump.rdb
文件,并且把数据读到内存中。
1.1.6. RDB小结
Redis 默认开启 RDB
持久化方式,适合大规模的数据恢复但它的数据一致性和完整性较差。
- RDB 策略的优点
优点是数据恢复速度快,因为它是将整个数据集保存到一个文件中,恢复时只需要将文件读入内存即可。 - RDB 策略的缺点
缺点是如果系统崩溃,最后一次快照之后的数据会丢失。即在进行了几次写操作之后,但是还没到指定的时间间隔,这时候计算机关机了,那么这些操作将会因为没有持久化到磁盘中,将会丢失,下次再启动 redis 服务将不会看到这些数据。(一般 redis 只用来缓存类似 MySQL 中频繁访问的数据,目的只是提高访问效率,真正保存原有数据的还是在 MySQL 这些数据库中)
1.2. AOF 策略
AOF(Append Only File)
策略,Redis 默认不开启。它的出现是为了弥补 RDB
的不足(数据的不一致性),所以它采用日志的形式来记录每个写操作,并追加到文件中。Redis 重启会根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。
1.2.1. AOF 原理
Redis 以日志的形式来记录每个写操作,将 Redis 执行过的所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件,Redis 启动之初会读取该文件重新构建数据,换言之,Redis 重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。
1.2.2. AOF 保存的文件
AOF
保存的文件是 appendonly.aof
文件,位置保存在 Redis 的启动目录。如果开启了 AOF
,Redis 每次记录写操作都会往 appendonly.aof
文件追加新的日志内容。
1.2.3. 配置 AOF 持久化策略
在 redis.conf
的 APPEND ONLY MODE
配置模块中,配置 AOF
保存策略。
1.2.4. AOF 数据恢复
通过脚本将 Redis 产生的 appendonly.aof
文件备份(cp appendonly.aof appendonly_bak.aof
),每次启动 Redis 前,把备份的 appendonly.aof
文件替换到 Redis 相应的目录(在 redis.conf 中配的的 dir
目录)下,只要开启 AOF
的功能,Redis 每次启动,会根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。
但在实际开发中,可能因为某些原因导致 appendonly.aof
文件格式异常,从而导致数据还原失败,可以通过命令 redis-check-aof --fix appendonly.aof
进行修复 。会把出现异常的部分往后所有写操作日志去掉。
1.2.5. AOF 的重写
AOF
采用文件追加方式,文件会越来越大为避免出现此种情况,新增了重写机制,当 AOF
文件的大小超过所设定的阈值时,Redis 就会启动 AOF
文件的内容压缩,只保留可以恢复数据的最小指令集。
AOF
文件持续增长而过大时,会 fork
出一条新进程来将文件重写(也是先写临时文件最后再 rename
),遍历新进程的内存中数据,每条记录有一条的 Set
语句。重写 aof
文件的操作,并没有读取旧的 aof
文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的 aof
文件,这点和快照有点类似。
Redis 会记录上次重写时的 AOF
大小,默认配置是当 AOF
文件大小是上次 rewrite
后大小的一倍且文件大于 64M
时触发。当然,也可以在配置文件中进行配置。
1.2.6. AOF 小结
Redis 需要手动开启 AOF
持久化方式,AOF
的数据完整性比 RDB
高,但记录内容多了,会影响数据恢复的效率。
- AOF 策略的优点
AOF 持久化的优点是数据可靠性高,因为每个写操作都被记录下来了,即使系统崩溃也可以通过日志文件来恢复数据。 - AOF 策略的缺点
缺点是日志文件比快照文件更大,恢复数据的速度也比较慢。
1.3. 应该选用 RDB 策略还是 AOF 策略?
关于 Redis 持久化的使用:若只打算用 Redis 做缓存,可以关闭持久化。若打算使用 Redis 的持久化,建议 RDB
和 AOF
都开启。其实 RDB
更适合做数据的备份,留一后手。AOF
出问题了,还有 RDB
。
AOF
与 RDB
模式可以同时启用,这并不冲突。如果 AOF
是可用的,那 Redis 启动时将自动加载 AOF
,这个文件能够提供更好的持久性保障。
2. Redis 持久化的配置
2.1. RDB 策略的配置
save <seconds> <changes>
配置复合的快照触发条件,即 Redis 在seconds
秒内key
改变changes
次,Redis 把快照内的数据保存到磁盘中一次。默认的策略是:1 分钟内改变了 1 万次
、或者 5 分钟内改变了 10 次
、或者 15 分钟内改变了 1 次
。
如果要禁用 Redis 的持久化功能,则把所有的save
配置都注释掉。stop-writes-on-bgsave-error
当bgsave
快照操作出错时停止写数据到磁盘,这样能保证内存数据和磁盘数据的一致性,但如果不在乎这种一致性,要在bgsave
快照操作出错时继续写操作,这里需要配置为no
。rdbcompression
设置对于存储到磁盘中的快照是否进行压缩,设置为yes
时,Redis 会采用LZF
算法进行压缩;如果不想消耗CPU
进行压缩的话,可以设置为no
,关闭此功能。rdbchecksum
在存储快照以后,还可以让 Redis 使用CRC64
算法来进行数据校验,但这样会消耗一定的性能,如果系统比较在意性能的提升,可以设置为no
,关闭此功能。dbfilename
这是 Redis 持久化数据生成的文件名,默认是dump.rdb
,也可以自己配置。dir
这是 Redis 持久化数据生成文件保存的目录,默认是./
即 Redis 的启动目录,也可以自己配置。
2.2. AOF 策略的配置
appendonly
配置是否开启AOF
,yes
表示开启,no
表示关闭。默认是no
。appendfilename
这是AOF
保存文件名appendfsync
关于AOF
异步持久化策略:
一:always
:同步持久化,每次发生数据变化会立刻写入到磁盘中。性能较差但数据完整性比较好(慢,安全)
二:everysec
:出厂默认推荐,每秒异步记录一次(默认值)
三:no
:不即时同步,由操作系统决定何时同步。no-appendfsync-on-rewrite
重写时是否可以运用appendsync
,默认no
,可以保证数据的安全性。auto-aof-rewrite-percentage
设置重写的基准百分比auto-aof-rewrite-min-size
设置重写的基准值