Redis持久化
一、持久化简介
因为Redis是内存数据库,它将自己的数据库状态储存在内存里面,所以如果不想办法将储存在内存中的数据库状态保存到磁盘里面,那么一旦服务器进程退出,服务器中的数据库状态也会消失不见。
因此Redis 提供了两种持久化方案,RDB (Redis DataBase)和 AOF (Append Only File)。
二、RDB持久化
RDB 是 Redis 默认的持久化方案。RDB持久化可以手动执行也可以根据服务器配置选项定期执行。该功能会将在某个时间点上的数据库状态保存到一个.rdb文件。Redis 重启会通过加载.rdb文件恢复数据。
2.1 RDB手动备份恢复
有两个redis命令可以用于生成rdb文件:
save:save命令会阻塞redis服务器进程,直到rdb文件创建完成为止,在服务器进程阻塞期间不能处理任何命令请求;
bgsave:bgsave命令会派生出一个子进程,由子进程负责创建rdb文件,父进程继续处理redis命令。
rdb文件的数据恢复工作是在redis启动时自动完成的,没有特殊命令来手动进行恢复工作,值得注意的是由于AOF的更新频率通常会比RDB更新频率高,因此如果服务器开启了AOF持久化那么redis优先使用AOF恢复数据,只有在AOF持久化关闭时才使用RDB恢复数据。
2.2 RDB配置
/etc/redis/redis.conf 文件中
那么为什么需要配置这么多条规则呢?因为Redis每个时段的读写请求肯定不是均衡的,为了平衡性能与数据安全,我们可以自由定制什么情况下触发备份。所以这里就是根据自身Redis写入情况来进行合理配置。
2.3 RDB优缺点
优点
适合大规模的数据恢复。
如果业务对数据完整性和一致性要求不高,RDB是很好的选择。
缺点:
数据的完整性和一致性不高,因为RDB可能在最后一次备份时宕机了。
备份时占用内存,因为Redis 在备份时会独立创建一个子进程,将数据写入到一个临时文件(此时总占用内存是原来的两倍),最后再将临时文件替换之前的备份文件。所以Redis 的持久化和数据的恢复要选择在夜深人静的时候执行是比较合理的。
三、AOF持久化
Redis 默认不开启。它的出现是为了弥补RDB的不足(数据的不一致性),所以它采用日志的形式来记录每个写操作,并追加到文件中。Redis 重启的会根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。
3.1 AOF持久化步骤
命令追加:在AOF模式打开的情况下,服务器每执行一次写命令就会以协议格式将执行的写命令追加到aof_buf缓冲区的末尾;
AOF文件的写入和同步:Redis每执行完一次事件循环,就要考虑要不要将缓冲区的数据写入AOF文件,写入同步策略有配置文件的
appendfsync
决定:appendfsync
的值有三个always:将缓冲区所有内容写入并同步AOF文件;
everysec(默认):将缓冲区内容写入AOF文件,如果上次同步AOF文件的时间与现在间隔超过1秒钟,那么在此对AOF文件进行同步,并且这个同步操作是由一个线程专门执行的;
no:将缓冲区内容写入文件,不对AOF进行同步,何时同步由操作系统来决定。
3.2 AOF重写机制
因为AOF备份的策略是保存所有的写命令,当写命令不断增加时,AOF文件会越来越大,可能会影响系统性能和恢复数据的性能。为了解决这个问题,Redis提供了AOF文件重写(rewrite)功能。通过该功能,Redis服务器可以创建一个新的AOF文件来替代现有的AOF文件,新旧两个AOF文件所保存的数据库状态相同,但新AOF文件不会包含任何浪费空间的冗余命令,所以新AOF文件的体积通常会比旧AOF文件的体积要小得多。
那么它是如何实现的呢?虽然名字叫做AOF重写,但是新文件并不会读取并分析旧的AOF文件,而是通过读取当前数据库的状态来实现的。过程就是首先从数据库中读取键现在的值,然后用一条命令去记录键值对,代替之前记录这个键值对的多条命令,这就是AOF重写功能的实现原理。
数据不一致的处理
Redis使用一个子进程来处理AOF的重写,这样会导致数据不一致的问题,比如当开始重写的时候数据库只有key1,在重写过程中有增加了key2,那么重写完后AOF中只有key1,就导致了数据的不一致。为了解决这种数据不一致问题,Redis服务器设置了一个AOF重写缓冲区,这个缓冲区在服务器创建子进程之后开始使用,当Redis服务器执行完一个写命令之后,它会同时将这个写命令发送给AOF缓冲区和AOF重写缓冲区。
当子进程完成AOF重写工作之后,它会向父进程发送一个信号,父进程在接到该信号之后,会调用一个信号处理函数,并执行以下工作:
将AOF重写缓冲区中的所有内容写入到新AOF文件中,这时新AOF文件所保存的数据库状态将和服务器当前的数据库状态一致。
对新的AOF文件进行改名,原子地(atomic)覆盖现有的AOF文件,完成新旧两个AOF文件的替换。这个信号处理函数执行完毕之后,父进程就可以继续像往常一样接受命令请求了。
在整个AOF后台重写过程中,只有信号处理函数执行时会对服务器进程(父进程)造成阻塞,在其他时候,AOF后台重写都不会阻塞父进程,这将AOF重写对服务器性能造成的影响降到了最低。
3.3 AOF配置和恢复
/etc/redis/redis.conf 文件中
恢复数据:
appendonly.aof其实就是文本文件,所以完全可以手动修改aof文件来恢复成指定的数据:
3.4 AOF优缺点
优点:
数据的完整性和一致性更高
缺点:
因为AOF记录的内容多,文件会越来越大,数据恢复也会越来越慢。
四、总结
Redis 默认开启RDB持久化方式,在指定的时间间隔内,执行指定次数的写操作,则将内存中的数据写入到磁盘中。
RDB 持久化适合大规模的数据恢复但它的数据一致性和完整性较差。
Redis 需要手动开启AOF持久化方式,默认是每秒将写操作日志追加到AOF文件中。
AOF 的数据完整性比RDB高,但记录内容多了,会影响数据恢复的效率。
Redis 针对 AOF文件大的问题,提供重写的瘦身机制。
若只打算用Redis 做缓存,可以关闭持久化。
若打算使用Redis 的持久化。建议RDB和AOF都开启。其实RDB更适合做数据的备份,留一后手。AOF出问题了,还有RDB。
问题
RDB和AOF持久化后的文件存储在哪?
RDB文件存储在/var/lib/redis/dump.rdb
,实际位置取决于配置文件/etc/redis/redis.conf
中的dir /var/lib/redis
,也可以在redis-cli中使用命令config get dir
获取。
AOF持久化开启后,是否只是记录开启时间点之后的写操作,那之前的数据如何保证备份呢?
AOF重写时会以当前数据库为依据生成所有写入语句。
Last updated