解锁 Kafka 的潜力:使用 eBPF 解决尾部延迟问题

Allegro,使用Kafka作为微服务间异步通信的骨干,每秒最多发布 30 万条消息和消费 100 万条消息,是基础设施的关键部分。几个月前,在主 Kafka 集群中发现中位数响应时间为单位数毫秒,但尾部延迟更差,p99 延迟高达 1 秒,p999 延迟高达 3 秒,这对新项目不可接受,于是决定调查此问题。

  • 追踪需求:Kafka 代理暴露各种指标,但无法确定高百分位生产请求缓慢的原因,系统指标也无异常,决定追踪单个请求,通过捕获网络流量并分析 Kafka 处理生产请求的组件来找出延迟峰值的来源,先找到每个 Kafka 生产请求的到达和结束时间,利用 tcpdump 捕获网络流量,编写工具分析数据包,获取请求元数据。
  • 动态追踪:借助网络流量分析获取每个请求的到达时间、结束时间和元数据,为找出 Kafka 组件中的延迟源,决定对底层存储的写入进行检测,在 Linux 中 Kafka 使用常规文件存储数据,通过普通 write 系统调用将数据先存储在页缓存然后异步刷新到磁盘,利用动态追踪技术无需修改源代码即可追踪单个文件写入,如使用 BPF(或 eBPF),它是一种通用的内核执行环境,有多种前端工具,如 BCC、bpftrace 和 libbpf 等,其中 ext4slower 可追踪 ext4 文件系统的文件系统操作。
  • 追踪 Kafka:Kafka 中每个分区有自己的目录,通过修改 ext4slower 程序包含父目录来追踪 Kafka 文件系统写入,获取写入的开始时间、结束时间、持续时间、线程 ID、写入字节数、文件偏移量、主题名称和分区 ID 等信息,将其与 tcpdump 输出的生产请求相关联,进一步确认慢生产请求是等待文件系统写入完成,且有请求无对应慢写入,推测请求在排队等待。
  • Kafka 锁争用:慢生产请求无对应慢写入时,怀疑请求在排队等待,通过分析 Kafka 源代码找到使用synchronized块的地方,包括保护日志文件写入的部分,尝试用追踪结合 ext4 文件系统追踪工具或使用 async-profiler 捕获 Kafka 线程状态来测量处理生产请求的线程在锁上花费的时间,最终选择 async-profiler 来清晰可视化线程状态和获取 JVM 特定线程属性的更多洞察,分析延迟峰值情况时,通过网络流量捕获确定慢生产请求,结合 async-profiler 输出和 eBPF 追踪确认线程等待锁是导致延迟的原因,即对于慢生产请求,要么有匹配的慢写入,要么线程在等待获取日志文件访问锁。
  • 追踪文件系统:原始 eBPF 脚本仅追踪ext4_file_write_iter函数,虽能确定慢写入导致延迟峰值,但不足以确定文件系统的哪些参数需要调整,通过分别使用profileoffcputime捕获ext4_file_write_iter的 on-CPU 和 off-CPU 轮廓,发现ext4_dirty_inodejbd2_journal_start函数在两个轮廓中都存在,jbd2_journal_start是 ext4 中日志机制的一部分,wait_transaction_locked函数在 off-CPU 轮廓中,通过搜索内核代码找到设置T_FLUSH标志的地方,即jbd2_journal_commit_transaction函数,追踪该函数发现其高延迟导致ext4_dirty_inode高延迟。
  • ext4 改进监控:确定日志提交是慢写入的原因后,使用ebpf_exporter工具以 Prometheus 格式暴露 eBPF 指标,在 Grafana 中可视化追踪函数的延迟,通过运行不同配置的代理并观察其写入延迟来观察优化的影响。
  • ext4 改进:研究 ext4 发现几种可能的性能改进方法,如禁用日志记录、减少提交间隔、更改日志模式为data=writeback和启用快速提交等,禁用日志记录因数据安全风险被排除,减少提交间隔实验无显著差异,更改日志模式为data=writeback后观察到延迟改善,启用快速提交后最大写入延迟显著降低,文件系统写入延迟降低也导致生产延迟降低。
  • XFS:研究 ext4 日志记录时发现 XFS 文件系统在处理大文件和高吞吐量工作负载方面表现更好,将一个代理迁移到 XFS 文件系统,其性能一致,优于其他 ext4 配置,测试几周后确定 XFS 是最佳选择,将所有代理从 ext4 迁移到 XFS。
    总结:测试了 ext4 的几种优化,如更改日志模式和启用快速提交,发现data=writebackfast commit显著降低延迟,XFS 性能最佳,最终将 XFS 部署到所有代理,使超过 65ms 的生产请求数量降低了 82%,并总结了在过程中的经验教训,如 eBPF 很有用,ebpf_exporter可观察长时间的追踪结果,p99 和 p999 分析有时不够等。
阅读 12
0 条评论