Kafka 消费者滞后的锯齿模式是如何出现的?

How does a sawtooth pattern of Kafka consumer lag emerge?

我的一些 Kafka 消费者(但不是全部)表现出一种有趣的滞后模式。

下图显示了两个很好的例子:

深蓝色:

浅蓝(与深蓝同题):

棕色:

两个 sawtoothy 客户端都可以处理比这大得多的吞吐量(通过暂停、恢复和让它们赶上进行测试),因此它们没有达到极限。

重新平衡有时确实会发生(根据日志),但比图表中的跳跃要少得多,而且少数事件也不与跳跃及时相关。

消息也不是分批来的。以下是受影响主题之一的附加信息:

这个图案起源于哪里?

刚发现低频锯齿波不是真的。而且解释很有趣。 ;)

当我使用命令行 (kafka-consumer-groups --bootstrap-server=[...] --group [...] --describe) 检查消费者滞后时,我发现总消费者滞后(每个分区的滞后总和)波动非常快。某一时刻大约是 6000,2 秒后大约是 1000,再过 2 秒可能是 9000。

然而,显示的图表似乎是基于以较低频率采集的样本,这违反了 Nyquist–Shannon sampling theorem. So the averaging does not work, and we see a Moiré pattern

结论:锯齿图案只是一种错觉。


为了完整起见,这里是一个描述效果的模拟:

#!/usr/bin/env python3
"""Simulate moire effect of Kafka-consumer-lag graph.
"""

import random

import matplotlib.pyplot as plt


def x_noise_sampling() -> int:
    return 31 + random.randint(-6, 6)


def main() -> None:
    max_x = 7000
    sample_rate = 97
    xs = list(range(max_x))
    ys = [x % 100 for x in xs]
    xs2 = [x + x_noise_sampling() for x in range(0, max_x - 100, sample_rate)]
    ys2 = [ys[x2] for x2 in xs2]

    plt.figure(figsize=(16, 9))
    plt.xlabel('Time')
    plt.xticks([])
    plt.yticks([])
    plt.ylabel('Consumer lag')
    signal, = plt.plot(xs, ys, '-')
    samples, = plt.plot(xs2, ys2, 'bo')
    interpolated, = plt.plot(xs2, ys2, '-')
    plt.legend([signal, samples, interpolated], ['Signal', 'Samples', 'Interpolated samples'])
    plt.savefig('sawtooth_moire.png', dpi=100)
    plt.show()


if __name__ == '__main__':
    main()