数据持久化功能是redis相比于其他缓存中间件具有的优势之一,它可以保证在redis重启时,数据不丢失,以提升系统的性能及可用性。
那么redis是如何实现数据持久化的呢?它提供了两种数据持久化的解决方案: RDB、AOF。
RDB
redis默认的持久化策略是RDB方案,rdb方案生成的rdb文件是一个经过压缩的二进制文件,通过它可以还原到生成RDB文件时的数据库状态,当redis仅开启了RDB方案重启时会载入rdb文件,这期间服务器处于阻塞状态,直到载入完成。
redis提供了手动和自动两种方式生成rdb文件
手动方式
- 执行save命令,该命令会让服务器处于阻塞状态直到生成RDB文件结束,这个命令会导致redis服务器暂时不可用,所以不推荐。
- 执行bgsave命令,redis会fork一个子进程,由子进程来完成生成RDB文件的操作。这个命令不会阻塞客户端请求(只有在fork进程时会发生短暂的阻塞)。
自动方式
- 可以通过在配置文件中设置生成RDB文件的触发条件,如下是redis的默认配置 ,这几种情况(900秒内至少出现一条数据更改,300秒内至少出现10条数据更改,60秒内至少出现10000条数据更改)都会触发redis执行bgsave命令。
save 900 1 save 300 10 save 60 10000
AOF
redis提供的另外一种持久化策略:AOF方案,它通过记录redis服务器所执行的写命令来记录数据库状态。
当AOF持久化功能处于打开状态时,服务器在执行一条写命令之后,会以协议格式将执行的写命令追加到记录服务器状态的aof_buf缓冲区的末尾。
针对何时将aof_buf缓冲区的内容写入并同步到aof文件中,redis提供了三种方式:
- always :总是将aof_buf缓冲区的内容写入并同步到AOF文件,数据完整性好(最多丢失一个事件循环内的数据更改),但性能差。
- everysec: 将aof_buf缓冲区的内容写入AOF文件,如果距离上次同步AOF文件时间超过一秒,那么同步aof文件。性能好,但可能丢失一秒内的数据。
- no :将aof_buf缓冲区的内容写入AOF文件,同步AOF文件操作由操作系统决定,性能与everysec差不多,但可能丢失更多的数据。
注:为了提高文件的写入效率,现代操作系统会将写入数据暂时保存在一个内存缓冲区中,当缓存区写满或达到限定时间时, 再真正将缓冲区内数据写入磁盘,但这种做法也给数据带来了安全问题,如果计算机停机,缓存区中的内容会丢失。为此系统提供了fsync和fdatasync两个同步函数,它们可以强制操作系统立即将缓存区中的内容写入到磁盘中,从而确保写入数据的安全性。
下面是同步AOF文件的默认配置:
# appendfsync always
appendfsync everysec
# appendfsync no
当执行一条 set name jason 命令时,可以直接打开AOF文件,我们可以在文件末尾看到如下内容:
$3 set $4 name $5 jason
aof文件重写
随着服务器运行时间的流逝,AOF文件中的内容会越来越多,如果不加以控制,体积过大的AOF文件可能会对redis服务器造成影响,所以redis提供了 AOF重写的机制,以应对AOF文件越来越大的问题。 执行bgrewriteaof命令,redis服务器会创建一个子进程 通过读取当前数据库的状态生成一个新的AOF文件,在命令执行期间,redis服务器会维护一个AOF重写缓冲区,该缓冲区会在子进程创建新AOF文件期间,记录服务器执行的所有写命令,当子进程创建好新的AOF文件之后,服务器会将重写缓冲区中的内容追加到新AOF文件的末尾,使得新旧两个AOF文件所保存的数据库状态一致,最后服务器会用新的AOF文件替换旧的AOF文件,完成AOF文件的重写操作。
rdb与aof的对比
RDB持久化 |
AOF持久化 |
全量备份,一次保存整个数据库 |
增量备份,一次保存一个修改数据库的命令 |
保存的间隔较长 |
保存的间隔默认一秒 |
数据还原速度快 |
数据还原速度一般 |
save会阻塞,但bgsave或者自动不会阻塞 |
无论是平时还是AOF重写,都不会阻塞 |
更适合数据备份,默认开启 |
更适合用来保存数据,和一般SQL持久化方式一样,默认关闭 |
启动优先级 : 低 |
启动优先级 : 高 |
体积 : 小 |
体积 : 大 |
恢复速度 : 快 |
恢复速度 : 慢 |
数据安全性 : 丢数据 |
数据安全性 : 根据策略决定 |
轻重 : 重 |
轻重: 轻 |