Redis
持久化RDB/AOF
命令
RDB(dump.rdb文件)
适用于大规模数据恢复,且对数据完整性和一致性不高的情况
把当前进程数据生成快照保存到硬盘的过程
RDB文件的处理
保存位置:dbfilename
压缩:rdbcompression,默认开启LZF压缩,会消耗CPU
校验:rdbchecksum,使用CRC64算法校验
RDB持久化触发方式 :手动触发
save:阻塞当前Redis服务器,直到RDB过程完成为止,对于内存比较大的实例容易造成长时间的阻塞,线上不建议使用
bgsave:阻塞只发生在fork阶段,一般时间很短。Redis进程执行fork操作创建子进程,RDB持久化由子进程负责,完成后自动结束。
自动触发的情况
配置文件使用save相关配置,默认15分钟至少一次修改,5分钟至少10次修改,1分钟至少10000次修改时
从节点执行全量复制,主节点自动执行bgsave生成RDB文件发送给从节点
执行debug reload命令重新加载Redis
默认情况下执行shutdown命令时,如果没有开启AOF持久化,则自动执行bgsave
优缺点
优点
RDB是一个紧凑压缩的二进制文件,代表Redis某一个时间点的快照,非常适用于备份,全量复制等场景
Redis加载RDB恢复速度远快于AOF的方式
缺点
最后一次持久化后的数据可能丢失
RDB没法做到实时持久化,因为bgsave每次运行时间都要执行fork操作创建子进程,频繁执行成本过高
老版本RDB文件可能无法兼容新版本RDB文件
AOF(append-only-file):appendonly yes开启
以独立日志的方式记录每次的写命令(包括flushall),解决数据持久化的实时性
执行了flush操作,就只能从AOF恢复,RDB会清空
流程
命令写入write:所有写操作会追加到aof_buf缓冲中
aof文件使用RESP协议
使用aof_buf缓冲能减小硬盘负载,并且方便Redis提供多种向硬盘同步的策略
文件同步fsync:AOF根据相应的策略向磁盘做同步操作
AOF缓冲区同步策略(由配置参数appendfsync)
always(不建议配置):每次同步都要调用fsync同步AOF文件,数据安全性最高,但导致Redis的写入性能下降
everysec(默认):fsync操作由专门的线程每秒调用一次,同时兼顾性能与数据安全,在系统突然宕机的情况下也不会丢失超过两秒的数据
no:不对AOF做fsync同步,同步由操作系统负责,但操作系统的同步周期不可控,性能最高,但不能保证数据安全性
使用write和fsync的说明
write会触发延迟写机制,linux系统提供页缓冲区来提高硬盘性能,write在写入系统缓冲区后直接返回,同步硬盘操作依赖于操作系统调度机制
fsync针对单个文件操作,做强制硬盘同步,fsync将阻塞直到写入硬盘操作完成后返回,保证数据持久化
文件重写rewrite:(bgrewriteaof命令)随着AOF文件增大,需要定期对AOF文件做重写操作
压缩AOF文件大小,降低文件占用空间
进程已经超时的数据不写入文件
旧AOF含有的的无效命令,新的AOF文件只保留最终数据的写命令
多条写命令合并成一个
重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合
触发条件
手动触发:直接调用bgrewriteaof命令
自动触发:同时满足以下两个条件时触发
根据auto-aof-rewrite-min-size(触发AOF重写时的文件最小体积,默认为64M)
根据auto-aof-rewrite-percentage
重启加载:Redis重启时,优先从AOF加载命令恢复数据,AOF文件不存在才从RDB加载
性能优化建议
RDB只做后被用途,建议只在Slave上持久化RDB文件,而且只设置15分钟备份一次就行了
开启AOF在最坏情况下也只会丢失不超过两秒的数据,坏处是带来了持续的IO,并且rewrite过程中产生的新数据写到新文件的阻塞几乎是不可避免的,只要硬盘许可,应该尽量减少AOF rewrite的频率,AOF重写的基础大小默认值64MB太小,可以改到5G以上,默认超过原大小100%时可以改到适当数值
如果不开启AOF,仅靠主从复制实现高可用也可以,这样能剩下大笔IO开销,也减少了rewrite带来的系统波动,代价是master/slave同时宕掉,会丢失十几分钟的数据
问题定位和优化
fork操作
控制Redis实例的最大内存,fork操作跟内存量成正比,建议每个实例控制在10GB以内
避免物理内存不足导致fork失败
降低fork操作频率,如放宽AOF触发时机
子进程开销监控和优化
子进程负责把进程内数据分批写入文件,该过程是CPU密集型操作,通常子进程对单核CPU利用率接近90%
避免和其他CPU密集型操作服务部署在一起
部署多个Redis实例时,尽量保证同一时刻只有一个子进程执行重写操作
避免大量写入时做子进程重写操作,这样将导致父进程维护大量页副本,造成内存消耗
AOF追加阻塞
当系统资源繁忙时fsync操作会造成Redis主线程阻塞
主线程会对比上一次AOF同步时间,如果距上次同步时间在2秒内就直接返回,否则主线程阻塞
对AOF追加阻塞的优化
不和其他高硬盘负载的服务部署在一起,如存储服务,消息队列服务等
AOF重写会消耗大量磁盘IO,可以开启配置no-appendfsync-on-rewrite,表示在AOF重写期间不做fsync,默认关闭
RDB-AOF混合持久化
先以RDB格式写入全量数据,再追加增量日志
这样既可以提高aofrewrite的恢复速度,也可以减少文件大小,还能保证数据完整性
Redis缓存设计
Redis内存理解和优化
复制
哨兵
集群