天天看点

Redis持久化方式的选择

本文将介绍Redis持久化的两种方式:快照持久化和AOF持久化,并对两种方法进行分析和对比,方便在实际中做出选择。

Redis所有数据保存在内存中,对数据的更新将异步地保存到磁盘上,使得数据在Redis重启之后仍然存在。这么做这有什么实际意义呢?将数据存储到硬盘是为了以后可以重用数据,将数据进行备份,可以在系统故障的时候从备份进行恢复。还有一点,存储在Redis里面的数据可能是经过复杂运算而得出的结果,把这些数据进行存储,方便后续的使用,以达到“空间换时间”的效果。

Redis提供了两种不同的持久化方法将数据保存到硬盘里面。

快照持久化:将Redis某一时刻存在的所有数据都写入硬盘。

AOF持久化:AOF的全称叫append-only file,中文意思是只追加文件。当使用AOF持久化方式的时候,Redis执行写命令的时候,将被执行的写命令复制到硬盘里面,说的通俗一点就是写日志。

Redis通过创建快照来获得存储在内存里面的数据在某个时间节点上的副本。

save(同步)

bgsave(异步)

自动

save命令:客户端向Redis发送save命令来创建一个快照文件。

执行save命令的时候,如果存在老的快照文件,新的将会替换老的。

bgsave命令:客户端向Redis发送bgsave命令,Redis调用fork创建一个子进程,然后子进程负责将快照写入硬盘,而父进程则继续处理命令请求。

save命令和bgsave命令对比:

<col>

命令

save

bgsave

IO类型

同步

异步

是否阻塞

复杂度

O(n)

优点

不会消耗额外内存

不阻塞客户端命令

缺点

阻塞客户端命令

需要fork,消耗内存

自动生成:通过配置,满足任何一个条件就会创建快照文件。

快照持久化选项:

最佳配置:

耗时、耗性能:通过bgsave命令进行持久化的的时候,需要fork一个子进程,如果数据量很大的话,需要的内存也会相应的变大,内存的占用会导致Redis性能降低。

不可控、丢失数据:举个例子,上一次创建快照是11:00开始创建并创建成功。如果Redis在12:00开始创建新的快照,如果系统在未完成创建快照之前崩溃,11:00-12:00写入的数据将会丢失;如果系统在快照创建完成之后崩溃,那么12:00之后,创建快照的过程中的数据将会丢失。

AOF持久化将被执行的写命令写到AOF文件的末尾,以达到记录数据的目的。Redis只要从头到尾重新执行一次AOF所有的命令就可以恢复数据。

always:每条Redis写命令都同步写入硬盘。

everysec:每秒执行一次同步,将多个命令写入硬盘。

no:由操作系统决定何时同步。

三种策略对比:生产环境中需要根据实际的需求进行选择。

always

everysec

no

不丢失数据

每秒一次fsync

不用管

IO开销较大,一般的SATA盘只有几百TPS

丢1s数据

不可控

随着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 counter 2

rpush mylist a b c

AOF重写的两种实现方式:

bgrewriteaof命令

bgrewriteaof命令和bgsave命令的工作原理相似:Redis创建一个子进程,然后由子进程负责对AOF文件进行重写。

AOF重写配置

配置参数说明:

名称

含义

auto-aof-rewrite-min-size

AOF文件重写需要的尺寸

auto-aof-rewrite-percentage

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。

[1] Josiah L.Carlson. Redis实战[M]. 陈健宏译. 北京:人民邮电出版社,2015.

[2] Redis持久化方案该如何选型

[3] 一站式学习Redis-从入门到高可用分布式实践

由于博主也是在攀登的路上,文中可能存在不当之处,欢迎各位多指教! 如果文章对您有用,那么请点个”推荐“,以资鼓励!

继续阅读