Ba mươi tư phần trước đã đo giá của từng nguồn dữ liệu quan sát. Phần này đặt chúng cạnh nhau ở một tình huống cụ thể: bạn ngồi viết báo cáo sau sự cố, ba ngày sau khi nó xảy ra. Câu hỏi không phải "giữ dữ liệu có tốn không" mà "giữ cái nào, bao lâu, để trả lời được những câu mà báo cáo phải trả lời".
Bảng số liệu
Tính ở 1 000 yêu cầu mỗi giây, dùng các con số đo được ở chính sê-ri này: 67 byte mỗi dòng log (phần 31), 135 byte mỗi span và 4 span mỗi yêu cầu (phần 21), 2,16 byte mỗi mẫu với 900 chuỗi thu thập mỗi 15 giây (phần 19).
| Nguồn | Mỗi ngày | 7 ngày | 30 ngày | 90 ngày |
|---|---|---|---|---|
| Chỉ số | 0,01 GB | 0,1 GB | 0,3 GB | 0,9 GB |
| Log | 5,39 GB | 37,7 GB | 161,7 GB | 485,2 GB |
| Trace | 43,45 GB | 304 GB | 1 304 GB | 3 911 GB |
Trace tốn gấp 4 178 lần chỉ số mỗi ngày.
Hai cách đặt thời gian giữ:
| Tổng | |
|---|---|
| Giữ cả ba trong 30 ngày | 1 466 GB |
| Chỉ số 90 ngày, log 7 ngày, trace 3 ngày | 169 GB — tiết kiệm 88% |
Và sáu câu hỏi một báo cáo phải trả lời:
| Câu hỏi | Nguồn |
|---|---|
| Sự cố bắt đầu lúc nào | chỉ số |
| Ảnh hưởng bao nhiêu người | chỉ số |
| Chặng dịch vụ nào chậm | trace |
| Yêu cầu cụ thể nào thất bại | log |
| Hàm nào tốn CPU | hồ sơ |
| Đã từng xảy ra chưa | chỉ số — cần dữ liệu vài tháng tuổi |
Điều đáng nhớ
Ba trong sáu câu hỏi cần chỉ số, và chỉ số là nguồn rẻ nhất. 0,01 GB mỗi ngày so với 43,45 GB của trace. Sự trùng hợp đó không phải may mắn — nó đến từ việc chỉ số lưu trạng thái gộp chứ không lưu từng sự kiện, như phần 31 đã đo.
Câu hỏi khó nhất cần dữ liệu cũ nhất. "Đã từng xảy ra chưa" là câu quyết định báo cáo này dẫn tới một bản sửa lỗi hay một dòng ghi chú — và nó cần dữ liệu vài tháng tuổi. Với 0,9 GB cho 90 ngày, chỉ số là nguồn duy nhất đủ rẻ để giữ lâu như vậy.
Đặt thời gian giữ bằng nhau cho ba nguồn là lãng phí 88%. Giữ cả ba 30 ngày tốn 1 466 GB; giữ chỉ số 90 ngày, log 7 ngày, trace 3 ngày tốn 169 GB — và cách thứ hai còn giữ chỉ số lâu gấp ba lần. Nó vừa rẻ hơn vừa tốt hơn ở đúng chỗ quan trọng.
Trace là nguồn đắt nhất nhưng cũng là nguồn cần ít thời gian nhất. Câu hỏi mà nó trả lời — chặng nào chậm — được trả lời trong lúc điều tra, thường trong vài giờ đầu. Ba ngày sau, khi ngồi viết báo cáo, bạn đã biết câu trả lời đó rồi.
Vì sao
Khác biệt 4 178 lần đến thẳng từ mô hình dữ liệu, và phần 31 đã đo nó: chỉ số ghi trạng thái, log và trace ghi sự kiện.
Một Counter là một số; nó tăng lên chứ không dài ra. Dung lượng của nó tỷ lệ với số chuỗi thời gian nhân số lần thu thập — cả hai đều không phụ thuộc vào việc dịch vụ nhận một hay một triệu yêu cầu. Log và trace thì mỗi yêu cầu để lại dấu vết riêng.
Điều đó dẫn tới một tính chất quan trọng cho việc lưu dài hạn: chi phí giữ chỉ số không tăng khi lưu lượng tăng. Dịch vụ của bạn lớn gấp mười lần thì hoá đơn log và trace lớn gấp mười, còn hoá đơn chỉ số gần như không đổi.
Về phía giá trị, ba nguồn có ba khoảng hữu ích khác nhau. Trace hữu ích nhất trong lúc sự cố đang diễn ra, khi bạn cần biết đi tìm ở đâu. Log hữu ích ngay sau đó, khi bạn đã biết chỗ và cần biết chi tiết. Chỉ số hữu ích mãi về sau, vì nó là thứ duy nhất cho phép so sánh sự cố này với sự cố tháng trước.
Đặt cùng một thời gian giữ cho cả ba là bỏ qua sự khác biệt đó theo cả hai chiều: giữ trace quá lâu so với lúc nó còn hữu ích, và giữ chỉ số quá ngắn so với lúc nó cần nhất.
Nghĩa là gì trong thực tế
- Đặt ba thời gian giữ khác nhau, và đặt chúng theo thứ tự ngược với chi phí. Chỉ số lâu nhất, trace ngắn nhất. Đây là một trong ít quyết định mà rẻ hơn và tốt hơn đi cùng nhau.
- Trước khi cắt thời gian giữ, hãy cắt lấy mẫu trace. Phần 23 đã đo: lấy mẫu đuôi giữ 100% trace lỗi với 5,93% chi phí lưu. Áp nó trước rồi mới bàn tới số ngày.
- Ghi lại các chỉ số cấp SLO thành chuỗi riêng và giữ chúng hàng năm. Chúng vừa rẻ vừa là thứ bạn cần để trả lời "đã từng xảy ra chưa" và để báo cáo với người ngoài đội.
- Kiểm tra thời gian giữ trước khi lên lịch viết báo cáo. Nếu trace giữ 3 ngày và báo cáo viết vào ngày thứ tư, hãy chụp lại các trace quan trọng trong lúc điều tra, đừng đợi.
- Đừng ngoại suy con số của tôi cho hệ thống của bạn — hãy chạy lại phép tính với lưu lượng và số chuỗi thật của bạn. Tỷ lệ giữa ba nguồn thì giữ nguyên; giá trị tuyệt đối thì không.
Chỗ tôi không kết luận được
Bảng sáu câu hỏi là phán đoán của tôi, không phải phép đo. Đây là điểm quan trọng nhất cần nói rõ. Tôi liệt kê những câu mà tôi cho là một báo cáo sau sự cố phải trả lời, rồi gán nguồn dựa trên những gì các phần trước đã đo về khả năng của từng nguồn. Việc gán thì có căn cứ; việc chọn ra sáu câu hỏi đó thì không — nó phản ánh cách tôi nghĩ về sự cố, không phải một khảo sát trên các báo cáo thật.
Toàn bộ bảng dung lượng là phép nhân, không phải phép đo mới. Các con số đơn vị đều được đo trong sê-ri này, nhưng mọi ô trong bảng đều là chúng nhân với 1 000 yêu cầu mỗi giây và số ngày. Tỷ lệ nén thực tế, mức lấy mẫu, và số chuỗi thật của bạn đều làm con số đổi.
Tôi giả định trace không lấy mẫu. Con số 43,45 GB mỗi ngày là trường hợp giữ 100%. Với lấy mẫu 10% nó thành 4,3 GB và tỷ lệ so với chỉ số tụt từ 4 178 xuống 418 lần — vẫn rất lớn, nhưng khác hẳn. Phần lớn hệ thống thật có lấy mẫu, nên con số của tôi là cận trên.
Và tôi không đo chi phí truy vấn dữ liệu cũ. Phần 32 đã nói rõ giới hạn đó: tôi chỉ đo được khoảng xem tối đa 3 phút, nên không biết việc truy vấn một chỉ số 90 ngày tuổi tốn bao nhiêu so với 1 ngày tuổi. Nếu chi phí đó lớn, nó có thể làm thay đổi khuyến nghị "giữ chỉ số thật lâu" — và tôi không có số để nói.
Thử ba mươi giây
docker run --rm python:3.12-slim python - <<'EOF'
# Doi ba con so nay thanh so cua ban roi chay lai
RPS = 1000 # yeu cau moi giay
SPAN = 4 # span moi yeu cau
CHUOI = 900 # so chuoi thoi gian
CHU_KY = 15 # giay
# Ba hang so nay do duoc trong se-ri, khong can doi
B_LOG, B_SPAN, B_MAU = 67, 135, 2.16
GB = 1073741824
ngay = {
"chi so": CHUOI / CHU_KY * B_MAU * 86400 / GB,
"log": RPS * B_LOG * 86400 / GB,
"trace": RPS * SPAN * B_SPAN * 86400 / GB,
}
print("%-10s %12s %12s %12s" % ("nguon", "moi ngay", "30 ngay", "90 ngay"))
for k, v in ngay.items():
print("%-10s %9.2f GB %9.1f GB %9.1f GB" % (k, v, v*30, v*90))
print()
deu = sum(ngay.values()) * 30
lech = ngay["chi so"]*90 + ngay["log"]*7 + ngay["trace"]*3
print("ca ba giu 30 ngay : %8.0f GB" % deu)
print("chi so 90 / log 7 / trace 3 : %8.0f GB (tiet kiem %.0f%%)" % (lech, 100*(1-lech/deu)))
EOF
Nếu dòng cuối tiết kiệm được hơn tám mươi phần trăm, đó là khoản bạn đang trả để giữ trace lâu hơn lúc nó còn hữu ích.