Cơn ác mộng mang tên Database “im hơi lặng tiếng”
Bạn đã bao giờ rơi vào cảnh 2 giờ sáng bị dựng dậy vì web chậm, còn database thì như một “hộp đen” không lời giải đáp? Hồi mới vào nghề, phản xạ duy nhất của mình là SSH vào server, gõ loạn xạ top, htop rồi soi iotop xem ổ cứng có đang “gào thét” không. Nếu mọi thứ vẫn xanh, mình lại phải lọ mọ grep hàng GB log file để tìm Slow Query. Cách làm này vừa khổ, vừa hên xui.
Thú thực, sau nửa năm trực chiến cùng bộ đôi Prometheus và Grafana, mình mới hiểu giá trị của việc quan sát dữ liệu. Có dashboard giống như lái xe có đầy đủ bảng đồng hồ đo tốc độ và nhiệt độ vậy. Mọi thông số từ production đều hiện rõ qua con số, không còn chỗ cho những câu cảm thán kiểu “hình như DB hơi lag”.
Cân đo đong đếm các giải pháp Monitoring
Trước khi chốt phương án Prometheus Exporter, mình từng kinh qua vài lựa chọn khác:
- Dùng hàng Cloud (CloudWatch, Azure Monitor): Cực kỳ nhàn vì chỉ cần vài cú click. Thế nhưng, hóa đơn cuối tháng sẽ khiến bạn giật mình nếu muốn theo dõi chi tiết (custom metrics) ở tần suất cao.
- Zabbix/Netdata: Zabbix cảnh báo rất tốt nhưng giao diện dashboard lại hơi “hoài cổ”. Việc tùy biến dữ liệu dạng chuỗi thời gian (time-series) cũng là một thử thách lớn. Netdata thì quá chi tiết mức OS, đôi khi làm mình bị nhiễu thông tin cần thiết.
- Prometheus Exporter: Đây là lựa chọn tối ưu nhất với mình. Exporter truy vấn trực tiếp vào
performance_schemacủa MySQL hoặcpg_stat_activitycủa Postgres. Nó lấy được những chỉ số “sâu thẳm” mà hệ điều hành không bao giờ chạm tới được.
Điểm cộng và điểm trừ của Exporter
Ưu điểm:
- Bắt được các chỉ số nội bộ: tỉ lệ hit buffer pool, lock giao dịch, hay độ trễ replication chính xác đến từng giây.
- Tốn rất ít tài nguyên hệ thống (overhead cực thấp, chỉ chiếm khoảng 1-2% CPU).
- Cộng đồng hỗ trợ cực mạnh. Bạn chỉ cần import mẫu dashboard Grafana có sẵn là dùng được ngay.
Nhược điểm:
- Phải cài thêm một agent nhỏ trên server hoặc chạy container đi kèm.
- Cần quản lý cấu hình bảo mật chặt chẽ cho port mà Exporter đang lắng nghe.
Bắt tay vào giám sát MySQL với mysqld_exporter
Để đảm bảo an toàn, tuyệt đối đừng dùng user root. Bạn nên tạo một user riêng trong MySQL với quyền hạn tối thiểu để Exporter làm việc.
-- Tạo user giám sát an toàn
CREATE USER 'exporter'@'localhost' IDENTIFIED BY 'MatKhauSieuKho123' WITH MAX_USER_CONNECTIONS 3;
GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'localhost';
FLUSH PRIVILEGES;
Nếu bạn thích sự gọn gàng, hãy dùng Docker Compose. Cách này giúp việc quản lý phiên bản và môi trường trở nên cực kỳ đơn giản.
# docker-compose.yml
services:
mysql-exporter:
image: prom/mysqld-exporter
container_name: mysql-exporter
environment:
- DATA_SOURCE_NAME=exporter:MatKhauSieuKho123@(mysql-host:3306)/
ports:
- "9104:9104"
restart: always
Mẹo nhỏ: Để theo dõi được Slow Query hiệu quả, hãy chắc chắn bạn đã bật slow_query_log. Exporter sẽ lấy dữ liệu từ information_schema để vẽ lên biểu đồ cho bạn.
Cài đặt giám sát PostgreSQL với postgres_exporter
Với PostgreSQL, sức mạnh nằm ở Stats Collector. Mình thường kết hợp thêm pg_stat_statements để soi tận gốc những query đang “ngốn” tài nguyên nhất.
-- Thêm dòng này vào postgresql.conf và restart DB
shared_preload_libraries = 'pg_stat_statements'
-- Sau đó cấu hình user cho exporter
CREATE USER postgres_exporter PASSWORD 'MatKhauSieuKho123';
ALTER USER postgres_exporter SET SEARCH_PATH TO postgres_exporter,pg_catalog;
GRANT pg_monitor TO postgres_exporter;
Khởi chạy Exporter cho Postgres bằng một câu lệnh duy nhất:
docker run -d \
--name postgres-exporter \
-e DATA_SOURCE_NAME="postgresql://postgres_exporter:MatKhauSieuKho123@db-host:5432/postgres?sslmode=disable" \
-p 9187:9187 \
prometheuscommunity/postgres-exporter
4 chỉ số “vàng” không thể rời mắt
Sau nhiều lần “chữa cháy”, đây là danh sách các chỉ số mình luôn ưu tiên đặt ở vị trí dễ nhìn nhất trên Dashboard.
1. Connection Pool (Số lượng kết nối)
Khi active_connections chạm ngưỡng 90% của max_connections, hệ thống sẽ bắt đầu từ chối người dùng. Mình thường cài cảnh báo (Alert) ở mức 80% để kịp thời xử lý trước khi thảm họa xảy ra.
2. Slow Queries (Truy vấn chậm)
Đừng chỉ nhìn vào số lượng, hãy nhìn vào xu hướng. Nếu sau một đợt deploy, số query chạy trên 100ms tăng vọt, chắc chắn team dev đã quên đánh Index ở đâu đó rồi.
3. Replication Lag (Độ trễ bản sao)
Với hệ thống Master-Slave, lag là chỉ số sống còn. Nếu Slave trễ quá 5-10 giây, dữ liệu người dùng xem được sẽ bị cũ. Trong MySQL, hãy bám sát chỉ số seconds_behind_master.
4. Cache Hit Ratio
Một database khỏe mạnh cần có tỉ lệ Cache Hit trên 95%. Nếu con số này sụt giảm, DB đang phải đọc từ ổ cứng quá nhiều. Lúc này, nâng cấp RAM là giải pháp không thể trì hoãn.
Case study thực tế: Khi 1 query “treo” làm phình 50GB ổ cứng
Có lần, nhờ biểu đồ của postgres_exporter, mình phát hiện một transaction bị trạng thái “Idle in transaction” suốt 2 tiếng. Nó giữ lock khiến tiến trình Auto-vacuum không thể dọn dẹp, làm dung lượng DB phình thêm 50GB chỉ sau một đêm. Nếu chỉ dùng lệnh ps aux thông thường, mình chắc chắn sẽ bỏ sót lỗi này.
Lời khuyên của mình: Đừng đợi đến khi có sự cố mới cài monitoring. Hãy triển khai ngay từ môi trường Staging. Việc nhìn vào biểu đồ mỗi ngày giúp bạn hiểu được “nhịp thở” của database, từ đó dự đoán được thời điểm cần scale tài nguyên trước khi hệ thống kịp sập.
Cuối cùng, việc làm chủ các con số giúp bạn tự tin hơn khi làm việc với team Dev. Thay vì nói “Em thấy DB hơi chậm”, hãy nói “Query X đang chiếm 40% IOPS và gây lag 5 giây cho Slave”. Nghe chuyên nghiệp và thuyết phục hơn nhiều, đúng không?
