【问题标题】:What could cause Redis RDB Snapshoting to Stall?什么可能导致 Redis RDB 快照停止?
【发布时间】:2016-02-24 19:11:22
【问题描述】:

我在 Ubuntu 14.04 上安装了 redis,我似乎几乎每周都会遇到 RDB 快照完成问题。 Redis版本是3.0.4 64位。

3838:M 2 月 24 日 09:46:28.826 * 后台保存成功终止
3838:M 2 月 24 日 09:47:29.088 * 100000 次变化在 60 秒内。保存...
3838:M 2 月 24 日 09:47:29.230 * 由 pid 17281 开始后台保存
17281:signal-handler (1456338079) 收到 SIGTERM 调度关闭...
3838:M 2 月 24 日 13:24:19.358 # 后台保存由信号 9 终止
3838:M 2 月 24 日 13:24:19.622 * 10 次更改在 900 秒内。保存...
3838:M 2 月 24 日 13:24:19.730 * 后台保存由 pid 17477 开始

您看到的是,在上午 9:47 开始后台保存,但是当我在下午 1:24 找到它时,它似乎完全停止了。我发现分叉的进程基本上没有活动——它消耗的内存量没有增加。我试图“杀死”子进程,但它从未真正退出,所以我不得不怀着极端的偏见(-9)杀死它。

当事情变得糟糕时,我的应用程序中出现以下错误:

2016-02-24 13:11:12,046 [2344] 错误 kCollectors.Main - 添加到 Redis 时出错:没有可用于服务此操作的连接:SADD ALLCH

我的 redis 配置是只做 rdb 快照(没有 AOF)。负载修改繁重,每秒写入数千次。

目前,我的 redis 后台保存没有成功,后台进程变得比常规进程大得多,以至于我的 VM 开始交换。这是我的TOP。 3838是我的redis实例,17477是后台保存进程(如上所述):

顶部 - 14:06:42 上升 118 天,2:05,1 个用户,平均负载:1.07、1.07、1.13
任务:总共 81 个,运行 3 个,睡眠 78 个,停止 0 个,僵尸 0 个
%Cpu(s): 0.8 us, 1.5 sy, 0.0 ni, 45.8 id, 51.3 wa, 0.0 hi, 0.5 si, 0.0 st
KiB 内存:总计 8176996,已使用 8036792,可用 140204,120 个缓冲区
KiB 交换:总共 6289404 个,已使用 3968236 个,免费 2321168 个。 4044 缓存内存

PID 用户 PR NI VIRT RES SHR S %CPU %MEM TIME+ 命令
36 根 20 0 0 0 0 S 2.3 0.0 288:05.05 kswapd0
3838 rrr 20 0 7791836 3.734g 612 S 2.0 47.9 330:08.65 redis 服务器
17477 rrr 20 0 7792228 6.606g 364 D 1.0 84.7 0:43.49 redis 服务器

【问题讨论】:

    标签: redis


    【解决方案1】:

    这很有趣,因为我不记得读过此类问题,因此发现根本原因可能非常有用。

    因此,您在这里报告了一个长时间处于活动状态,甚至继续分配内存的子进程。如果不是进程内存中的数据损坏,我对此没有任何解释,导致 RDB 进程发现意外情况并以某种方式永远循环。

    几个问题:

    1. 即使重新启动进程也会发生这种情况吗? (但是,如果您可以避免重新启动并且尚未重新声明,请不要这样做,否则我们可能不再了解根本原因。
    2. 当 RDB 保存处于活动状态时,您是否看到 CPU 使用率很高并且进程使用 ps/top 运行?
    3. 能否尝试使用gdb -p <pid> 中断进程并获取进程的堆栈跟踪?
    4. 能否提供 Redis INFO 输出来检查版本和其他配置内容和状态?
    5. 发生这种情况时您能检查free 的输出吗?

    TLDR:系统是否可能内存不足并且交换了很多内容?因此,子进程在保存 RDB 文件时访问了所有页面并强制所有内容都在驻留集中。系统无法处理如此多的 I/O,因此需要很长时间才能完成 RDB 保存。

    编辑:我刚刚注意到你报告了内存信息:

    KiB 内存:总共 8176996 个,已使用 8036792 个,可用 140204 个,120 个缓冲区

    所以系统内存不足并且正在疯狂地交换,这导致了上述行为。随着 RDB 开始保存,COW 将使用大量额外内存,将服务器推向内存限制。

    谢谢。

    【讨论】:

    • 内存统计数据来自 rdb 子进程运行一段时间后。它并不是从交换状态开始的——事实上,它远非如此。它在编写 rdb 大约 10-15 分钟后进入该状态。关于是否在重新启动进程后发生,您的意思是重新启动子进程还是重新启动父进程?我之前重新启动了孩子,它最终处于相同的状态。我最终不得不关闭我的整个 redis 并让它重新启动。 Cpu 永远不会很高——永远不会超过 10%。明天我会尝试获取redis信息(虽然我给出了版本)
    • 顺便说一句...我看到你是 redis 上帝 :-) 非常感谢你的回答。当它再次发生时,我一定会尽可能多地捕捉。如果我进行捕获交换,答案是否只是添加内存?我觉得这是一个愚蠢的问题,但我觉得有必要问……我的 IT 人员讨厌这个东西已经这么大了。我知道我可以启动一个集群,但我必须至少多站 2 个节点才能减少每个节点的大小,因此我们场中的总内存占用显着增加......
    • @longofest 8G 现在对于服务器来说真的不是很多 RAM。我的笔记本电脑运行两倍。
    • @Not_a_Golfer 哦,我同意。但很难说服 IT 部门。
    • 又抓到了,确实,我的服务器正在交换。感谢您的反馈。
    猜你喜欢
    • 2013-11-04
    • 2017-01-08
    • 2020-06-29
    • 2020-01-23
    • 2010-11-15
    • 1970-01-01
    • 1970-01-01
    • 2016-02-29
    • 1970-01-01
    相关资源
    最近更新 更多