Phần 9 đo chi phí ghi một chỉ số. Bài này đo chặng tiếp theo: Prometheus tự đi lấy nó về.
Một lần quét tốn bao nhiêu
Một điểm /metrics với số giá trị nhãn thay đổi, đo từ bên ngoài container:
| Số giá trị nhãn | Byte mỗi lần quét | Thời gian quét | RAM của ứng dụng |
|---|---|---|---|
| 100 | 96.760 | 1 / 1 / 1 ms | 9,66 MiB |
| 1.000 | 982.252 | 8 / 9 / 7 ms | 16,46 MiB |
| 10.000 | 9.981.172 | 83 / 75 / 71 ms | 77,56 MiB |
| 50.000 | 50.616.372 | 465 / 400 / 441 ms | 308,8 MiB |
Tuyến tính: khoảng 1.012 byte và 8,7 ms cho mỗi 1.000 giá trị nhãn.
Ở 50.000 nhãn, mỗi lần quét chuyển 50,6 MB. Với chu kỳ 15 giây:
50,6 MB × 4 lần/phút × 60 × 24 = 291 GB mỗi ngày
Cho một mục tiêu. Nhân với số bản sao và số dịch vụ.
Ba con số Prometheus tự sinh
Với 2.000 giá trị nhãn và chu kỳ quét 5 giây, Prometheus tự ghi lại thông tin về chính lần quét đó:
scrape_duration_seconds = 0,0547 s (54,7 ms)
scrape_samples_scraped = 30.000
up = 1
Ba chỉ số này có sẵn ở mọi cài đặt, không cần thêm gì, và chúng là công cụ chẩn đoán tốt nhất cho chính hệ thống giám sát.
Quy tắc bắt buộc của mô hình kéo:
scrape_duration < scrape_timeout < scrape_interval
Vượt qua thì lần quét bị bỏ, và dữ liệu có lỗ hổng mà không có cảnh báo nào. Với mặc định scrape_timeout: 10s, bảng trên cho thấy bạn còn chỗ tới khoảng một triệu giá trị nhãn — nhưng băng thông và bộ nhớ sập từ rất lâu trước đó.
Đặt cảnh báo lên chính nó:
- alert: QuetChamDan
expr: scrape_duration_seconds / scrape_timeout_seconds > 0.5
for: 10m
Khi mục tiêu chết
Đo bằng cách giết container mục tiêu và hỏi Prometheus liên tục:
| Thời điểm | up |
Chỉ số cũ |
|---|---|---|
| Trước khi giết | 1 | 0 (giá trị thật của nó) |
| Sau 3 giây | 0 | — |
| Sau 8 giây | 0 | KHÔNG CÓ KẾT QUẢ |
| Sau 159 giây | 0 | KHÔNG CÓ KẾT QUẢ |
Nhưng truy vấn theo khoảng:
http_requests_total{path="/api/v1/tuyen-0"}[10m]
vẫn trả về 6 điểm dữ liệu.
Dữ liệu không mất. Prometheus ghi một dấu hết hạn ngay khi lần quét đầu tiên thất bại, nên truy vấn tức thời không thấy chuỗi nữa, còn truy vấn theo khoảng vẫn đọc được lịch sử.
Điều này khác với hiểu biết phổ biến rằng "Prometheus giữ giá trị cũ trong 5 phút". Cửa sổ 5 phút đó là khoảng nhìn lại cho các chuỗi vẫn tồn tại nhưng chưa có mẫu mới, không áp dụng khi mục tiêu biến mất — lúc đó dấu hết hạn có tác dụng ngay.
Hệ quả nguy hiểm cho cảnh báo
Một cảnh báo viết thế này:
rate(http_errors_total[5m]) > 10
ngừng kêu khi dịch vụ chết hoàn toàn, vì chuỗi không còn tồn tại và biểu thức không có gì để so sánh.
Nghĩa là sự cố nghiêm trọng nhất — dịch vụ chết hẳn — là sự cố mà cảnh báo dựa trên chỉ số nghiệp vụ không bắt được.
Luôn phải có một cảnh báo riêng:
- alert: MucTieuChet
expr: up == 0
for: 2m
Và với những chuỗi chỉ xuất hiện khi có sự kiện — ví dụ http_errors_total chỉ được tạo sau lỗi đầu tiên — dùng absent():
absent(up{job="dich-vu-cua-toi"}) == 1
Kéo hay đẩy
Mô hình kéo có ba tính chất mà bảng trên cho thấy trực tiếp:
up là miễn phí. Vì Prometheus chủ động đi lấy, nó biết ngay khi không lấy được. Với mô hình đẩy, "không nhận được dữ liệu" và "dịch vụ không có gì để gửi" không phân biệt được.
Mục tiêu không cần biết gì về hệ thống giám sát. Ứng dụng chỉ mở một cổng HTTP; đổi địa chỉ Prometheus không cần đụng vào ứng dụng.
Nhưng Prometheus phải đến được mục tiêu. Với tiến trình sống ngắn — job theo lô, hàm serverless — không có gì để quét, và đó là lý do Pushgateway tồn tại. Nó là ngoại lệ, không phải mặc định, và dùng sai nó sẽ mất mọi lợi ích ở trên.
Chỗ phép đo này không nói tới
Tôi đo một mục tiêu. Prometheus quét hàng nghìn mục tiêu song song, và chi phí phía Prometheus — phân tích, nén, ghi TSDB — tôi chưa đo. Phần 19 sẽ đo phần lưu trữ.
Tôi cũng không đo honor_timestamps, metric_relabel_configs (thứ lọc bớt chuỗi trước khi ghi, và là cách chữa hữu hiệu nhất cho bảng đầu bài), hay giao thức nén mới của Prometheus.
Con số scrape_duration của tôi đo trên mạng Docker nội bộ với độ trễ gần 0. Qua mạng thật, nó cộng thêm ít nhất một vòng khứ hồi.
Thử ba mươi giây
Xem hệ thống giám sát của bạn đang tự nói gì về chính nó:
# Muc tieu nao quet lau nhat
topk(10, scrape_duration_seconds)
# Muc tieu nao nhieu mau nhat
topk(10, scrape_samples_scraped)
# Co muc tieu nao sap cham tran thoi gian khong
scrape_duration_seconds / on(job) group_left() scrape_timeout_seconds > 0.5
# Muc tieu nao dang chet
up == 0
# Tong so chuoi thoi gian dang giu
prometheus_tsdb_head_series
Truy vấn thứ ba là truy vấn ít người chạy nhất và hay cứu nhất: nó chỉ ra mục tiêu sắp vượt thời gian chờ trước khi dữ liệu bắt đầu có lỗ hổng.
Phần sau: nhãn và bùng nổ chiều — đo khi số chuỗi tăng vọt.