本文将介绍Redis持久化的两种方式:快照持久化和AOF持久化,并对两种方法进行分析和对比,方便在实际中做出选择。
持久化
什么是持久化
Redis所有数据保存在内存中,对数据的更新将异步地保存到磁盘上,使得数据在Redis重启之后仍然存在。这么做这有什么实际意义呢?将数据存储到硬盘是为了以后可以重用数据,将数据进行备份,可以在系统故障的时候从备份进行恢复。还有一点,存储在Redis里面的数据可能是经过复杂运算而得出的结果,把这些数据进行存储,方便后续的使用,以达到“空间换时间”的效果。
持久化的实现方式
Redis提供了两种不同的持久化方法将数据保存到硬盘里面。
快照持久化:将Redis某一时刻存在的所有数据都写入硬盘。
AOF持久化:AOF的全称叫append-only file,中文意思是只追加文件。当使用AOF持久化方式的时候,Redis执行写命令的时候,将被执行的写命令复制到硬盘里面,说的通俗一点就是写日志。
快照持久化
什么是快照持久化
Redis通过创建快照来获得存储在内存里面的数据在某个时间节点上的副本。
触发机制-主要三种方式
-
save(同步)
-
bgsave(异步)
-
自动
save命令和bgsave命令对比:
命令
|
save
|
bgsave
|
IO类型
|
同步
|
异步
|
是否阻塞
|
是
|
是
|
复杂度
|
O(n)
|
O(n)
|
优点
|
不会消耗额外内存
|
不阻塞客户端命令
|
缺点
|
阻塞客户端命令
|
需要fork,消耗内存
|
快照持久化选项:
多久执行一次自动快照操作,60s之内有1000次操作写入时执行 save 60 1000 创建快照失败后是否仍然继续执行写命令 stop-writes-on-bgsave-error no 是否对快照文件进行压缩 rdbcompression yes 命名硬盘上的快照文件 dbfilename dump.rdb
最佳配置:
dbfilename dump-${port}.rdb dir /bigdiskpath stop-writes-on-bgsave-error yes rdbcompression yes rdbchecksum yes
AOF持久化
快照持久化现存问题
耗时、耗性能:通过bgsave命令进行持久化的的时候,需要fork一个子进程,如果数据量很大的话,需要的内存也会相应的变大,内存的占用会导致Redis性能降低。
不可控、丢失数据:举个例子,上一次创建快照是11:00开始创建并创建成功。如果Redis在12:00开始创建新的快照,如果系统在未完成创建快照之前崩溃,11:00-12:00写入的数据将会丢失;如果系统在快照创建完成之后崩溃,那么12:00之后,创建快照的过程中的数据将会丢失。
什么是AOF
AOF持久化将被执行的写命令写到AOF文件的末尾,以达到记录数据的目的。Redis只要从头到尾重新执行一次AOF所有的命令就可以恢复数据。
AOF三种策略
三种策略对比:生产环境中需要根据实际的需求进行选择。
命令 | always | everysec | no |
优点 | 不丢失数据 | 每秒一次fsync | 不用管 |
缺点 | IO开销较大,一般的SATA盘只有几百TPS | 丢1s数据 | 不可控 |
AOF重写
随着Redis的运行,被执行的写命令不断同步到AOF文件中,AOF文件的体积越来越大,极端情况将会占满所有的硬盘空间。如果AOF文件体积过大,还原的过程也会相当耗时。为了解决AOF文件不断膨胀的问题,需要移除AOF文件中的冗余命令来重写AOF。
原生AOF | AOF重写 |
set hello world
set hello java
set hello redis
incr counter
inct counter
rpush mylist a
rpush mylist b
rpush mylist c
过期数据
|
set hello redis
set counter 2
rpush mylist a b c
|
-
bgrewriteaof命令
bgrewriteaof命令和bgsave命令的工作原理相似:Redis创建一个子进程,然后由子进程负责对AOF文件进行重写。
-
AOF重写配置
配置参数说明:
名称 | 含义 |
auto-aof-rewrite-min-size | AOF文件重写需要的尺寸 |
auto-aof-rewrite-percentage | AOF文件增长率 |
具体配置:
appendonly yes appendfilename "appendonly-${port}.aof" appendfsync everysc dir /bigdiskpath no-appendfsync-on-rwrite yes auto-aof-rewrit-percentage 100 auto-aof-rewrite-min-size 64mb
快照持久化和AOF持久化的对比和选择
对比
命令 | 快照持久化 | AOF持久化 |
启动优先级 | 低 | 高 |
体积 | 小 | 大 |
恢复速度 | 快 | 慢 |
数据安全性 | 丢数据 | 根据策略决定 |
轻重 | 重 | 轻 |
选择
在实际生产环境中,根据数据量、应用对数据的安全要求、预算限制等不同情况,会有各种各样的持久化策略;如完全不使用任何持久化、使用快照持久化或AOF持久化的一种,或同时开启快照持久化和AOF持久化等。此外,持久化的选择必须与Redis的主从策略一起考虑,因为主从复制与持久化同样具有数据备份的功能,而且主机master和从机slave可以独立的选择持久化方案。
(1)如果Redis中的数据完全丢弃也没有关系(如Redis完全用作DB层数据的cache),那么无论是单机,还是主从架构,都可以不进行任何持久化。
(2)在单机环境下(对于个人开发者,这种情况可能比较常见),如果可以接受十几分钟或更多的数据丢失,选择快照持久化对Redis的性能更加有利;如果只能接受秒级别的数据丢失,应该选择AOF。
(3)但在多数情况下,我们都会配置主从环境,slave的存在既可以实现数据的热备,也可以进行读写分离分担Redis读请求,以及在master宕掉后继续提供服务。在这种情况下,一种可行的做法是:master:完全关闭持久化,这样可以让master的性能达到最好slave:关闭快照持久化,开启AOF(如果对数据安全要求不高,开启快照持久化关闭AOF也可以),并定时对持久化文件进行备份(如备份到其他文件夹,并标记好备份的时间);然后关闭AOF的自动重写,然后添加定时任务,在每天Redis闲时(如凌晨12点)调用bgrewriteaof。