Redis持久化
1、Redis 持久化的三种方式
1、RDB: 以快照的方式将此刻 Redis 中的数据以二进制的文件形式保存在磁盘中。
RDB 的优点是:快照文件小、恢复速度快,适合做备份和灾难恢复。
RDB 的缺点是:定期更新可能会丢数据(在最后一次数据快照到服务器宕机之间的数据就会丢失)
2、AOF: AOF 是将 Redis 的所有写操作追加到 AOF 文件 (Append Only File)的结尾,从而记录了 Redis 服务器运行期间所有修改操作的详细记录。当 Redis 重新启动时,可以通过执行 AOF 文件中保存的写操作来恢复数据。
AOF 的优点是:可以实现更高的数据可靠性、支持更细粒度的数据恢复,适合做数据存档和数据备份。
AOF 的缺点是:文件大占用空间更多,每次写操作都需要写磁盘导致负载较高
3、混合模式: 在开启混合持久化的情况下,AOF 重写时会把 Redis 的持久化数据,以 RDB 的格式写入到 AOF 文件的开头,之后的数据再以 AOF 的格式化追加的文件的末尾。
优点:解决了上述 RDB 和 AOF 的缺点
缺点:Redis 4.0 之后才支持,对低版本的不兼容
2、RDB 的执行流程
RDB 的流程:
1、当 Redis 进行 RDB 快照的时候,主进程 fork 出一个子进程。
2、子进程会把页表复制一份,真正的数据还在内存上也就是主进程和子进程共用的数据。
3、子进程将此时物理内存中的数据写入到磁盘中替换掉原来的 RDB 文件。
但是此时如果有请求来修改数据,而子进程在读和写数据到磁盘中,那么此时就会有脏读问题。
fork 采用的是 copy-on–write 技术:
- 当主进程在读的时候,访问共享内存
- 当主进程正在写的时候,会拷贝一份数据副本,进行写操作。
fork 操作之后再把数据副本覆盖到数据上。
3、AOF 的三种写策略
AOF 有三种数据写回策略,分别是 Always, Everyseci 和 No。
- Awys, 同步写回:每个写命令执行完,立马同步地将日志写回磁盘;
- Everysec 每秒写回:每个写命令执行完,只是先把日志写到 AOF 文件的内存缓冲区,每隔一秒把缓冲区中的内容写入磁盘:
- No, 操作系统控制的写回:每个写命令执行完,只是先把日志写到 AOF 文件的内存缓冲区,由操作系统决定何时将缓冲区内容写回磁盘。
“同步写回”可靠性肯定是最高的,但是它在每一个写命令后都有一个落盘操作,而且还是同步的,这和直接写磁盘类型的数据库有啥区别?
"操作系统控制的写回"这种是最不靠谱的,谁知道操作系统啥时候帮你做持久化,万一没来及持久化就宕机了,不就 gg 了。
"每秒写回"是在二者之间折中了一下,异步的每秒把数据写会到磁盘上,最大程度的提升效率和降低风险。也是实际开发中使用最多的策略
4、AOF 无用写命令问题:
因为 AOF 中一条数据可能多次的写操作,只有最后一次有意义,
比如:set name 1 set name 2 set name 3 这三条命令,在恢复数据的时候只有最后一条数据有意义,如果上述无意义的写操作非常多,就会导致 AOF 的文件臃肿大多数据都是无用的。
解决方法:bgrewriteaof 命令
可以让 AOF 文件执行重写,擦去无用的写操作。
Redis 也会在触发阈值时自动去重写 AOF 文件。阈值也可以在 redis.conf 中配置:
# AOF 文件比上次文件增长超过多少百分比则触发重写
auto-aof-rewrite-percentage 100
# AOF文件体积最小多大以上才触发重写
auto-aof-rewrite-min-size 64 mb