Redis持久化机制
为什么要持久化
如果Redis再次访问时,发现Redis的数据是空的,就会形成缓存穿透。更重要的是,因为Redis的数据是空的,所以客户端想要访问的key都没有,就会造成大量的请求就会瞬间打到数据库上,造成缓存雪崩(少量的key是穿透,大量的key是雪崩)。这个时候,数据库可能就挂掉。而又无法保证redis不宕机,所以需要当redis宕机后,迅速将里里面的内容恢复出来。因此需要做一个持久化。持久化是为了恢复数据用的,而不是存储数据用的
RDB
RDB(Redis DataBase),是Redis默认的存储方式,RDB方式是通过快照(snapshotting)完成的。
触发快照的方式
符合自定义配置的快照规则
-
save 900 1 # 表示15分钟(900秒钟)内至少1个键被更改则进行快照。
-
save 300 10 # 表示5分钟(300秒)内至少10个键被更改则进行快照。
-
save 60 10000 # 表示1分钟内至少10000个键被更改则进行快
N秒内数据集至少有M个改动”这一条件被满足时,自动保存一次数据集。
执行save或者bgsave命令
执行命令save或bgsave可以生成dump.rdb文件,每次命令执行都会将所有redis内存快照到一个新的rdb文件里,并覆盖原有rdb快照文件。
save与bgsave对比:
命令 | save | bgsave |
---|---|---|
IO类型 | 同步 | 异步 |
是否阻塞redis其它命令 | 是 | 否(在生成子进程执行调用fork函数时会有短暂阻塞) |
复杂度 | O(n) | O(n) |
优点 | 不会消耗额外内存 | 不阻塞客户端命令 |
缺点 | 阻塞客户端命令 | 需要fork子进程,消耗内存 |
配置自动生成rdb文件后台使用的是bgsave方式。
执行flushall命令
flushall
复制代码
清空Redis之前,保存当前Redis快照
执行主从复制操作 (第一次)
第一次主从复制时需要生成rdb文件,会保存当前Redis快照
RDB执行流程
-
流程分析
-
- Redis父进程首先判断:当前是否在执行save或bgsave/bgrewriteaof(aof文件重写命令)的子进程,如果在执行则bgsave命令直接返回。
-
- 父进程执行fork(调用操作系统函数复制主进程)操作创建子进程,这个过程中父进程是阻塞的,Redis不能执行来自客户端的任何命令。
-
- 父进程fork后,bgsave命令返回”Background saving started”信息并不再阻塞父进程,并可以响应其他命令。
-