Cơn ác mộng lúc 2 giờ sáng: Tại sao các công cụ tiêu chuẩn lại thất bại
Điện thoại của bạn rung lên lúc 2 giờ sáng. Đó là một cảnh báo ưu tiên cao: cơ sở dữ liệu sản xuất đang chạy cực chậm và thời gian phản hồi API đang tăng vọt. Bạn SSH vào máy chủ và chạy top. Mức sử dụng CPU có vẻ ổn. Bạn kiểm tra iostat, và mặc dù mức sử dụng đĩa bị kẹt ở mức 90%, bạn không thể biết tiến trình nào là thủ phạm. Các công cụ truyền thống như top, ps và iostat đã là lựa chọn hàng đầu của chúng ta trong nhiều thập kỷ. Chúng rất tốt để xem nhanh, nhưng chúng chỉ cho bạn biết “điều gì” đang xảy ra. Chúng hiếm khi giải thích “tại sao” hoặc “ai” là người chịu trách nhiệm.
Các tiện ích truyền thống này dựa vào hệ thống tệp /proc. Nó cung cấp các số liệu thống kê tổng hợp—về cơ bản là các ảnh chụp nhanh (snapshots) tại một thời điểm. Chúng thường bỏ sót các tiến trình ngắn hạn hoặc độ trễ chi tiết của từng yêu cầu I/O. Đây là lúc eBPF (Extended Berkeley Packet Filter) định nghĩa lại khả năng quan sát (observability). Nó cho phép bạn chạy các chương trình trong môi trường cô lập (sandboxed) trực tiếp trong nhân (kernel) Linux. Bạn có thể theo dõi hầu như bất kỳ sự kiện nào mà không cần chạm vào mã nguồn kernel hoặc tải các module rủi ro.
BPF Compiler Collection (BCC) giúp công nghệ này trở nên dễ tiếp cận hơn. Nó cung cấp hàng chục kịch bản Python được xây dựng sẵn để xử lý logic biên dịch phức tạp cho bạn. Bạn không cần phải là một kỹ sư kernel để sử dụng chúng. Tôi đã sử dụng những công cụ này để giải quyết những bí ẩn trong vài phút mà lẽ ra phải mất hàng giờ để lục lọi nhật ký (log) thủ công.
Cài đặt: Đưa BCC lên máy của bạn
Nhân của bạn cần tương đối hiện đại—phiên bản 4.1 trở lên—để chạy BCC. Hầu hết các môi trường chạy Ubuntu 20.04+, Debian 11+ hoặc RHEL 8+ đều đã sẵn sàng. Mặc dù tên gói có hơi khác nhau giữa các bản phân phối, nhưng các công cụ bên dưới vẫn giống nhau.
Trên Ubuntu/Debian
Đối với các hệ thống dựa trên Debian, gói này có sẵn trong các kho lưu trữ tiêu chuẩn. Bạn cũng phải cài đặt các kernel headers khớp với phiên bản đang chạy. Điều này cho phép BCC biên dịch các chương trình BPF ngay lập tức.
sudo apt update
sudo apt install bpfcc-tools linux-headers-$(uname -r)
Trên RHEL/CentOS Stream/AlmaLinux
Các hệ thống dựa trên RHEL bao gồm BCC trong kho lưu trữ AppStream. Sử dụng lệnh sau để bắt đầu:
sudo dnf install bcc-tools
Lưu ý: Người dùng RHEL và AlmaLinux thường sẽ tìm thấy các kịch bản này được đặt trong /usr/share/bcc/tools. Bạn có thể muốn thêm thư mục đó vào PATH hoặc gọi các công cụ bằng đường dẫn đầy đủ của chúng.
Cấu hình: Chuẩn bị môi trường Kernel
Việc đưa phần mềm vào đĩa chỉ là bước đầu tiên. BCC biên dịch mã C thành bytecode BPF tại thời điểm chạy, điều này yêu cầu quyền truy cập vào cấu hình nhân của bạn. Nếu bạn đang làm việc trong một image đám mây rút gọn hoặc một container bị hạn chế, bạn có thể thấy lỗi liên quan đến việc thiếu tệp trong /lib/modules/$(uname -r)/build.
Tôi đã thử nghiệm điều này trên một instance Ubuntu 22.04 thực tế với 4GB RAM. Việc đảm bảo linux-headers được ánh xạ chính xác đã cho phép BCC khởi tạo trong chưa đầy hai giây. Nếu không có chúng, các công cụ sẽ thất bại với các lỗi biên dịch khó hiểu. Tốc độ rất quan trọng khi cơ sở dữ liệu đang bị treo.
Kiểm tra thiết lập bằng cách chạy opensnoop. Công cụ này theo dõi mọi lời gọi hệ thống open() trên toàn bộ hệ điều hành. Nếu nó bắt đầu in các đường dẫn tệp, môi trường của bạn đã sẵn sàng để chẩn đoán chuyên sâu:
sudo /usr/sbin/opensnoop-bpfcc
Nếu bạn thấy một luồng dữ liệu trực tiếp về các tệp đang được truy cập bởi các PID khác nhau, bạn đã sẵn sàng để bắt đầu săn lùng các điểm nghẽn hiệu năng thực sự.
Xác minh & Giám sát: Những công cụ đã qua thực chiến
Bộ công cụ BCC bao gồm hơn một trăm tiện ích. Trong một sự cố thực tế, bạn không có thời gian để đọc hướng dẫn sử dụng. Tôi luôn ghi nhớ một danh sách ngắn gồm bốn công cụ cụ thể giúp giải quyết khoảng 90% các bí ẩn về hiệu năng phổ biến.
1. Theo dõi các tiến trình ngắn hạn với execsnoop
Bạn đã bao giờ thấy CPU tăng đột biến trong khi top hiển thị hệ thống đang rảnh rỗi chưa? Điều này thường do các tiến trình “ma”—các kịch bản hoặc cron job khởi chạy và kết thúc trong vài mili giây. Các công cụ tiêu chuẩn không lấy mẫu đủ nhanh để bắt được chúng.
sudo execsnoop-bpfcc
Lệnh này hiển thị mọi lần thực thi tiến trình mới, bao gồm PID cha và các đối số dòng lệnh đầy đủ. Tôi từng tìm thấy một shell script bị lỗi tự gọi chính nó một cách đệ quy. Nó tạo ra 2.500 tiến trình mỗi giây, một sự hỗn loạn mà htop hoàn toàn bỏ sót.
2. Đo độ trễ đĩa với biolatency
Tỷ lệ sử dụng đĩa thường gây nhầm lẫn. Một ổ đĩa ở mức sử dụng 100% vẫn có thể đang hoạt động tốt, trong khi một ổ đĩa ở mức 10% có thể gây ra hiện tượng lag lớn do thời gian tìm kiếm (seek time) cao. biolatency loại bỏ các nhiễu thông tin này bằng cách cung cấp một biểu đồ tần suất (histogram) về độ trễ I/O thực tế.
sudo biolatency-bpfcc 10 1
Lệnh này thu thập dữ liệu trong 10 giây và in ra sự phân phối. Hãy tìm kiếm các cụm dữ liệu. Nếu bạn thấy số lượng lớn trong khoảng >128ms, hệ thống lưu trữ của bạn đang gặp vấn đề, bất kể các con số về băng thông (throughput) của bạn nói gì.
3. Xác định các tiến trình chiếm dụng mạng với tcptop
Khi mạng bị bão hòa, iftop cho bạn thấy băng thông trên mỗi host. Tuy nhiên, tcptop cho bạn thấy băng thông trên mỗi tiến trình. Đây là cách nhanh nhất để xác định chính xác container hoặc dịch vụ nào đang “ngốn” băng thông của bạn.
sudo tcptop-bpfcc
Nó hoạt động giống như top, nhưng dành cho các kết nối TCP. Nó hiển thị các PID, địa chỉ IP và lưu lượng RX/TX tính bằng Kilobytes. Nó hoàn hảo để phát hiện một kịch bản sao lưu chạy sai hoặc rò rỉ dữ liệu trong thời gian thực.
4. Tìm độ trễ của hệ thống tệp với ext4slower
Đôi khi phần cứng vẫn ổn, nhưng lớp hệ thống tệp lại chậm do tranh chấp khóa (lock contention). Nếu bạn sử dụng EXT4, ext4slower sẽ theo dõi các thao tác phổ biến như đọc và ghi. Nó chỉ báo cáo những thao tác vượt quá một ngưỡng nhất định, ví dụ như 10ms.
sudo ext4slower-bpfcc 10
Điều này vô cùng quý giá để khắc phục sự cố cơ sở dữ liệu. Nếu một lời gọi write() vào transaction log mất 50ms, hiệu năng cơ sở dữ liệu của bạn sẽ giảm sút nghiêm trọng. Công cụ này xác định chính xác tệp và PID đã chịu sự chậm trễ đó.
Giải thích kết quả
Sử dụng các công cụ BCC cốt yếu là để tìm ra các giá trị ngoại lai (outliers). Trong một hệ thống khỏe mạnh, các biểu đồ tần suất nên tập trung ở phần đầu (“top-heavy”), nghĩa là hầu hết các thao tác diễn ra trong vài micro giây. Khi bạn thấy một phân phối “lưỡng đỉnh” (bimodal)—nơi xuất hiện đỉnh thứ hai trong phạm vi mili giây hoặc giây—bạn đã tìm thấy điểm rò rỉ hiệu năng của mình.
Chi phí tài nguyên (overhead) là một mối quan tâm lớn trong môi trường thực tế (production). Strace có thể làm tê liệt một tiến trình, làm nó chậm đi 10 lần hoặc hơn. Các công cụ BCC sử dụng eBPF để giữ mức overhead cực thấp, thường dưới 1%. Sự an toàn này cho phép bạn chạy chẩn đoán trên một máy chủ đang chạy tải nặng mà không làm sập ứng dụng.
Lần tới khi bạn đối mặt với một hệ thống chậm chạp và uptime cho thấy mức tải trung bình (load average) cao mà không có nguyên nhân rõ ràng, đừng đoán mò nữa. Hãy chạy execsnoop để kiểm tra sự biến động của tiến trình và biolatency để kiểm tra các ổ đĩa. Thông thường, một trong số chúng sẽ dẫn bạn đến nguyên nhân gốc rễ trước khi tách cà phê của bạn kịp nguội.

