Giải mã nút thắt cổ chai ẩn giấu trong ClickHouse: Bài học từ hệ thống Billing của Cloudflare
Khi hệ thống billing của Cloudflare đột ngột chậm lại sau một đợt di chuyển dữ liệu, đội ngũ kỹ thuật đã phát hiện ra một nút thắt cổ chai nằm sâu trong cơ chế xử lý của ClickHouse. Đây là hành trình...
Tại Cloudflare, ClickHouse đóng vai trò là nền tảng OLAP (Online Analytical Processing) chủ chốt, xử lý hàng triệu truy vấn mỗi ngày để tính toán hóa đơn cho khách hàng. Tuy nhiên, sau một đợt di chuyển dữ liệu (migration), các tác vụ tổng hợp dữ liệu hàng ngày vốn rất quan trọng cho việc xuất hóa đơn đã trở nên chậm chạp một cách bất thường.
Thách thức từ quy mô Petabyte
Hệ thống “Ready-Analytics” của Cloudflare lưu trữ hơn 100 petabyte dữ liệu trên hàng chục cụm server. Để quản lý việc lưu giữ dữ liệu (retention policy) linh hoạt hơn cho từng namespace, đội ngũ kỹ thuật đã thay đổi khóa phân vùng (partitioning key) từ (day) sang (namespace, day). Giả định ban đầu là việc này sẽ không ảnh hưởng đến hiệu suất vì mỗi truy vấn đều được lọc theo namespace cụ thể.
Tuy nhiên, thực tế lại khác. Khi số lượng part dữ liệu tăng lên, thời gian truy vấn bắt đầu kéo dài đáng kể. Các chỉ số thông thường như I/O, bộ nhớ hay số dòng quét đều không cho thấy dấu hiệu bất thường, dẫn đến một cuộc điều tra sâu vào nội tại của ClickHouse.
Truy vết bằng Flame Graphs
Sử dụng trace_log để tạo các flame graph, đội ngũ kỹ thuật phát hiện ra rằng 45% thời gian CPU của các truy vấn SELECT bị tiêu tốn trong giai đoạn lập kế hoạch truy vấn (query planning). Cụ thể, hệ thống đang gặp tình trạng tranh chấp khóa (lock contention) nghiêm trọng tại mutex MergeTreeData. Mỗi khi lập kế hoạch, các luồng (thread) phải chờ đợi để có được quyền truy cập độc quyền vào danh sách part, sau đó sao chép toàn bộ danh sách này.
Bộ ba bản vá tối ưu hóa
Để giải quyết vấn đề, Cloudflare đã thực hiện ba cải tiến kỹ thuật quan trọng:
- Sử dụng Shared Lock: Thay thế khóa độc quyền bằng
std::shared_lock, cho phép nhiều luồng lập kế hoạch truy vấn cùng truy cập vào danh sách part mà không cần chờ đợi. - Tối ưu hóa sao chép Vector: Thay vì sao chép toàn bộ danh sách part mỗi khi truy vấn, hệ thống chuyển sang sử dụng bản sao chia sẻ (shared copy). Các thao tác chỉ đọc sẽ dùng chung bản sao này, giúp giảm đáng kể chi phí CPU.
- Tìm kiếm nhị phân (Binary Search): Triển khai tìm kiếm nhị phân dựa trên namespace trong partition ID. Điều này giúp loại bỏ nhanh chóng các part không liên quan thay vì phải quét tuyến tính (linear scan) qua toàn bộ danh sách.
Kết quả là thời gian truy vấn đã giảm 50% và không còn phụ thuộc vào tổng số lượng part trong cụm. Những cải tiến này không chỉ giúp hệ thống billing hoạt động ổn định trở lại mà còn được đóng góp ngược lại cho cộng đồng ClickHouse (từ phiên bản 25.11).
Câu chuyện này là minh chứng cho thấy ngay cả những thay đổi tưởng chừng nhỏ trong kiến trúc cũng có thể dẫn đến những hệ quả lớn về hiệu suất, đòi hỏi sự hiểu biết sâu sắc về cách các công cụ vận hành ở quy mô lớn.
Nguồn tham khảo: Cloudflare Blog



No Comment! Be the first one.