Karp 的技术博客

服务器抛错, redis 持久化出了问题. 抛错如下:

Fatal error: Uncaught RedisException: MISCONF Redis is configured to save RDB snapshots, but it is currently not able to persist on disk. Commands that may modify the data set are disabled, because this instance is configured to report errors during writes if RDB snapshotting fails (stop-writes-on-bgsave-error option). Please check the Redis logs for details about the RDB error

翻译:

(错误)MISCONF Redis 已配置为保存 RDB 快照,但目前无法在磁盘上持久化。 可以修改数据集的命令被禁用,因为如果 RDB 快照失败(stop-writes-on-bgsave-error 选项),此实例被配置为在写入期间报告错误。 有关 RDB 错误的详细信息,请检查 Redis 日志。
抛错中 已经提供了解决方案 stop-writes-on-bgsave-error 参数调整为 no;

这个问题19年也是发生过的, 解决方案 Redis抛错:MISCONF Redis is configured to save RDB snapshots, but it is currently not able to.

下面找了个介绍的文章内容比较细.

Redis 可以将数据库快照保存在名为dump.rdb的二进制文件中。
RDB这种持久化方式被称为快照。

工作方式:

Redis调用forks,获得子进程 子进程将数据集写入到一个临时RDB文件中
当子进程完成对新RDB文件的写入时,Redis用新RDB文件替换原来的文件,并删除旧的RDB文件
这种工作方式使得Redis可以从copy-on-write机制中获益。(AOF的重写也利用了写时复制)
写时复制 是一种计算机程序设计领域的优化策略。核心思想是,如果有多个调用者同时要求相同资源,他们会共同获取相同的指针指向相同的资源,直到某个调用者试图修改资源的内容时,系统才会真正复制一份专用副本给该调用者,而其他调用者所见到的最初的资源仍然保持不变。这过程对其他的调用者都是透明的。此作法主要的优点是如果调用者没有修改该资源,就不会有副本被创建,因此多个调用者只是读取操作时可以共享同一份资源。

其实stop-writes-on-bgsave-error 在配置文件里在 快照 板块里。

默认情况下,如果启用了 RDB 快照(至少一个保存点)并且最新的后台保存失败,``将停止接受写入。
这将使用户意识到(以一种艰难的方式)数据没有正确地保存在磁盘上,否则很可能没有人会注意到并且会发生一些灾难。
如果后台保存过程将再次开始工作,Redis 将自动允许再次写入。
但是,如果您设置了对 Redis 服务器和持久性的适当监控,您可能希望禁用此功能,以便 Redis 继续照常工作,即使存在磁盘、权限等问题。

所以说简单将该选项设置为no很可能依然没有从本质上解决问题, 只是说就算发生错误我也依然备份。
其实在持久化出错时停止工作也是一种保护机制和提示。

我之后又将stop-writes-on-bgsave-error 设置为了yes, 但是再次加入KEY的时候, 没有报错。

理论上应该要看日志, 但是我这里大概可以猜测到应该是和内存有关, 因为我的服务器只有4G的内存, 大概是一时之间起了好几个程序, 内存空间不够fork的子进程

即使我有很多空闲 RAM,在 Linux 下后台保存也会因 fork() 错误而失败!
简短的回答:echo 1 > /proc/sys/vm/overcommit_memory:)

现在是长的:

Redis 后台保存模式依赖于现代操作系统中 fork 的写时复制语义:Redis fork(创建子进程)是父进程的精确副本。子进程将数据库转储到磁盘上并最终退出。理论上,子进程应该使用与作为副本的父进程一样多的内存,但实际上由于大多数现代操作系统实现的写时复制语义,父进程和子进程将共享公共内存页面。只有在子页面或父页面发生变化时,页面才会被复制。由于理论上所有页面都可能在子进程保存时发生变化,Linux 无法提前知道子进程将占用多少内存,因此如果overcommit_memory 设置为零 fork 将失败,除非有足够多的可用 RAM 来真正复制所有父内存页面,结果是如果您有 3 GB 的 Redis 数据集和只有 2 GB 的可用内存,它将失败。

设置overcommit_memory为 1 告诉 Linux 放松并以更乐观的分配方式执行 fork,这确实是Redis 想要的。

原文地址 : https://blog.csdn.net/qq_43178138/article/details/119144986

redis

版权属于:karp
作品采用:本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。
更新于: 2023年04月09日 21:22
1

目录

来自 《Redis持久化相关问题 ISCONF Redis is configured to save RDB snapshots》