4.redis持久化
1.持久化概念:
redis支持 将内存中的数据持久化到磁盘中,在下次启动redis时可以将磁盘中的数据加载到内存中
2.持久化通用的两种方式:
- 快照(某一时刻对数据的备份)
例如:mmysql dump redis RDB - 记录日志()
例如:Mysql binlog Hbase Hlog redis AOF
3.redis持久化之 RDB(redis database)
①RDB概念:
②触发机制-主要三种方式:
1) save(同步)
2)bgsave(异步)
3)自动
save与bgsave
IO类型 | 同步 | 异步 |
阻塞? | 是 | 否(阻塞发生在forkl) |
复杂度 | O(n) | O(n) |
优点 | 不会消耗额外内存 | 不阻塞客户端命令 |
缺点 | 阻塞客户端命令 | 需要fork,消耗内存 |
自动生成RDB
save | 900 | 1 |
save | 300 | 10 |
save | 60 | 10000 |
释义:
60秒改变10000次,会采用bgsave方式生成RDB文件
300秒改变10次,会自动生成RDB文件
③RDB配置相关
save | save 900 1 | RDB自动配置,可配置多组,不配置可取消自动RDB |
dbfilename | dump-${port}.rdb | RDB文件名 |
dir | ./ | RDB文件AOF文件及日志文件存放路径 |
stop-writes-on-bgsave-error | yes | bgsave生成RDB文件出错时是否停止 |
rdbcompression | yes | RDB文件是否采用压缩 |
rdbchecksum | yes | 是否对RDB文件校验和校验 |
④可能忽略RDB触发机制
全量复制
debug reload
shutdown
RDB存在问题:
① 耗时、耗性能
复杂度为o(n),save时内存数据dump到磁盘:耗时
bgsave时,fork()阶段采用copy-on-write策略,会比较耗内存
dump到文件造成io开销
②不可控,丢失数据
T1 | 执行多个命令 |
T2 | 满足RDB自动创建条件 |
T3 | 再次执行多个命令 |
T4 | 宕机 |
在T4时刻redis出现宕机,会导致T3-T4时刻的数据丢失
如何解决? 请看下一节AOF持久化方式吧
4.redis持久化之AOF(Append-only file)
client每次请求redis,都会将写请求的命令保存到文件中,
①AOF三种策略
① always
只要缓冲区有数据 立马写入文件中
②everysec
每隔一秒将数据从缓冲区写入文件中
③no
写文件的操作交由操作系统控制
AOF三种策略比较
优点 | 不丢失数据 | 每秒一次fsync只丢失1秒数据 | >交由操作系统fsync,不用管 |
缺点 | 磁盘开销较大,一般sata磁盘一秒只有几百TPS | 丢失1秒数据 | 交由操作系统fsync,不可控 |
总结:
是业务情况,场景而定,一般可以使用everysec,在磁盘开销及数据丢失情况取个折中
②AOF重写
引入原因:
随着数据的不断写入,会造成AOF文件不断增大,重复的命令会额外占用磁盘空间,而是增加redis重启速度
AOF重写定义:
AOF文件重写不是对原有AOF文件进行读取分析,而是读取最新的数据进行分析实现的。
AOF重写作用:
1.减少磁盘占用量
2.加速恢复速度
AOF重写实现两种方式
1.bgrewriteaof
2.AOF重写配置
bgwriteaof命令
AOF重写配置
auto-aof-rewrite-min-size | AOF文件重写需要尺寸(单位:字节) |
auto-aof-rewrite-percentage | AOF文件增长率 |
aof_current_size | AOF当前尺寸(单位:字节) |
aof_base_size | AOF上次启动和重写的尺寸(单位:字节) |
重写触发时机
1.aof_current_size>auto-aof-rewrite-min-size
2.(aof_current_size - aof_base_size)/aof_base_size > auto-aof-rewrite-percentage
AOF重写流程
注:
aof_rewrite是在子进程执行,子进程带有主进程数据副本,不会阻塞客户端请求
子进程在AOF重写期间,主进程依然需要会记录数据变化日志,就会出现当前数据与AOF重写之后的数据不一致
解决方案:
redis增加了一个aof_rewrite_buf(aof重写缓冲区),当主进程fork出子进程后开始启用,此时主进程需要将日志同时记录到aof_buf(aof缓冲区)与aof_ewrite_aof(aof重写缓冲区),当子进程重写完数据后给主进程发送信号,此时 主进程通过信号处理函数将aof_rewrite_buf数据追加到新aof文件后,替换旧aof文件
aof相关配置
appendonly | yes | aof启用开关 |
appendfilename | appendonly-${port}.aof | aof文件名 |
appendfsync | everysec | aof持久策略 |
dir | ./data | 数据存放路径 |
no-appendfsync-on-rewrite | yes | aof重写期间主进程是否继续讲日志从缓冲区刷新到旧日志文件(上图aof_buf-<旧aof文件) |
auto_aof_rewrite_percentage | 100 | 文件增长率 |
auto-aof-rewrite-min-size | 64mb | aof重写需要的文件尺寸 |
5.总结
①redis存在AOF与RDB两种持久化方式
如果redis宕机或重启时想要恢复数据,会优先采用哪种方式恢复数据呢?
AOF与RDB同时开启时,会优先使用AOF恢复数据,如果采用RDB恢复数据,可以先将AOF关闭,appendonly no,重启完成后,执行config set appendonly yes动态开启AOF