跳转到主要内容

延迟监控工具

KeyDB 通常用于要求严苛的使用场景,在这些场景中,它需要为每个实例每秒处理大量的查询,同时对平均响应时间和最坏情况下的延迟都有非常严格的要求。

虽然 KeyDB 是一个内存系统,但它以不同的方式与操作系统交互,例如在持久化到磁盘的情况下。此外,KeyDB 实现了一套丰富的命令。某些命令速度很快,以常数或对数时间运行,而其他一些命令则是较慢的 O(N) 命令,可能会导致延迟尖峰。

基于所有这些原因,我们创建了**延迟监控(Latency Monitoring)**功能,以帮助用户检查和排查潜在的延迟问题。延迟监控由以下几个概念部分组成:

  • 对不同延迟敏感代码路径进行采样的延迟挂钩(Latency hooks)。
  • 按不同事件划分的延迟尖峰时间序列记录。
  • 用于从时间序列中获取原始数据的报告引擎。
  • 根据测量结果提供人类可读报告和建议的分析引擎。

本文档的其余部分将详细介绍延迟监控子系统,但有关 KeyDB 和延迟的一般主题的更多信息,请阅读本文档中的 KeyDB 延迟问题排查页面。

事件和时间序列#

不同的被监控代码路径有不同的名称,被称为*事件*。例如,`command` 是一个用于测量可能较慢的命令执行延迟尖峰的事件,而 `fast-command` 则是用于监控 O(1) 和 O(log N) 命令的事件名称。其他事件则不那么通用,它们监控 KeyDB 执行的某个非常具体的操作。例如,`fork` 事件只监控 KeyDB 执行 `fork(2)` 系统调用所花费的时间。

延迟尖峰是指执行时间超过配置的延迟阈值的事件。每个被监控的事件都有一个独立的时间序列与之关联。时间序列的工作方式如下:

  • 每当发生延迟尖峰时,它会被记录在相应的时间序列中。
  • 每个时间序列由 160 个元素组成。
  • 每个元素都是一个键值对:一个是测量到延迟尖峰时的 Unix 时间戳,另一个是该事件执行所花费的毫秒数。
  • 在同一秒内发生的同一事件的延迟尖峰会被合并(通过取最大延迟),因此即使某个事件持续测量到延迟尖峰(例如,因为用户设置了非常低的阈值),也至少能保留 180 秒的历史记录。
  • 对于每个元素,都会记录其历史最高延迟。

该框架监控并记录以下事件执行时间的延迟尖峰:

  • `command`:常规命令。
  • `fast-command`:O(1) 和 O(log N) 命令。
  • `fork`:`fork(2)` 系统调用。
  • `rdb-unlink-temp-file`:`unlink(2)` 系统调用。
  • `aof-write`:写入 AOF 文件 —— 一个涵盖所有 `fsync(2)` 系统调用的事件。
  • `aof-fsync-always`:当由 `appendfsync allways` 策略调用时的 `fsync(2)` 系统调用。
  • `aof-write-pending-fsync`:当存在待处理写入时执行的 `fsync(2)` 系统调用。
  • `aof-write-active-child`:当由子进程执行时的 `fsync(2)` 系统调用。
  • `aof-write-alone`:当由主进程执行时的 `fsync(2)` 系统调用。
  • `aof-fstat`:`fstat(2)` 系统调用。
  • `aof-rename`:在完成 `BGREWRITEAOF` 后重命名临时文件的 `rename(2)` 系统调用。
  • `aof-rewrite-diff-write`:在执行 `BGREWRITEAOF` 期间写入累积的差异数据。
  • `active-defrag-cycle`:主动碎片整理周期。
  • `expire-cycle`:过期清理周期。
  • `eviction-cycle`:驱逐周期。
  • `eviction-del`:驱逐周期中的删除操作。

如何启用延迟监控#

对于一个用例来说是高延迟的情况,对于另一个用例可能并非如此。有些应用要求所有查询必须在 1 毫秒内完成,而另一些应用则可以接受一小部分客户端偶尔经历 2 秒的延迟。

因此,启用延迟监控的第一步是设置一个以毫秒为单位的**延迟阈值**。只有执行时间超过指定阈值的事件才会被记录为延迟尖峰。用户应根据自身需求设置阈值。例如,如果基于 KeyDB 的应用要求最大可接受延迟为 100 毫秒,则应将阈值设置为该值,以便记录所有阻塞服务器时间等于或大于 100 毫秒的事件。

在生产服务器上,可以使用以下命令在运行时轻松启用延迟监控:

CONFIG SET latency-monitor-threshold 100

默认情况下,监控是禁用的(阈值设置为 0),尽管延迟监控的实际开销几乎为零。然而,虽然延迟监控的内存需求非常小,但对于一个运行良好的 KeyDB 实例,没有充分的理由去增加其基线内存使用量。

使用 LATENCY 命令进行信息报告#

延迟监控子系统的用户接口是 `LATENCY` 命令。与许多其他 KeyDB 命令一样,`LATENCY` 接受不同的子命令来改变其行为。这些子命令是:

  • `LATENCY LATEST` - 返回所有事件的最新延迟样本。
  • `LATENCY HISTORY` - 返回给定事件的延迟时间序列。
  • `LATENCY RESET` - 重置一个或多个事件的延迟时间序列数据。
  • `LATENCY GRAPH` - 渲染一个事件延迟样本的 ASCII 艺术图。
  • `LATENCY DOCTOR` - 回复一份人类可读的延迟分析报告。

有关更多信息,请参阅每个子命令的文档页面。