← 回總覽

LinkedIn 如何发现导致系统反复死机的内核锁竞争问题

📅 2026-06-03 12:30 InfoQ 中文 软件编程 2 分鐘 1552 字 評分: 87
后端开发 系统设计 性能优化 Rust eBPF
📌 一句话摘要 LinkedIn 工程师利用 eBPF 离线 CPU 性能分析技术,定位并修复了因 Rust HashMap 扩容触发内核 mmap_lock 死锁导致的数据库间歇性冻结问题。 📝 详细摘要 本文详细介绍了 LinkedIn 工程师解决一个棘手的数据库间歇性冻结问题的全过程。该问题表现为数据库每 10 到 15 秒突然不可用,随后自行恢复,且无任何日志记录。常规监控手段(如 CPU、内存、I/O 分析)均无法定位原因。工程师最终设计了一套基于 eBPF 的自动化监控脚本,在系统冻结瞬间触发离线 CPU 性能分析(off-CPU profiling),捕获了被阻塞线程的内核堆

📌 一句话摘要

LinkedIn 工程师利用 eBPF 离线 CPU 性能分析技术,定位并修复了因 Rust HashMap 扩容触发内核 mmap_lock 死锁导致的数据库间歇性冻结问题。

📝 详细摘要

本文详细介绍了 LinkedIn 工程师解决一个棘手的数据库间歇性冻结问题的全过程。该问题表现为数据库每 10 到 15 秒突然不可用,随后自行恢复,且无任何日志记录。常规监控手段(如 CPU、内存、I/O 分析)均无法定位原因。工程师最终设计了一套基于 eBPF 的自动化监控脚本,在系统冻结瞬间触发离线 CPU 性能分析(off-CPU profiling),捕获了被阻塞线程的内核堆栈。分析发现,根本原因在于 Rust 内存中的 HashMap 在达到 5870 万条记录后触发扩容,导致约 3.5 GB 的大规模内存分配。此操作在内核层面以写模式锁定了 mmap_lock 信号量,阻塞了所有其他需要内存操作的线程(包括页面错误处理和内存清理),从而造成系统短暂冻结。解决方案是预分配 HashMap,避免运行时扩容,虽然增加了约 3 GB 的启动内存占用,但彻底解决了问题。文章总结了三个关键教训:预分配大型数据结构对延迟敏感路径的重要性、eBPF 离线性能分析在诊断瞬时性问题中的强大作用,以及自动化监控机制对于捕获短暂故障诊断信息的必要性。

💡 主要观点

- 利用 eBPF 离线 CPU 性能分析是诊断瞬时性系统冻结的关键。 常规监控无法捕捉仅持续 10-15 秒的故障,而通过 BCC 工具包中的 offcputime.py 分析器,在故障触发瞬间捕获被阻塞线程的内核堆栈,是定位根本原因的唯一方法。

Rust HashMap 的运行时扩容触发了内核级 mmap_lock 死锁。 当 HashMap 条目数超过 5870 万时,扩容操作需要以写模式持有 mmap_lock 信号量,这会阻塞所有其他需要修改虚拟地址空间或进行内存操作的线程,导致系统短暂冻结。
预分配大型数据结构是避免延迟敏感路径中突发内存激增的有效策略。 通过预分配 HashMap,避免了运行时的动态扩容操作,虽然增加了启动时的内存占用(约 3 GB),但换取了运行时的稳定性和低延迟,是一个可接受的权衡。

💬 文章金句

- 这是关键的突破口。这些事件发生得太过短暂,常规监控无法捕捉其根本原因,因此要观察根本原因,唯一的方法就是在系统冻结开始时,用已经部署好的性能分析工具获取当时的信息。

  • 任何修改进程虚拟地址空间的操作(如大规模的 mmap 分配)都必须以写模式持有此锁。在持有写锁期间,所有需要进行内存操作的其他线程(包括用于清理的 madvise 以及用于 I/O 的页面故障处理)都会被阻塞。

📊 文章信息

AI 初评:87

来源:InfoQ 中文

作者:InfoQ 中文

分类:软件编程

语言:中文

阅读时间:6 分钟

字数:1357

标签: 后端开发, 系统设计, 性能优化, Rust, eBPF

阅读完整文章

查看原文 → 發佈: 2026-06-03 12:30:00 收錄: 2026-06-04 02:00:35

🤖 問 AI

針對這篇文章提問,AI 會根據文章內容回答。按 Ctrl+Enter 送出。