持久化
持久化:Redis中数据存储至文件保存到硬盘
1)后续启动可直接读取持久化文件,实现Redis状态的快速复现;
2)Redis持久化分为:RDB(数据快照)、AOF(命令日志)
如:Redis启动时持久化流程
//优先级:AOF文件 > RDB文件
RDB
RDB:将Redis进程中所有数据生成快照保存至文件
1)RDB只能生成特定时间点的数据快照(常用于备份和全量复制等);
2)RDB通过fork命令创建子进程,由子进程生成RDB文件;
//SAVE命令直接占用主线程,但会阻塞Redis(已弃用)
通过BGSAVE命令生成RDB文件的流程:
1)客户端发送BGSAVE命令至服务端;
2)服务端判断是否已有BGSAVE命令正在执行,有则拒绝请求(反之执行);
3)Redis主进程调用fork命令创建子进程(短暂阻塞);
4)子进程根据父进程内存生成数据快照;
5)完成后,发送相关信息至父进程;
//LASTSAVE可获取最后一次生成RDB文件的时间
如:RDB通过创建子进程生成RDB文件格式(BGSAVE命令)
//期间Redis线程仍可执行其他命令(不会阻塞)
RDB优点:
1)RDB文件由紧凑压缩的二进制格式存储数据;
2)Redis加载RDB文件恢复数据的速度快于AOF文件;
3)只在创建子进程时阻塞,其他时间仍可响应其他命令的执行请求;
RDB缺点:
1)RDB无法做到实时持久化/秒级持久化;
2)Redis不同版本之间的二进制格式存储不兼容;
3)每次持久化时都需创建子进程(重量级操作),执行成本较高;
实现
RDB文件实现分为:命令触发(手动触发)、自动触发、
1)RDB文件默认采用LZF算法进行压缩处理;
//可通过设置参数“rdbcompression”指定是否(yse/no)启动该功能
命令触发分为:SAVE命令、BGSAVE命令
(1)SAVE命令:阻塞服务端Redis,直到生成RDB文件
1)可用于数据较少的服务端(不建议在线上使用该命令);
(2)BGSAVE命令:创建子进程用于生成RDB文件
1)主线程调用fork命令生成子进程(会短暂阻塞);
2)子进程对当前主线程的数据生成快照,完成后返回相关信息至主线程;
3)Redis内部所有涉及RDB的操作均通过调用BGSAVE命令的方式实现;
常见自动触发场景:
1)使用“debug reload”命令重新加载Redis时,触发SAVE命令;
2)无AOF功能执行SHUTDOWN命令时,自动执行BGSAVE命令;
3)从节点执行全量复制时,Master节点执行BGSAVE命令生成RDB文件发送至Slave节点;
AOF
AOF(Append Only File):以独立日志记录Redis每次写/修改命令
1)AOF实现数据的实时持久化,但默认未开启;
//可通过设置参数“appendonly”指定是否(yse/no)启动该功能
如:AOF工作流程(AOF文件不能手动触发)
//通过AOF文件恢复节点状态时需先设置(使Redis不再进行AOF自动重写):auto-aof-rewrite-percentage和auto-aof-rewrite-min-size
同步策略
同步策略:Redis将AOF缓冲区中内容写入到文件
由配置参数“appendfsync”指定同步策略;
值 | 说明 |
---|---|
always | 当命令写入aof_buf后 立刻调用fsync系统操作同步到AOF文件 |
everysec (默认) | 当命令写入aof_buf后,先调用write系统操作 由其他线程每隔一秒调用fsync系统操作同步到AOF文件 |
no | 命令写入aof_buf后,只调用write系统操作 (由系统负责同步操作,一般为30秒) |
1)write系统操作:数据写入页缓冲区调用(同步文件前故障会导致数据丢失)
2)fsync系统操作:针对文件做强制硬盘同步,并阻塞直到写入硬盘完成为止
重写机制
重写机制:优化已有的AOF文件以缩小文件容量(删除无用数据)
1)本质:删除无用命令(过期)、合并相同作用的命令等
2)重写实现分为:命令触发(手动触发)、自动触发
//当部署多个Redis时,尽量保证同一时刻只有一个子进程执行重写
通过BGWRITEAOF命令重写AOF文件的流程:
1)客户端发送BGWRITEAOF命令至服务端;
2)Redis主进程调用fork命令创建子进程(短暂阻塞,后续仍响应);
3)fork根据写时复制机制复制父进程中内存数据;
4)子进程根据内存数据生成新AOF文件;
5)完成后,发送信号和相关信息至父进程;
6)父进程将该期间执行其他命令也写入新AOF文件;
7)替换旧AOF文件;
//批量写入文件中,由参数aof-rewrite-incremental-fsync指定,默认32MB
如:AOF重写流程
//命令触发和自动触发本质都在底层调用BGREWRITEAOF命令
//重写期间可暂时关闭fsync系统操作(参数no-appendfsync-on-rewrite)
命令触发:BGREWRITEAOF命令
(1)BGREWRITEAOF命令:BGREWRITEAOF
自动触发:
(1)超过AOF文件最小限制时:
1)由参数“auto-aof-rewrite-min-size
”指定,默认64MB;
2)字段“aof_current_size
”代表当前AOF文件大小;
(2)超过当前AOF文件大小和上一次AOF文件大小比值:
1)由参数“auto-aof-rewrite-percentage
”指定,默认值100;
2)字段“aof_base_size
”代表上一次AOF文件大小;
追加阻塞
当系统硬盘繁忙时,AOF可能会导致Redis主线程阻塞
1)仅适用于同步策略是everysec;
2)通过阻塞保证硬盘繁忙时,同步操作也可完成;
//保证Redis最多丢失2秒的数据;
Redis通过创建AOF线程执行fsync操作(数据同步到硬盘):
1)主线程将数据写入AOF缓冲区;
2)AOF线程每秒执行一次同步操作,并返回同步时间;
3)主线将当前时间和AOF线程返回的同步时间作比较;
4)若同步时间超过2秒,主线程将会被阻塞(反之,将略过);