apache-kafka - 卡夫卡消费者滞后的锯齿模式是如何出现的?
问题描述
我的一些 Kafka 消费者(但不是全部)在他们的延迟方面表现出一种有趣的模式。
下图显示了两个很好的示例:
深蓝:
- 主题中每秒大约 200 条消息
- 32个分区
- 组中的 1 个消费者(Python 客户端,在 Kubernetes 上运行)
浅蓝色(与深蓝色相同的主题):
- 所以主题中每秒也有大约 200 条消息
- 32个分区也是如此
- 组中的 1 个使用者(也是一个 Python 客户端,在 Kubernetes 上运行)
棕色的:
- 主题中每秒大约 1500 条消息
- 40个分区
- 组中的 2 个消费者(Java/Spring 客户端,在 Kubernetes 上运行)
两个锯齿状的客户端都可以处理比这更大的吞吐量(通过暂停、恢复和让它们赶上来进行测试),因此它们没有达到极限。
重新平衡有时确实会发生(根据日志),但比图表中的跳跃要少得多,而且少数事件也与跳跃在时间上不相关。
消息也不会分批出现。以下是受影响主题之一的附加信息:
这种模式起源于哪里?
解决方案
才发现低频的锯齿纹不是真的。而且解释很有趣。;)
当我使用命令行 ( kafka-consumer-groups --bootstrap-server=[...] --group [...] --describe
) 检查消费者滞后时,我看到总消费者滞后(每个分区的滞后总和)波动非常快。有一次它大约是 6000,2 秒后它大约是 1000,再过 2 秒它可能是 9000。
然而,显示的图表似乎基于以较低频率采集的样本,这违反了Nyquist-Shannon 采样定理。所以平均不起作用,我们看到了莫尔图案。
结论:锯齿纹只是一种错觉。
为了完整起见,这里是一个描述效果的模拟:
#!/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()
推荐阅读
- javascript - 在继续下一行之前,等待函数没有执行。(异步/等待不工作)
- java - JVM方法和堆区中类引用的区别
- ruby - 通过引用进行 Ruby 哈希
- swift - 如何等待一个返回无效的未来?
- python - model.eval() 在 pytorch 中做了什么?
- r - 将剪贴板内容粘贴到 RStudio 中的快捷方式自动用引号括起来?
- c# - 如何通过 DGV 在 WinForms 中创建表格、添加行并保存所有内容而不使用数据库?
- django - Django - 在一个模板中处理同一模型的两个表单元素
- mysql - SQL搜索多表并包含
- amadeus - 使用 Amadeus Trip 解析器 API