Khi sếp hỏi “Doanh thu hôm nay bao nhiêu?” và nỗi ám ảnh mang tên SQL tay
Hồi mới vào nghề, mình từng rơi vào một tình huống khá dở khóc dở cười. Cứ mỗi sáng thứ Hai, sếp lại nhắn tin: “Check giúp anh xem cuối tuần qua có bao nhiêu user mới? Tỉ lệ đơn thành công thế nào?”. Thế là mình lại lạch cạch SSH vào server, mở terminal gõ SELECT COUNT(*) mỏi tay rồi copy-paste vào Excel gửi sếp.
Lúc đó mình tự hỏi: Tại sao hệ thống đã có Grafana xịn để theo dõi CPU, RAM mà lại không đưa luôn mấy con số kinh doanh này lên dashboard? Nếu làm được, sếp chỉ cần nhìn màn hình là thấy. Mình cũng rảnh tay để làm việc khác thay vì làm “máy xuất báo cáo” chạy bằng cơm.
Tuy nhiên, team Developer thường bận chạy deadline tính năng mới. Họ không có 2-3 ngày để tích hợp Prometheus Client vào từng dòng code ứng dụng. Lúc này, Prometheus SQL Exporter chính là giải pháp “mì ăn liền” nhưng cực kỳ hiệu quả cho dân Ops.
Tại sao không nên sửa code App để lấy Business Metrics?
Cách làm “sách giáo khoa” là dùng thư viện Prometheus (như client_golang hay client_python) ngay trong code. Nhưng thực tế triển khai thường vấp phải 3 rào cản lớn:
- Legacy Code: Những ứng dụng cũ, code rối rắm đến mức không ai dám động vào vì sợ lỗi dây chuyền.
- Tốn tài nguyên Dev: Việc thêm metrics, viết test case và chờ deploy có thể mất cả tuần làm việc.
- Sự phụ thuộc: Mỗi khi sếp muốn thêm một chỉ số mới, bạn lại phải yêu cầu Dev sửa code, build lại image và deploy từ đầu.
Dữ liệu kinh doanh thường nằm sẵn trong các bảng Database như MySQL hay PostgreSQL. Vậy tại sao chúng ta không lấy trực tiếp từ đó cho nhanh?
Các giải pháp phổ biến và nhược điểm
Trước khi chốt dùng SQL Exporter, mình cũng đã thử qua vài cách:
- Chạy Cronjob bằng Python: Script sẽ query DB rồi đẩy kết quả vào Pushgateway. Cách này khá ổn lúc đầu. Tuy nhiên, khi số lượng chỉ số lên tới 50-100, việc quản lý đống script này trở thành một thảm họa bảo trì.
- Dùng Telegraf SQL Input: Đây là công cụ mạnh nhưng cấu hình hơi rườm rà nếu team bạn đã quen dùng hệ sinh thái Prometheus thuần túy.
Giải pháp tối ưu: Prometheus SQL Exporter
Công cụ này đóng vai trò như một “thông dịch viên”. Nó kết nối tới Database, chạy các câu lệnh SQL bạn định nghĩa, sau đó expose dữ liệu ra endpoint /metrics để Prometheus vào lấy.
Điểm cộng lớn nhất là bạn không cần chạm vào một dòng code ứng dụng nào. Chỉ cần viết file cấu hình YAML là xong. Cực kỳ an toàn cho các hệ thống đang chạy ổn định.
Bước 1: Chuẩn bị tài khoản Database
Đừng dùng tài khoản root. Hãy tạo một user chỉ có quyền SELECT trên các bảng cần thiết để đảm bảo bảo mật.
-- Ví dụ cho MySQL
CREATE USER 'sql_exporter'@'%' IDENTIFIED BY 'password_bao_mat';
GRANT SELECT ON your_db.* TO 'sql_exporter'@'%';
FLUSH PRIVILEGES;
Bước 2: Cấu hình SQL Exporter (config.yml)
Đây là phần quan trọng nhất. Giả sử bạn cần theo dõi số lượng đơn hàng theo trạng thái để biết hệ thống có đang bị nghẽn thanh toán hay không.
# config.yml
jobs:
- name: "business_metrics"
interval: '1m' # Cứ 60 giây chạy query một lần
connections:
- 'sql_exporter:password_bao_mat@tcp(db_host:3306)/your_db'
queries:
- name: "orders_total"
help: "Tổng số đơn hàng theo trạng thái"
labels:
- "status"
values:
- "count"
query: |
SELECT status, count(*) as count
FROM orders
GROUP BY status;
SQL Exporter sẽ tự động chuyển kết quả thành các metric như orders_total{status="completed"} hoặc orders_total{status="pending"}.
Bước 3: Triển khai nhanh bằng Docker Compose
Dùng Docker giúp bạn quản lý version và môi trường đồng nhất. Khi cần cập nhật câu lệnh SQL, bạn chỉ cần sửa file config rồi restart container trong vài giây.
version: '3'
services:
sql-exporter:
image: burningalchemist/sql_exporter:latest
volumes:
- ./config.yml:/config.yml
command:
- "--config.file=/config.yml"
ports:
- "9399:9399"
restart: always
Kinh nghiệm thực chiến: Những lỗi dễ gây “sập” hệ thống
Qua nhiều dự án lớn, mình rút ra 3 bài học xương máu để tránh làm gián đoạn dịch vụ:
1. Tránh xa các Query nặng trên bảng lớn
Sai lầm lớn nhất là chạy COUNT(*) trên bảng có 50-100 triệu dòng mà không có index phù hợp. Việc này có thể khiến CPU Database vọt lên 100% ngay lập tức.
Lời khuyên: Luôn dùng EXPLAIN để kiểm tra query. Nếu bảng quá lớn, hãy query trên Slave (Read-replica) để không ảnh hưởng đến người dùng cuối.
2. Cẩn thận với High Cardinality
Đừng bao giờ đưa user_id hay order_id vào label của metric. Nếu bạn có 1 triệu user, Prometheus sẽ phải lưu trữ 1 triệu chuỗi thời gian (time series) khác nhau. Điều này sẽ làm RAM của server Prometheus cạn kiệt chỉ sau vài giờ.
3. Tần suất lấy dữ liệu (Interval)
Dữ liệu kinh doanh không cần cập nhật từng giây như CPU. Thay vì để 15 giây, hãy để 1 phút hoặc 5 phút. Điều này vừa giúp giảm tải cho Database, vừa giúp dashboard chạy mượt mà hơn.
Tổng kết
Tùy vào nhu cầu mà bạn chọn cách tiếp cận phù hợp:
- Nếu cần đo độ trễ (latency) của từng hàm code: Dùng Prometheus Client.
- Nếu cần theo dõi doanh thu, số lượng user nhanh chóng: SQL Exporter là lựa chọn số 1.
Việc đưa Business Metrics lên Grafana không chỉ giúp team Ops rảnh tay. Nó còn giúp nâng tầm giá trị của team kỹ thuật. Khi bạn show được dashboard doanh thu real-time cho ban giám đốc, tiếng nói của team sẽ có trọng lượng hơn rất nhiều.

