redis持久化
redis是一个内存数据库,如果宕机会导致数据丢失,对于业务来说自然是不允许的,redis通过持久化机制写到磁盘中保证数据不丢失。
RDB快照
RDB会单独创建一个子进程(fork)来进行持久化,整个过程中,主进程不需要进行任何IO操作,保证了主进程的性能。rdb快照的原理是对redis中的数据进行周期性的持久化,也可以理解为redis每隔一段时间就把当前内存数据的状态持久化到磁盘中。
如何触发RDB:
1.自动触发:通过配置文件中的save自动触发
# save ""
save 900 1
save 300 10
save 60 10000
分别表示:“900秒内至少有一个key被改动、300秒内至少有10个key被改动、60秒内至少有10000个key被改动”时,触发一次RDB操作,自动保存数据集。如果是save ""表示关闭RDB。
2.手动触发:通过save或者bgsave命令。save命令会阻塞其他操作,生产环境慎用。
save:save时只管保存,其它不管,全部阻塞。
bgsave: bgsave是在后台异步进行快照保存,同时还可以响应客户端的请求。
RDB优点:
- 整个redis中只有这一个备份文件,不用经常进行备份。适合大规模的数据恢复。
- 高性能。通过fork子进程来持久化,同时主进程又能继续处理客户端的请求。
- 重启和恢复redis数据的速度很快。
RDB缺点:
- 最后一次持久化后修改的数据会丢失
- 由于是fork了一个与当前进程一样的进程,包含当前进程的所有数据,所以,内存中的数据增加了一倍,性能会有所影响。
AOF
以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis重启的话就根据日志文件的内容,将写指令从头到尾执行一次以完成数据的恢复工作。
开启了aof持久化模式后,redis会将所有收到的修改命令通过write函数追加到日志文件中,具体的执行可以设置以下3种:
- always:每次有修改操作就强制写入(会导致性能低)
- everysec:每秒钟强制写入(推荐使用)
- no:不主动进行持久化,将数据存放在操作系统中,一般linux每30分钟刷新一次数据
这三种模式分别对应配置文件中的appendfsync always、appendfsync everysec,和appendfsync no。
Rewite(AOF重写)
如果采用文件追加方式,那么AOF文件会越来越大,重启恢复时会非常耗时。所以,redis提供了AOF重写机制,当AOF文件超过设定的阈值时,redis将aof文件重写,只保存恢复数据的最小执行集。
rewirte原理:
AOF文件持续增长而过大时,会fork出一个新的进程来重写文件。当AOF文件超过设定的阈值时,redis将aof文件重写,只保存恢复数据的最小执行集。
原理:如果我们反复地执行set操作,那么aof日志中就会重复地保存这些不必要的操作,因为这些命令最终的执行结果和一个set命令的执行结果没有任何区别,rewite删除冗余的命令。
Redis-check-aof --fix
如果在AOF的过程中服务器宕机,命令没有全部追加到日志中,造成AOF文件出错,那么redis重启时会拒绝载入这个文件。可以使用Redis-check-aof --fix来修复出错的文件。
AOF优点:
- 更高的数据安全性和完整性。默认情况下每秒同步,最多丢失一秒的数据。
- 提供Redis-check-aof --fix机制,确保数据正确性。
AOF缺点:
- AOF文件相较于RDB文件大得多,数据恢复效率低。
- 在写入负载很大的情况下,aof不能提供最大延迟的保证,而rbd可以
总结
- RDB保存某一时刻内存数据集的快照。
- AOF以追加形式保存的命令日志文件。
- 通常AOF文件比RDB文件大,数据恢复效率较低。
- AOF数据安全性、完整性比RDB高,RDB丢失数据风险大。
- 根据fsync策略不同,AOF对redis的性能影响比RDB大。
如果同时开启了两种持久话方式,redis数据恢复时会采用哪一种呢?
如果同时开启两种持久化方式,redis重启时会采用AOF文件来恢复数据。因为AOF文件保存的数据比RDB要完整,RDB丢失数据的风险要大一些。
使用场景
- 如果你可以允许当发生宕机时有几分钟的数据丢失,那么就使用RDB快照模式,它可以让你更快地重启redis
- 其余情况均推荐采用RDB+AOF的模式
在使用时可以同时配置rdb和aof两种模式,redis官方也推荐我们这么做,aof为主,rdb为辅,aof记录日志,rdb做数据库备份,以及aof引擎失效后的替代