LabHub
学习 学习路径 课程

Redis 与缓存

RDB、AOF,以及可以丢的东西

在 LabHub 中继续学习

一句话总结

永续性设置是对“可以失去几秒钟的值吗”的问题的回答。如果答案是“一点也不可以”,那么应该重新考虑Redis是否是正确的工具。

概念图: 将两者同时打开是基本型 · fork子进程 · 内存会增加两倍 · 存储本身失败

为什么需要这个?

Redis是内存存储库。进程死亡时,内存就会消失。所以提供了两种永存性方式。

RDB是周期性快照。设置例子如下save 3600 1save 300 100save 60 10000—如果一个小时内更改1件以上,5分钟内更改100件,1分钟内更改10000件,则会弹出快照。优点是只有一个文件,所以备份和恢复简单,重启速度快。缺点是最后一个快照之后的所有写入都丢失。

AOF将所有写入命令都记录在日志中。appendfsync everysec这是这个实务的基本值,在最坏的情况下会失去1秒钟。always设置为则几乎不会丢失,但每次写入都会处理量大幅下降,因为会被处理为fsync。no交给OS的话,丢失区间会变大。

怎么行动

实际操作的标准是同时使用两个的混合模式。打开AOFaof-use-rdb-preamble yes这样做的话,在AOF重写时,将前部分以RDB格式保存,然后加上增量命令。恢复速度快,丢失区间也保持在1秒以内。

Redis 7的Multi-Part AOF进一步整理了这一点,将base文件和incr文件分放在专用目录中。重新加载时磁盘空间翻倍的问题减少了。

这里有一个诚实的地方。即使打开永续性,Redis也不是数据库。复制是异步的,所以主进程死掉时,可能会有写入操作无法到达副本。WAIT虽然可以通过命令部分改进,但不是完全同步复制。因此,不适合作为“绝对不能丢失”数据的1次存储库。

在现场相遇的样子

经常低估fsync的成本。appendfsync always更换为后者的情况下,处理量下降到一半以下的报告很常见。在磁盘速度慢的环境中,AOF写入会被推迟,主线程也会被阻塞。

RDB快照也不是免费的。fork创建一个子进程来显示快照,由于copy-on-write,如果写入量大,内存会瞬间大幅增加。4GB的实例会在快照中使用6GB。如果maxmemory正好与物理内存匹配,此时就会发生OOM。通常将物理内存的一半左右设定为maxmemory。

把两种方式并排放在一起的话

RDB(快照) AOF(命令日志)
保存 那个时刻的全部数据 按顺序排列更改的命令
文件大小 小(压缩的二进制) 大(通过重构缩小)
重新启动速度 慢(重新执行命令)
最糟糕的遗失 最后快照之后全部 appendfsync附上
负载 fork 瞬间内存爆满 虽然继续使用,但很温和

appendfsync是AOF的核心手柄。

always    쓸 때마다 fsync — 거의 안 잃지만 아주 느리다
everysec  1초마다 fsync — 최악 1초 유실. 사실상 표준
no        OS 에 맡김 — 빠르지만 몇 초를 잃을 수 있다

将两者同时打开是基本型。用AOF保持到最近1秒,用RDB快速 获取恢复和备份文件。Redis在重新启动时,如果有AOF,会优先使用它。 写。

fork制造的内存急剧增加

RDB快照和AOF重写是通过fork子进程进行的。Linux的 多亏了copy-on-write,虽然一开始会共享内存,但存储期间父节点会更改的 每个页面都会生成副本。

在使用量很大的瞬间,如果Snapchat重叠的话,内存会增加两倍。容器 因超出限额而以OOM死亡的事故就发生在这里。

maxmemory 4gb          ← 데이터 상한
컨테이너 한도 6~8gb     ← fork 여유를 남긴다

vm.overcommit_memory = 1推荐的理由也是这个。如果这个值为0,则内核 因为“内存好像不够”而拒绝fork,存储本身失败。Redis是 虽然在日志上留下警告,但很容易被忽视。

先决定可以失去什么

最常见的错误是打开持续性。不必要的fork成本和 删除磁盘I/O后,实际恢复时旧的缓存会复活,造成问题。

在下次确认中看到的东西

更改永续性设置可能会影响实训板的其他实训,因此用测验代替。确认RDB·AOF的丢失范围和恢复成本是否可以按情况区分,然后完成课程。