4)RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快 。
RDB 的缺点:
1)RDB 在服务器故障时容易造成数据的丢失 。RDB 允许我们通过修改 save point 配置来控制持久化的频率 。但是,因为 RDB 文件需要保存整个数据集的状态,所以它是一个比较重的操作,如果频率太频繁,可能会对 Redis 性能产生影响 。所以通常可能设置至少5分钟才保存一次快照,这时如果 Redis 出现宕机等情况,则意味着最多可能丢失5分钟数据 。
2)RDB 保存时使用 fork 子进程进行数据的持久化,如果数据比较大的话,fork 可能会非常耗时,造成 Redis 停止处理服务N毫秒 。如果数据集很大且 CPU 比较繁忙的时候,停止服务的时间甚至会到一秒 。
3)Linux fork 子进程采用的是 copy-on-write 的方式 。在 Redis 执行 RDB 持久化期间,如果 client 写入数据很频繁,那么将增加 Redis 占用的内存,最坏情况下,内存的占用将达到原先的2倍 。刚 fork 时,主进程和子进程共享内存,但是随着主进程需要处理写操作,主进程需要将修改的页面拷贝一份出来,然后进行修改 。极端情况下,如果所有的页面都被修改,则此时的内存占用是原先的2倍 。
相关源码在 rdb.c,核心方法是:rdbSaveBackground、rdbSave
AOF的实现原理、优缺点
描述:保存 Redis 服务器所执行的所有写操作命令来记录数据库状态,并在服务器启动时,通过重新执行这些命令来还原数据集 。
开启:AOF 持久化默认是关闭的,可以通过配置:appendonly yes 开启 。
关闭:使用配置 appendonly no 可以关闭 AOF 持久化 。
AOF 持久化功能的实现可以分为三个步骤:命令追加、文件写入、文件同步 。
命令追加:当 AOF 持久化功能打开时,服务器在执行完一个写命令之后,会将被执行的写命令追加到服务器状态的 aof 缓冲区(aof_buf)的末尾 。
文件写入与文件同步:可能有人不明白为什么将 aof_buf 的内容写到磁盘上需要两步操作,这边简单解释一下 。
Linux 操作系统中为了提升性能,使用了页缓存(page cache) 。当我们将 aof_buf 的内容写到磁盘上时,此时数据并没有真正的落盘,而是在 page cache 中,为了将 page cache 中的数据真正落盘,需要执行 fsync / fdatasync 命令来强制刷盘 。这边的文件同步做的就是刷盘操作,或者叫文件刷盘可能更容易理解一些 。
在文章开头,我们提过 serverCron 时间事件中会触发 flushAppendOnlyFile 函数,该函数会根据服务器配置的 appendfsync 参数值,来决定是否将 aof_buf 缓冲区的内容写入和保存到 AOF 文件 。
appendfsync 参数有三个选项:
1)always:每处理一个命令都将 aof_buf 缓冲区中的所有内容写入并同步到AOF 文件,即每个命令都刷盘 。
2)everysec:将 aof_buf 缓冲区中的所有内容写入到 AOF 文件,如果上次同步 AOF 文件的时间距离现在超过一秒钟,那么再次对 AOF 文件进行同步,并且这个同步操作是异步的,由一个后台线程专门负责执行,即每秒刷盘1次 。
3)no:将 aof_buf 缓冲区中的所有内容写入到 AOF 文件,但并不对 AOF 文件进行同步,何时同步由操作系统来决定 。即不执行刷盘,让操作系统自己执行刷盘 。
AOF 的优点
1)AOF 比 RDB可靠 。你可以设置不同的 fsync 策略:no、everysec 和 always 。默认是 everysec,在这种配置下,redis 仍然可以保持良好的性能,并且就算发生故障停机,也最多只会丢失一秒钟的数据 。
2)AOF文件是一个纯追加的日志文件 。即使日志因为某些原因而包含了未写入完整的命令(比如写入时磁盘已满,写入中途停机等等),我们也可以使用 redis-check-aof 工具也可以轻易地修复这种问题 。
3)当 AOF文件太大时,Redis 会自动在后台进行重写:重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合 。整个重写是绝对安全,因为重写是在一个新的文件上进行,同时 Redis 会继续往旧的文件追加数据 。当新文件重写完毕,Redis 会把新旧文件进行切换,然后开始把数据写到新文件上 。
4)AOF 文件有序地保存了对数据库执行的所有写入操作以 Redis 协议的格式保存,因此 AOF 文件的内容非常容易被人读懂,对文件进行分析(parse)也很轻松 。如果你不小心执行了 FLUSHALL 命令把所有数据刷掉了,但只要 AOF 文件没有被重写,那么只要停止服务器,移除 AOF 文件末尾的 FLUSHALL 命令,并重启 Redis,就可以将数据集恢复到 FLUSHALL 执行之前的状态 。
推荐阅读
- 富春山居图是中国十大传名画之一这幅画的作者是 富春山居图是中国十大传世名画之一这幅画的作者是什么
- 聊聊golang的zap的ReflectType
- 端午节又称什么 端午节的别称分别是什么
- 提高微服务安全性的11个方法
- 绿茶的保质期,红茶的保质期
- 8款药膳花茶,茶药膳疗法对保健起着不可忽视的作用
- 白福鼎老白茶价格,白茶的价格
- 老公眼里觉得你很“贱”的7个举动
- 男人不同时期想要的女人
- 女人单身太久的十大负面表现
