文档:诊断延迟问题

此页面正在审查中。此页面可能不正确,包含无效链接,和/或需要技术审查。未来它可能会有重大更改或被完全删除。


本文档将帮助您了解在使用 Valkey 时遇到延迟问题可能是什么原因。

在此上下文中,延迟是指客户端发出命令到客户端收到命令回复之间的最大延迟。通常 Valkey 的处理时间极低,在亚微秒范围内,但某些条件会导致更高的延迟数据。

我时间不多,请给我清单

以下文档对于以低延迟方式运行 Valkey 非常重要。但我理解我们都很忙,所以让我们从一个快速清单开始。如果您未能遵循这些步骤,请返回此处阅读完整文档。

  1. 确保您没有运行阻塞服务器的慢命令。使用 Valkey 的 Slow Log 功能来检查这一点。
  2. 对于 EC2 用户,请确保您使用基于 HVM 的现代 EC2 实例,如 m3.medium。否则 fork() 会太慢。
  3. 透明大页(Transparent Huge Pages)必须在您的内核中禁用。使用 echo never > /sys/kernel/mm/transparent_hugepage/enabled 来禁用它们,并重启您的 Valkey 进程。
  4. 如果您正在使用虚拟机,可能存在与 Valkey 无关的固有延迟。使用 ./valkey-cli --intrinsic-latency 100 检查您的运行时环境可以预期的最小延迟。注意:您需要在服务器而不是客户端上运行此命令。
  5. 启用并使用 Valkey 的 Latency monitor 功能,以便获得您 Valkey 实例中延迟事件和原因的人类可读描述。

一般来说,请使用下表来权衡持久性与延迟/性能,按从更强安全性到更好延迟的顺序排列。

  1. AOF + fsync always:这非常慢,您应该只在了解其作用时才使用它。
  2. AOF + fsync every second:这是一个很好的折衷方案。
  3. AOF + fsync every second + no-appendfsync-on-rewrite 选项设置为 yes:这与上述相同,但避免在重写期间执行 fsync 以降低磁盘压力。
  4. AOF + fsync never。在此设置中,fsync 由内核负责,甚至磁盘压力和延迟峰值的风险都更小。
  5. RDB。在这里,您根据配置的保存触发器有广泛的权衡选择。

现在,对于有 15 分钟时间的人,以下是详细信息...

测量延迟

如果您遇到延迟问题,您可能知道如何在应用程序上下文中测量它,或者您的延迟问题甚至在宏观上都非常明显。然而,valkey-cli 可以用于以毫秒为单位测量 Valkey 服务器的延迟,只需尝试

valkey-cli --latency -h `host` -p `port`

使用 Valkey 内部延迟监控子系统

Valkey 提供了延迟监控功能,能够采样不同的执行路径以了解服务器在哪里阻塞。这使得调试本文档中说明的问题变得简单得多,因此我们建议尽快启用延迟监控。请参阅 Latency monitor 文档

虽然延迟监控的采样和报告功能将使您更容易理解 Valkey 系统中的延迟来源,但仍建议您广泛阅读本文档,以更好地理解 Valkey 和延迟峰值的主题。

延迟基线

有一种延迟是您运行 Valkey 的环境固有的,即由您的操作系统内核提供的延迟,如果您正在使用虚拟化,则是由您使用的管理程序提供的延迟。

虽然这种延迟无法消除,但研究它很重要,因为它是基线,换句话说,您无法实现比环境中每个进程因内核或管理程序实现或设置而经历的延迟更好的 Valkey 延迟。

我们将这种延迟称为固有延迟(intrinsic latency),并且 valkey-cli 能够测量它。这是一个运行示例。

注意:参数 100 是测试将执行的秒数。我们运行测试的时间越长,越有可能发现延迟峰值。100 秒通常是合适的,但您可能希望在不同时间执行几次运行。请注意,此测试是 CPU 密集型的,可能会使您系统中的单个核心饱和。

$ ./valkey-cli --intrinsic-latency 100
Max latency so far: 1 microseconds.
Max latency so far: 16 microseconds.
Max latency so far: 50 microseconds.
Max latency so far: 53 microseconds.
Max latency so far: 83 microseconds.
Max latency so far: 115 microseconds.

注意:在这种特殊情况下,valkey-cli 需要在您运行或计划运行 Valkey 的服务器上运行,而不是在客户端上。在这种特殊模式下,valkey-cli 完全不连接到 Valkey 服务器:它只会尝试测量内核不向 valkey-cli 进程本身提供 CPU 时间的最长时间。

在上面的示例中,系统的固有延迟仅为 0.115 毫秒(或 115 微秒),这是一个好消息,但请记住,固有延迟可能会根据系统负载随时间变化。

在负载较高或存在“吵闹邻居”(noisy neighbors)的虚拟化环境中,您可能会得到这样的数字

$ ./valkey-cli --intrinsic-latency 100
Max latency so far: 573 microseconds.
Max latency so far: 695 microseconds.
Max latency so far: 919 microseconds.
Max latency so far: 1606 microseconds.
Max latency so far: 3191 microseconds.
Max latency so far: 9243 microseconds.
Max latency so far: 9671 microseconds.

这里我们有 9.7 毫秒的固有延迟:这意味着我们无法要求 Valkey 表现得更好。然而,在不同虚拟化环境中,负载更高或有“吵闹邻居”的情况下,在不同时间进行的测试很容易显示出更差的值。我们能够在其他方面看似正常运行的系统中测量到高达 40 毫秒的延迟。

网络和通信引起的延迟

客户端使用 TCP/IP 连接或 Unix 域连接到 Valkey。1 吉比特/秒网络的典型延迟约为 200 微秒,而 Unix 域套接字的延迟可低至 30 微秒。这实际上取决于您的网络和系统硬件。除了通信本身,系统还会增加一些额外的延迟(由于线程调度、CPU 缓存、NUMA 位置等)。在虚拟化环境中,系统引起的延迟显著高于物理机。

结果是,即使 Valkey 在亚微秒范围内处理大多数命令,但客户端对服务器进行多次往返通信时,将不得不承担这些网络和系统相关的延迟。

因此,高效的客户端会尝试通过将多个命令流水线化来限制往返次数。服务器和大多数客户端都完全支持这一点。像 MSET/MGET 这样的聚合命令也可以用于此目的。许多命令还支持所有数据类型的变长参数。

以下是一些准则

  • 如果条件允许,优先选择物理机而非虚拟机来托管服务器。
  • 不要系统地连接/断开服务器(特别是对于基于 Web 的应用程序)。尽可能保持连接长时间活跃。
  • 如果您的客户端与服务器在同一主机上,请使用 Unix 域套接字。
  • 优先使用聚合命令(MSET/MGET)或带变长参数的命令(如果可能),而非流水线。
  • 优先使用流水线(如果可能),而非连续的往返通信。
  • Valkey 支持 Lua 服务器端脚本,以应对不适合纯流水线操作的情况(例如,当一个命令的结果是后续命令的输入时)。

在 Linux 上,有些人可以通过调整进程放置(taskset)、cgroups、实时优先级(chrt)、NUMA 配置(numactl)或使用低延迟内核来获得更好的延迟。请注意,原版 Valkey 实际上不适合绑定到**单个** CPU 核心。Valkey 可以派生出可能极其消耗 CPU 的后台任务,如 BGSAVEBGREWRITEAOF。这些任务**绝不能**与主事件循环在同一个核心上运行。

在大多数情况下,不需要这类系统级优化。仅在您需要并且熟悉它们时才进行。

Valkey 顺序命令执行

Valkey 对命令执行使用大部分单线程设计。这意味着一个单独的进程通过一种称为多路复用的技术顺序执行所有客户端命令。虽然多个命令的 I/O 操作可以在后台并发处理,但任何给定时刻只能执行一个命令。这与 Node.js 的工作方式类似。然而,这两种产品通常不会被认为是慢的。这部分是由于完成单个命令执行所需的时间很短,但主要是因为这些产品设计为不阻塞系统调用,例如从套接字读取数据或写入数据。

慢命令产生的延迟

单线程的一个结果是,当一个请求服务缓慢时,所有其他客户端都将等待此请求被服务。当执行正常命令时,如 GETSETLPUSH,这根本不是问题,因为这些命令以常数(且非常短的)时间执行。但是,有些命令操作许多元素,如 SORTLREMSUNION 等。例如,计算两个大集合的交集可能需要相当长的时间。

所有命令的算法复杂度都有文档说明。一个好的做法是,在使用不熟悉的命令时系统地检查它。

如果您有延迟顾虑,您要么不应对包含许多元素的键值使用慢命令,要么应使用 Valkey 复制运行一个副本,并在该副本上运行所有慢查询。

可以使用 Valkey 的 Slow Log 功能监控慢命令。

此外,您可以使用您喜欢的进程监控程序(tophtopprstat 等)快速检查主 Valkey 进程的 CPU 消耗。如果流量不高而 CPU 消耗却很高,这通常是使用了慢命令的迹象。

重要提示:由慢命令执行产生的延迟的一个非常常见的来源是在生产环境中使用 KEYS 命令。KEYS 命令,如 Valkey 文档中所述,应仅用于调试目的。要增量迭代键空间和其他大型集合,请查看 SCANSSCANHSCANZSCAN 命令以获取更多信息。

fork 操作产生的延迟

为了在后台生成 RDB 文件,或者在启用 AOF 持久化时重写 Append Only File,Valkey 必须派生后台进程。fork 操作(在主线程中运行)本身会引起延迟。

Forking 在大多数类 Unix 系统上是一个昂贵的操作,因为它涉及复制大量与进程相关的对象。对于与虚拟内存机制关联的页表来说尤其如此。

例如,在 Linux/AMD64 系统上,内存被划分为 4 KB 的页面。为了将虚拟地址转换为物理地址,每个进程存储一个页表(实际上表示为一棵树),其中包含进程地址空间中每个页面的至少一个指针。因此,一个大型的 24 GB Valkey 实例需要一个 24 GB / 4 KB * 8 = 48 MB 的页表。

当执行后台保存时,此实例必须被派生(forked),这将涉及分配和复制 48 MB 的内存。这需要时间和 CPU,尤其是在虚拟机上,因为大型内存块的分配和初始化可能非常昂贵。

不同系统中的 fork 时间

现代硬件在复制页表方面非常快。现代硬件辅助虚拟化环境也是如此,但如果没有硬件支持,在旧的虚拟化环境中 fork 可能会非常慢。截至 2024 年,这几乎不是问题。

您可以通过执行 BGSAVE 并查看 INFO 命令输出中的 latest_fork_usec 字段来测量 Valkey 实例的 fork 时间。

透明大页引起的延迟

不幸的是,当 Linux 内核启用了透明大页时,Valkey 在使用 fork 调用进行磁盘持久化后会产生很大的延迟开销。大页是以下问题的原因:

  1. 调用 fork 后,会创建两个共享大页的进程。
  2. 在一个繁忙的实例中,几次事件循环运行将导致命令针对数千个页面,从而导致几乎整个进程内存的写时复制(copy on write)。
  3. 这将导致巨大的延迟和高内存使用。

请务必使用以下命令禁用透明大页

echo never > /sys/kernel/mm/transparent_hugepage/enabled

交换(操作系统分页)引起的延迟

Linux(以及许多其他现代操作系统)能够将内存页从内存重新定位到磁盘,反之亦然,以高效利用系统内存。

如果 Valkey 的一个页面被内核从内存移动到交换文件,当 Valkey 使用存储在该内存页面中的数据时(例如访问存储在该内存页面中的键),内核将停止 Valkey 进程以便将该页面移回主内存。这是一个涉及随机 I/O 的慢速操作(与访问已在内存中的页面相比),并将导致 Valkey 客户端经历异常延迟。

内核将 Valkey 内存页重新定位到磁盘主要有三个原因:

  • 系统面临内存压力,因为正在运行的进程所需的物理内存超过了可用量。这个问题最简单的例子就是 Valkey 使用的内存超出了可用内存。
  • Valkey 实例数据集,或数据集的一部分,大部分完全空闲(从未被客户端访问),因此内核可能会将空闲内存页交换到磁盘。这个问题非常罕见,因为即使是一个中等速度的实例也会经常触及所有内存页,迫使内核将所有页面保留在内存中。
  • 有些进程在系统上生成大量的读写 I/O。由于文件通常会被缓存,这往往会给内核施加压力,要求增加文件系统缓存,从而产生交换活动。请注意,这包括 Valkey RDB 和/或 AOF 后台线程,它们可能生成大文件。

幸运的是,Linux 提供了很好的工具来调查这个问题,所以当怀疑延迟是由于交换引起的时,最简单的方法就是检查是否确实如此。

首先要做的是检查 Valkey 有多少内存被交换到磁盘上。为此,您需要获取 Valkey 实例的 PID

$ valkey-cli info | grep process_id
process_id:5454

现在进入此进程的 `/proc` 文件系统目录

$ cd /proc/5454

在这里您会找到一个名为 smaps 的文件,它描述了 Valkey 进程的内存布局(假设您使用的是 Linux 2.6.16 或更高版本)。此文件包含有关我们进程内存映射的非常详细的信息,其中一个名为 Swap 的字段正是我们正在寻找的。然而,smaps 文件中并非只有一个 Swap 字段,因为它包含了 Valkey 进程的不同内存映射(进程的内存布局比简单的线性页面数组更复杂)。

由于我们对进程交换的所有内存感兴趣,首先要做的是在整个文件中 grep 查找 Swap 字段

$ cat smaps | grep 'Swap:'
Swap:                  0 kB
Swap:                  0 kB
Swap:                  0 kB
Swap:                  0 kB
Swap:                  0 kB
Swap:                 12 kB
Swap:                156 kB
Swap:                  8 kB
Swap:                  0 kB
Swap:                  0 kB
Swap:                  0 kB
Swap:                  0 kB
Swap:                  0 kB
Swap:                  0 kB
Swap:                  0 kB
Swap:                  0 kB
Swap:                  0 kB
Swap:                  4 kB
Swap:                  0 kB
Swap:                  0 kB
Swap:                  4 kB
Swap:                  0 kB
Swap:                  0 kB
Swap:                  4 kB
Swap:                  4 kB
Swap:                  0 kB
Swap:                  0 kB
Swap:                  0 kB
Swap:                  0 kB
Swap:                  0 kB

如果所有都显示 0 kB,或者只有零星的 4k 条目,那么一切都完全正常。实际上,在我们的示例实例中(一个运行 Valkey 且每秒服务数百用户的真实网站),有一些条目显示了更多交换的页面。为了调查这是否是一个严重问题,我们修改了命令,使其也打印内存映射的大小

$ cat smaps | egrep '^(Swap|Size)'
Size:                316 kB
Swap:                  0 kB
Size:                  4 kB
Swap:                  0 kB
Size:                  8 kB
Swap:                  0 kB
Size:                 40 kB
Swap:                  0 kB
Size:                132 kB
Swap:                  0 kB
Size:             720896 kB
Swap:                 12 kB
Size:               4096 kB
Swap:                156 kB
Size:               4096 kB
Swap:                  8 kB
Size:               4096 kB
Swap:                  0 kB
Size:                  4 kB
Swap:                  0 kB
Size:               1272 kB
Swap:                  0 kB
Size:                  8 kB
Swap:                  0 kB
Size:                  4 kB
Swap:                  0 kB
Size:                 16 kB
Swap:                  0 kB
Size:                 84 kB
Swap:                  0 kB
Size:                  4 kB
Swap:                  0 kB
Size:                  4 kB
Swap:                  0 kB
Size:                  8 kB
Swap:                  4 kB
Size:                  8 kB
Swap:                  0 kB
Size:                  4 kB
Swap:                  0 kB
Size:                  4 kB
Swap:                  4 kB
Size:                144 kB
Swap:                  0 kB
Size:                  4 kB
Swap:                  0 kB
Size:                  4 kB
Swap:                  4 kB
Size:                 12 kB
Swap:                  4 kB
Size:                108 kB
Swap:                  0 kB
Size:                  4 kB
Swap:                  0 kB
Size:                  4 kB
Swap:                  0 kB
Size:                272 kB
Swap:                  0 kB
Size:                  4 kB
Swap:                  0 kB

正如您从输出中看到的,有一个 720896 kB 的映射(其中只有 12 kB 被交换),另一个映射中还有 156 kB 被交换:基本上,我们只有非常少量的内存被交换,所以这根本不会造成任何问题。

相反,如果进程的非少量内存被交换到磁盘上,您的延迟问题可能与交换有关。如果您的 Valkey 实例出现这种情况,您可以使用 vmstat 命令进一步验证它

$ vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
 0  0   3980 697932 147180 1406456    0    0     2     2    2    0  4  4 91  0
 0  0   3980 697428 147180 1406580    0    0     0     0 19088 16104  9  6 84  0
 0  0   3980 697296 147180 1406616    0    0     0    28 18936 16193  7  6 87  0
 0  0   3980 697048 147180 1406640    0    0     0     0 18613 15987  6  6 88  0
 2  0   3980 696924 147180 1406656    0    0     0     0 18744 16299  6  5 88  0
 0  0   3980 697048 147180 1406688    0    0     0     4 18520 15974  6  6 88  0
^C

对我们来说,输出中有趣的部分是 siso 这两列,它们分别计算从/到交换文件交换的内存量。如果您在这两列中看到非零计数,那么您的系统中存在交换活动。

最后,可以使用 iostat 命令检查系统的全局 I/O 活动。

$ iostat -xk 1
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          13.55    0.04    2.92    0.53    0.00   82.95

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util
sda               0.77     0.00    0.01    0.00     0.40     0.00    73.65     0.00    3.62   2.58   0.00
sdb               1.27     4.75    0.82    3.54    38.00    32.32    32.19     0.11   24.80   4.24   1.85

如果您的延迟问题是由于 Valkey 内存被交换到磁盘上,您需要降低系统中的内存压力,要么在 Valkey 使用的内存超过可用内存时增加更多 RAM,要么避免在同一系统上运行其他内存密集型进程。

AOF 和磁盘 I/O 引起的延迟

另一个延迟源是 Valkey 对 Append Only File (AOF) 的支持。AOF 基本上使用两个系统调用来完成其工作。一个是 write(2),用于将数据写入只追加文件;另一个是 fdatasync(2),用于将内核文件缓冲区刷新到磁盘,以确保用户指定的持久性级别。

write(2)fdatasync(2) 调用都可能是延迟的来源。例如,当系统范围内正在进行同步时,或者当输出缓冲区已满且内核需要刷新到磁盘才能接受新写入时,write(2) 都可能阻塞。

fdatasync(2) 调用是一个更严重的延迟来源,因为在许多内核和文件系统组合下,它可能需要几毫秒到几秒才能完成,特别是在有其他进程执行 I/O 的情况下。因此,在可能的情况下,Valkey 会在不同的线程中执行 fdatasync(2) 调用。

我们将了解在使用 AOF 文件时,配置如何影响延迟的数量和来源。

AOF 可以通过 appendfsync 配置选项配置以三种不同方式在磁盘上执行 fsync(此设置可以在运行时使用 CONFIG SET 命令修改)。

  • appendfsync 设置为 no 时,Valkey 不执行 fsync。在此配置中,唯一的延迟来源可能是 write(2)。当发生这种情况时,通常没有解决方案,因为磁盘根本无法处理 Valkey 接收数据的速度,但是,如果磁盘没有被其他 I/O 进程严重拖慢,这种情况并不常见。

  • appendfsync 设置为 everysec 时,Valkey 每秒执行一次 fsync。它使用不同的线程,如果 fsync 仍在进行中,Valkey 会使用缓冲区将 write(2) 调用延迟最多两秒(因为如果对同一文件进行 fsync,Linux 上的写入会阻塞)。然而,如果 fsync 花费时间过长,即使 fsync 仍在进行中,Valkey 最终也会执行 write(2) 调用,这可能成为延迟的来源。

  • appendfsync 设置为 always 时,每次写入操作在回复客户端 OK 代码之前都会执行一次 fsync(实际上 Valkey 会尝试将同时执行的许多命令聚合到一次 fsync 中)。在这种模式下,性能通常非常低,强烈建议使用快速磁盘和能够在短时间内执行 fsync 的文件系统实现。

大多数 Valkey 用户会为 appendfsync 配置指令使用 noeverysec 设置。对于最小延迟的建议是避免在同一系统中运行其他执行 I/O 的进程。使用 SSD 磁盘也会有所帮助,但通常即使是非 SSD 磁盘也能很好地与只追加文件配合,前提是磁盘空闲,因为 Valkey 在写入只追加文件时不会执行任何寻道操作。

如果您想调查与只追加文件相关的延迟问题,您可以在 Linux 下使用 strace 命令

sudo strace -p $(pidof valkey-server) -T -e trace=fdatasync

上述命令将显示 Valkey 在主线程中执行的所有 fdatasync(2) 系统调用。使用上述命令,当 appendfsync 配置选项设置为 everysec 时,您将看不到后台线程执行的 fdatasync 系统调用。为此,只需向 strace 添加 -f 开关。

如果您愿意,也可以使用以下命令同时查看 fdatasyncwrite 系统调用

sudo strace -p $(pidof valkey-server) -T -e trace=fdatasync,write

然而,由于 write(2) 也用于向客户端套接字写入数据,这可能会显示太多与磁盘 I/O 无关的内容。显然,无法告诉 strace 只显示慢速系统调用,所以我使用以下命令:

sudo strace -f -p $(pidof valkey-server) -T -e trace=fdatasync,write 2>&1 | grep -v '0.0' | grep -v unfinished

过期键产生的延迟

Valkey 通过两种方式驱逐过期键:

  • 一种惰性方式是,当命令请求某个键时,如果发现它已经过期,则将其过期。
  • 另一种主动方式是,每 100 毫秒过期几个键。

主动过期设计为自适应的。过期周期每 100 毫秒启动一次(每秒 10 次),并将执行以下操作:

  • 采样 ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP 个键,驱逐所有已过期的键。
  • 如果发现超过 25% 的键已过期,则重复此过程。

鉴于 ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP 默认设置为 20,并且该过程每秒执行十次,通常每秒只有 200 个键被主动过期。这足以快速清理数据库,即使长期未访问已过期的键,惰性算法也无济于事。同时,每秒只过期 200 个键对 Valkey 实例的延迟没有影响。

然而,该算法是自适应的,如果在采样键集中发现超过 25% 的键已过期,它将循环。但考虑到我们每秒运行该算法十次,这意味着在我们的随机样本中,超过 25% 的键至少在同一秒内过期,这是不幸的情况。

基本上,这意味着**如果数据库中有大量键在同一秒内过期,并且这些键至少占当前设置了过期时间的键总数的 25%**,Valkey 可能会阻塞,以使已过期键的百分比降至 25% 以下。

这种方法是为了避免对已过期键使用过多内存,并且通常是完全无害的,因为大量键在同一秒精确过期是很罕见的,但用户大量使用具有相同 Unix 时间的 EXPIREAT 并非不可能。

简而言之:请注意,许多键在同一时刻过期可能是延迟的一个来源。

Valkey 软件看门狗

Valkey 软件看门狗是一种调试工具,旨在跟踪那些因某种原因未能通过常规工具分析出来的延迟问题。

软件看门狗是一个实验性功能。虽然它设计用于生产环境,但在继续之前应注意备份数据库,因为它可能与 Valkey 服务器的正常执行产生意外交互。

当无法通过其他方式跟踪问题时,仅将其作为最后手段使用非常重要。

此功能的工作原理如下:

  • 用户使用 CONFIG SET 命令启用软件看门狗。
  • Valkey 开始持续监控自身。
  • 如果 Valkey 检测到服务器被阻塞在某个操作中,该操作返回不够快,并且可能是延迟问题的来源,则会将服务器阻塞位置的低级报告转储到日志文件中。
  • 用户通过在 GitHub 上提交问题联系开发者,并在消息中包含看门狗报告。

请注意,此功能不能通过 valkey.conf 文件启用,因为它旨在仅在已运行的实例中启用,并且仅用于调试目的。

要启用此功能,只需使用以下命令:

CONFIG SET watchdog-period 500

周期以毫秒为单位指定。在上面的示例中,我指定只有当服务器检测到延迟达到或超过 500 毫秒时才记录延迟问题。最小可配置周期为 200 毫秒。

当您使用完软件看门狗后,可以通过将 watchdog-period 参数设置为 0 来将其关闭。重要提示:请记住这样做,因为让实例长时间开启看门狗通常不是一个好主意。

以下是软件看门狗检测到延迟超过配置值后,您将在日志文件中看到的一个示例:

[8547 | signal handler] (1333114359)
--- WATCHDOG TIMER EXPIRED ---
/lib/libc.so.6(nanosleep+0x2d) [0x7f16b5c2d39d]
/lib/libpthread.so.0(+0xf8f0) [0x7f16b5f158f0]
/lib/libc.so.6(nanosleep+0x2d) [0x7f16b5c2d39d]
/lib/libc.so.6(usleep+0x34) [0x7f16b5c62844]
./valkey-server(debugCommand+0x3e1) [0x43ab41]
./valkey-server(call+0x5d) [0x415a9d]
./valkey-server(processCommand+0x375) [0x415fc5]
./valkey-server(processInputBuffer+0x4f) [0x4203cf]
./valkey-server(readQueryFromClient+0xa0) [0x4204e0]
./valkey-server(aeProcessEvents+0x128) [0x411b48]
./valkey-server(aeMain+0x2b) [0x411dbb]
./valkey-server(main+0x2b6) [0x418556]
/lib/libc.so.6(__libc_start_main+0xfd) [0x7f16b5ba1c4d]
./valkey-server() [0x411099]
------

注意:在此示例中,使用了 DEBUG SLEEP 命令来阻塞服务器。如果服务器在不同的上下文中阻塞,堆栈跟踪将不同。

如果您收集到多个看门狗堆栈跟踪,建议您将其全部发布到 GitHub issue 中。我们获得的跟踪越多,就越容易理解您的实例存在什么问题。