Redis 是一个基于内存的键值存储系统,它使用内存存储数据,以提供快速读写访问。内存存储的数据是容易丢失的,这就意味着如果Redis一旦奔溃或者重启,所有数据都将丢失。为了解决这个问题,Redis引入了持久化机制,它允许Redis将内存中的数据异步或同步地写入磁盘中,以便在Redis重启时能够从磁盘中恢复数据。
Redis支持两种持久化机制:RDB和AOF。快照是一次全量备份,AOF 日志是连续的增量备份。快照是内存数据的二进制序列化形式,在存储上非常紧凑,而 AOF 日志记录的是内存数据修改的指令记录文本。
RDB(Redis DataBase) 可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot),以二进制的方式写入磁盘。它是Redis默认的持久化方式。使用RDB持久化方式会生成一个名为 dump.rdb 的文件,文件名是可以通过配置文件修改的。RDB持久化分为两种方式:手动触发和自动触发。
手动触发是指手动执行 save 、bgsave、flushall 命令
save :使 Redis 处于阻塞状态,直到 RDB 持久化完成,才会响应其他客户端发来的命令,所以在生产环境一定要慎用。
bgsave :Redis会fork出一个子进程执行持久化生成dump.rdb 文件,主进程只在fork过程中有短暂的阻塞,子进程创建之后,主进程就可以响应客户端请求了。
flushall :该命令会删除Redis的所有数据并清空dump.rdb文件,相当于删库,如果没有dump.rdb文件会生成一个空的dump.rdb文件。
因为BGSAVE命令可以在不阻塞服务器进程的情况下执行,所以推荐使用BGSAVE命令。
我们可以通过save选项设置多个保存条件,只要其中任意一个条件被满足,服务器就会执行BGSAVE命令。
save选项设置的默认条件如下所示:
save 900 1
save 300 10
save 60 10000
默认的配置条件表示,只要满足以下3个条件中的任意1个,BGSAVE命令就会被执行:
Redis载入RDB文件并没有专门的命令,而是在Redis服务器启动时自动执行的。
Redis服务器启动时是否会载入RDB文件还取决于服务器是否启用了AOF持久化功能,具体判断逻辑为:
默认情况下,Redis服务器的AOF持久化功能是关闭的,所以Redis服务器在启动时会载入RDB文件。
服务器状态
创建和载入RDB文件,可能存在的服务器状态有以下3种:
优点
缺点
AOF日志是持续增量的备份,是基于写命令存储的可读的文本文件。AOF日志会在持续运行中持续增大,由于Redis重启过程需要优先加载AOF日志进行指令重放以恢复数据,恢复时间会无比漫长。所以需要定期进行AOF重写,对AOF日志进行瘦身。目前AOF是Redis持久化的主流方式。AOF持久化也分为手动触发和自动触发。AOF类似于MySQL的binlog
AOF持久化的实现
AOF默认是关闭的,通过redis.conf配置文件进行开启
appendonly yes #yes开启AOF日志,no关闭
appendfilename "appendonly.aof"# aof文件名
appendfsync everysec ## 指定aof操作中文件同步策略
手动触发
可以使用BGREWRITEAOF命令手动触发持久化机制。
BGREWRITEAOF:Redis在后台异步进行AOF重写操作,即将AOF文件重写为一个新的、更加紧凑的AOF文件,不会阻塞Redis服务器进程。
自动触发
通过auto-aof-rewrite-percentage和auto-aof-rewrite-min-size参数配置AOF文件重写触发条件,当AOF文件大小达到auto-aof-rewrite-min-size并且AOF文件增长率超过了auto-aof-rewrite-percentage时,Redis会自动启动AOF重写操作。默认配置为auto-aof-rewrite-percentage 100和auto-aof-rewrite-min-size 64mb,也就是说当AOF文件大小达到原先文件的2倍,并且超过64mb将对AOF文件进行重写。
修改配置文件中AOF的写入策略。
AOF是文件操作,对于变更操作比较密集的server,那么将造成磁盘IO的负荷加重。此外linux对文件操作采取了“延迟写入”手段,即并非每次write操作都会触发实际磁盘操作,而是进入了buffer中,当buffer数据达到阀值时触发实际写入(也有其他时机),这是linux对文件系统的优化。
Linux 的glibc
提供了fsync(int fd)
函数可以将指定文件的内容强制从内核缓存刷到磁盘。只要 Redis 进程实时调用 fsync 函数就可以保证 aof 日志不丢失。但是 fsync 是一个磁盘 IO 操作,它很慢!如果 Redis 执行一条指令就要 fsync 一次,那么 Redis 高性能的地位就不保了。
因此在上述配置文件中,可观察到Redis中提供了3中AOF记录同步选项:
always: 每次执行写命令时都立即将命令同步到磁盘,这种方式数据最可靠,但写入性能最差。
everysec: 每秒钟同步一次,性能和数据可靠性折中。AOF 默认使用的策略
no: 完全依赖操作系统来决定何时同步磁盘,性能最好,但数据可靠性最差
载入AOF文件
因为AOF文件包含了重建数据库所需的所有写命令,所以Redis服务器只要读入并重新执行一遍AOF文件里面保存的写命令,就可以还原Redis服务器关闭之前的数据。
Redis读取AOF文件并还原数据库的详细步骤如下:
AOF重写机制
因为AOF持久化是通过保存被执行的写命令来记录数据库数据的,所以随着Redis服务器运行时间的增加,AOF文件中的内容会越来越多,文件的体积会越来越大,如果不做控制,会有以下2点坏处:
Redis提供了AOF文件重写功能,即Redis服务器会创建一个新的AOF文件来替代现有的AOF文件,新旧两个AOF文件所保存的数据库数据相同,但新AOF文件不会包含任何浪费空间的冗余命令(用一条命令去记录键值对,代替之前记录这个键值对的多条命令),所以新AOF文件的体积通常会比旧AOF文件的体积要小很多。
AOF后台重写
Redis服务器使用单个线程来处理命令请求,AOF重写会进行大量文件写入操作长时间阻塞线程。Redis将AOF文件重写功能放到子进程里执行,这样做有以下2个好处:
AOF后台重写的步骤如下所示:
Redis提供了BGREWRITEAOF
命令来执行以上步骤。
参考:https://zhuanlan.zhihu.com/p/106997927
https://zhuanlan.zhihu.com/p/77646963