Redis持久化
本文为redis学习笔记的第五篇文章。redis处理数据都是在内存中进行,所以速度特别快,同样,它也可以支持持久化,这里注意,并不是说redis要来充当mysql那种角色,其实更多的是为了在崩溃的时候快速恢复以及主从复制这样的功能。redis的持久化主要有两种方式,一种是RDB,一种是AOF,对于他们的原理和区别都是比较重要的面试考察点,需要掌握。
1. 什么是持久化
redis
所有数据保持在内存中,对数据的更新将异步地保存到磁盘中。
2. 持久化的方式
快照—mysql dump
或者redis rdb
写日志—mysql binlog
或者hbase glog
或者redis aof
3. RDB
什么是RDB
触发机制三种主要方式
- save(同步持久化,会造成redis主线程的阻塞,不推荐使用)
save
是同步的,当保存的数据量很大时,可能造成redis
的阻塞,即客户端访问redis
被阻塞。
他的文件策略是:如果存在老的RDB
文件,则新的替换老的。复杂度为O(n)
。
- bgsave(异步,fork一个子进程来进行持久化,不会造成主线程的阻塞)
一般情况下,fork
是比较快的,但是也可以会慢,这时会阻塞redis
。只要fork
不慢,客户端不会被阻塞。
他的文件策略和复杂度与save是一样的。
save
和bgsave
两者对比:
- 自动
redis
的自动保存的默认配置是:
配置 | seconds | changes |
---|---|---|
save | 900 | 1 |
save | 300 | 10 |
save | 60 | 10000 |
就是说,在60秒内改变了10000条数据,就自动保存;在300秒内有10条改变才自动保存;900秒内有1一条改变就保存。
RDB总结
RDB
是Redis
内存到硬盘的快照,用于持久化。save
通常会阻塞redis
。bgsave
不会阻塞redis
,但是会fork
新进程。save
自动配置满足任一就会被执行。- 有些触发机制不容忽视。
4. AOF
RDB问题
- 全量数据存入磁盘
O(n)
数据的备份,很耗时间;对于bgsave
来说,fork()
是一个很消耗内存的操作;将数据全写到硬盘,必然对硬盘IO占用很大。
- 宕机丢失数据多
还有一点是:某个时间点宕机,那么在某个时间段的数据就丢失了。
AOF原理
将对redis
的操作追加到aof
文件中。当redis
宕机之后,使用aof
恢复所有的操作继而实现数据的恢复。
AOF三种策略
- always
- everysec
redis
出现故障,有可能丢失一秒的数据。redis
默认方式。
- no
三种策略的比较
AOF重写
好处是:减少硬盘占用、减少数据丢失
下面是AOF的bgrewirteaof
的过程:
注意:这里的重写并不是上面演示的,将原来的aof
文件进行重写,而是根据redis
现在的内存数据进行一次回溯。
aof重写流程
也就是说,子进程在执行 AOF 重写时,主进程需要执行以下三个工作:
- 1.处理命令请求;
- 2.将写命令追加到现有的 AOF 文件中;
- 3.将写命令追加到 AOF 重写缓存中。
如此可以保证:
- 现有的AOF功能继续执行,即使 AOF 重写期间发生停机,也不会有任何数据丢失;
- 所有对数据库进行修改的命令都会被记录到 AOF 重写缓存中。
当子进程完成对 AOF 文件重写之后,它会向父进程发送一个完成信号,父进程接到该完成信号之后,会调用一个信号处理函数,该函数完成以下工作:(阻塞)
- 将 AOF 重写缓存中的内容全部写入到新的 AOF 文件中;(现有 AOF 文件、新的 AOF 文件和数据库三者的状态就完全一致了)
- 对新的 AOF 文件进行改名,覆盖原有的 AOF 文件。(执行完毕后,程序就完成了新旧两个 AOF 文件的替换)
当这个信号处理函数执行完毕之后,主进程就可以继续像往常一样接收命令请求了。在整个 AOF 后台重写过程中,只有最后的“主进程写入命令到AOF缓存”和“对新的 AOF 文件进行改名,覆盖原有的 AOF 文件”这两个步骤会造成主进程阻塞,在其他时候, AOF 后台重写都不会对主进程造成阻塞,这将 AOF 重写对性能造成的影响降到最低。
小结:
- AOF 重写的目的是轻量地保存数据库状态,整个重写过程基本上不影响 Redis 主进程处理命令请求;
- AOF在redis宕机的时候最多丢失一秒的数据,比RDB要好一点,并且可读性高,基本上能看得懂
- AOF 重写其实是一个有歧义的名字,实际上重写工作是针对数据库的当前值来进行的,重写过程中不会读写、也不适用原来的 AOF 文件;
- AOF 可以由用户手动触发,也可以由服务器自动触发。
5. 持久化的取舍和选择
RDB和AOF对比
可以看出,世界上没有完美的东西,只有合适的东西。AOF同样存在一些问题:AOF文件的体积通常要大于RDB文件的体积、且恢复速度慢。
RDB最佳策略
“关”:建议关闭,但是后面主从复制功能是需要他的,因为需要主节点执行dbsave
,然后将rdb
文件传给从节点。所以说,关不是永久关。
“集中管理”:虽然RDB
很重,但是对于数据备份是很重要的,按照小时或者天集中地进行备份比较好,因为他的文件很小,利于传输。
“主从,从开”:有时候从节点打开这个功能是比较好的,但是备份太频繁,取决于实际的场景。
AOF最佳策略
- “开”:建议打开,如果仅仅是作为一个普通缓存,对于数据要求不是很高,这次数据丢了,下次可以从数据库取(数据库压力不是很大),这种情况就建议关闭,因为
AOF
还是有性能开销的。 - “everysec”
Redis4
Redis 4.0
新增了 RDB-AOF
混合持久化格式, 这是一个可选的功能,
在开启了这个功能之后, AOF
重写产生的文件将同时包含 RDB
格式的内容和 AOF
格式的内容, 其中 RDB
格式的内容用于记录已有的数据, 而 AOF
格式的内存则用于记录最近发生了变化的数据, 这样 Redis
就可以同时兼有 RDB
持久化和 AOF
持久化的优点 —— 既能够快速地生成重写文件, 也能够在出现问题时, 快速地载入数据。
RDB和AOF共存的情况下如何恢复数据:
- 优点:
- 混合持久化结合了
RDB
持久化 和AOF
持久化的优点, - 由于绝大部分都是
RDB
格式,加载速度快,同时结合AOF
,增量的数据以AOF
方式保存了,数据更少的丢失。
- 混合持久化结合了
- 缺点:
- 兼容性差,一旦开启了混合持久化,在4.0之前版本都不识别该
aof
文件,同时由于前部分是RDB
格式,阅读性较差
- 兼容性差,一旦开启了混合持久化,在4.0之前版本都不识别该
策略是: