rdb
RDB是一种快照存储持久化方式,具体就是将Redis某一时刻的内存数据保存到硬盘的文件当中,默认保存的文件名为dump.rdb,而在Redis服务器启动时,会重新加载dump.rdb文件的数据到内存当中恢复数据。 触发 RDB 持久化过程分为手动触发和自动触发
手动触发
·save 命令:阻塞当前 Redis 服务器,直到 RDB 过程完成为止,对于内存比较大的实例会造成长时间阻塞,线上环境不建议使用。
·bgsave 命令:Redis 进程执行 fork 操作创建子进程,RDB 持久化过程由子进程负责,完成后自动结束。阻塞只发生在 fork 阶段,一般时间很短。
持久化流程
bgsave 是主流的触发 RDB 持久化方式
1)执行 bgsave 命令,Redis 父进程判断当前是否存在正在执行的子进程,如 RDB/AOF 子进程,如果存在 bgsave 命令直接返回。
2)父进程执行 fork 操作创建子进程,fork 操作过程中父进程会阻塞,通过 info stats 命令查看 latest_fork_usec 选项,可以获取最近一个
fork 操作的耗时,单位为微秒。
3)父进程 fork 完成后,bgsave 命令返回“Background saving started”信息并不再阻塞父进程,可以继续响应其他命令。
4)子进程创建 RDB 文件,根据父进程内存生成临时快照文件,完成后对原有文件进行原子替换。执行 lastsave 命令可以获取最后一次生成 RDB
的时间,对应 info 统计的 rdb_last_save_time 选项。
5)进程发送信号给父进程表示完成,父进程更新统计信息,具体见 info Persistence 下的 rdb_* 相关选项。
自动触发
在redis.conf配置文件中进行配置,Redis配置文件中的save指定到达触发RDB持久化的条件,比如【多少秒内至少达到多少写操作】就开
启RDB数据同步。
# 900s内至少达到一条写命令
save 900 1
# 300s内至少达至10条写命令
save 300 10
# 60s内至少达到10000条写命令
save 60 10000
aof
AOF持久化方式会记录客户端对服务器的每一次写操作命令到日志当中,并将这些写操作以 Redis协议追加保存到以后缀为aof文件末尾
持久化配置
appendonly yes #启用aof持久化方式
appendfsync always #每次收到写命令就立即强制写入磁盘,最慢的大概只有几百的TPS,但是保证完全的持久化,不推荐使用
appendfsync everysec #每秒钟强制写入磁盘一次,在性能和持久化方面做了很好的折中,推荐
appendfsync no #完全依赖os,性能最好,持久化没保证,Redis不会主动调用fsync去将AOF日志内容同步到磁盘,所以这一切就完全依赖于操作系统的 调试了。对大多数Linux操作系统,是每30秒进行一次fsync,将缓冲区中的数据写到磁盘上。
流程如下:
持久化方式
·手动触发:直接调用 bgrewriteaof 命令。
·自动触发:根据 auto-aof-rewrite-min-size和auto-aof-rewrite-percentage 参数确定自动触发时机。
·auto-aof-rewrite-min-size:表示运行 AOF 重写时文件最小体积,默认为 64MB。
·auto-aof-rewrite-percentage:代表当前 AOF 文件空间(aof_current_size)和上一次重写后 AOF 文件空间(aof_base_size)的比值。
示例:
auto-aof-rewrite-percentage:100
auto-aof-rewrite-min-size:64mb
默认配置是当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发
持久化的选择
1)如果Redis中的数据完全丢弃也没有关系(如Redis完全用作DB层数据的cache),那么无论是单机,
还是主从架构,都可以不进行任何持久化。
2)在单机环境下(对于个人开发者,这种情况可能比较常见),如果可以接受十几分钟或更多的数据丢失,选择RDB对Redis的性能更加有利;
如果只能接受秒级别的数据丢失,应该选择AOF。
3)但在多数情况下,我们都会配置主从环境,slave的存在既可以实现数据的热备,也可以进行读写分离分担Redis读请求,
以及在master宕掉后继续提供服务。
在这种情况下的做法是:
master:完全关闭持久化(包括RDB和AOF),这样可以让master的性能达到最好;
slave:关闭RDB,开启AOF(如果对数据安全要求不高,开启RDB关闭AOF也可以),并定时对持久化文件进行备份(如备份到其他文件夹,并标记好 备份的时间);然后关闭AOF的自动重写,然后添加定时任务,在每天Redis闲时(如凌晨12点)调用bgrewriteaof。
这里需要解释一下,为什么开启了主从复制,可以实现数据的热备份,还需要设置持久化呢?因为在一些特殊情况下,主从复制仍然不足以保证数
据的安全,例如:
master和slave进程同时停止:考虑这样一种场景,如果master和slave在同一个机房,则一次停电事故就可能导致master和slave机器同时关机,
Redis进程停止;如果没有持久化,则面临的是数据的完全丢失。
master误重启:考虑这样一种场景,master服务因为故障宕掉了,如果系统中有自动拉起机制(即检测到服务停止后重启该服务)将master自动重
启,由于没有持久化文件,那么master重启后数据是空的,
slave同步数据也变成了空的;如果master和slave都没有持久化,同样会面临数据的完全丢失。需要注意的是,即便是使用了哨兵进行自
动的主从切换,
也有可能在哨兵轮询到master之前,便被自动拉起机制重启了。因此,应尽量避免“自动拉起机制”和“不做持久化”同时出现。
4)异地灾备:上述讨论的几种持久化策略,针对的都是一般的系统故障,如进程异常退出、宕机、断电等,这些故障不会损坏硬盘。但是对于一些可能
导致硬盘损坏的灾难情况,如火灾地震,就需要进行异地灾备。
例如对于单机的情形,可以定时将RDB文件或重写后的AOF文件,通过scp拷贝到远程机器,如阿里云;对于主从的情形,可以定时在master上执行 bgsave,然后将RDB文件拷贝到远程机器,
或者在slave上执行bgrewriteaof重写AOF文件后,将AOF文件拷贝到远程机器上。
一般来说,由于RDB文件文件小、恢复快,因此灾难恢复常用RDB文件;异地备份的频率根据数据安全性的需要及其它条件来确定,但最好不要低于一 天一次。
1、企业级的持久化的配置策略
save 60 10000:如果你希望尽可能确保说,RDB最多丢1分钟的数据,那么尽量就是每隔1分钟都生成一个快照,低峰期,数据量很少,也没必要
10000->生成RDB,1000->RDB,这个根据你自己的应用和业务的数据量,你自己去决定
AOF一定要打开,fsync,everysec
auto-aof-rewrite-percentage 100: 就是当前AOF大小膨胀到超过上次100%,上次的两倍
auto-aof-rewrite-min-size 64mb: 根据你的数据量来定,16mb,32mb
2、数据备份方案
RDB非常适合做冷备,每次生成之后,就不会再有修改了
数据备份方案
(1)写crontab定时调度脚本去做数据备份
(2)每小时都copy一份rdb的备份,到一个目录中去,仅仅保留最近48小时的备份
(3)每天都保留一份当日的rdb的备份,到一个目录中去,仅仅保留最近1个月的备份
(4)每次copy备份的时候,都把太旧的备份给删了
(5)每天晚上将当前服务器上所有的数据备份,发送一份到远程的云服务上去【crontab】
AOF常用配置总结
appendonly no:是否开启AOF
appendfilename "appendonly.aof":AOF文件名
dir ./:RDB文件和AOF文件所在目录
appendfsync everysec:fsync持久化策略
no-appendfsync-on-rewrite no:AOF重写期间是否禁止fsync;如果开启该选项,可以减轻文件重写时CPU和硬盘的负载(尤其是硬盘),但是可能会丢失
AOF重写期间的数据;需要在负载和安全性之间进行平衡
auto-aof-rewrite-percentage 100:文件重写触发条件之一
auto-aof-rewrite-min-size 64mb:文件重写触发提交之一
aof-load-truncated yes:如果AOF文件结尾损坏,Redis启动时是否仍载入AOF文件