Menu
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Đang tải...

Bài 18 — Alerting Strategy: Signal vs Noise

Operations Management for Tech Bài 18/60

Mở đầu — vì sao bài này quan trọng

Hãy tưởng tượng bạn là kỹ sư trực ca (on-call) cho một hệ thống thương mại điện tử. 3 giờ sáng, điện thoại rung liên hồi. Bạn bật dậy, tim đập nhanh, mở laptop... để rồi phát hiện đó chỉ là một cảnh báo "CPU node-07 chạm 82%" — con số đã tự trở về bình thường sau 4 phút mà chẳng cần ai làm gì. Bạn quay lại ngủ, nhưng 40 phút sau lại một cái page khác. Sáng hôm sau bạn đến công ty với đôi mắt thâm quầng, và điều tồi tệ nhất chưa xảy ra: dần dần bạn học cách phớt lờ tiếng chuông báo. Đến ngày hệ thống thật sự chết, cái page quan trọng bị chôn vùi giữa 200 cảnh báo rác, và không ai bấm vào.

Đây chính là alert fatigue (mệt mỏi vì cảnh báo) — kẻ thù số một của mọi đội vận hành. Và nó không đến từ việc thiếu cảnh báo, mà đến từ việc có quá nhiều cảnh báo sai chỗ.

Bài học hôm nay tập trung vào một câu hỏi tưởng đơn giản mà cực kỳ khó trả lời đúng: "Khi nào thì nên đánh thức một con người dậy?". Nguyên tắc vàng của toàn bộ bài này chỉ gói gọn trong một câu: Alert (page) chỉ khi cần con người can thiệp NGAY. Mọi thứ còn lại thuộc về log và dashboard. Phân biệt được signal (tín hiệu thật, đáng hành động) và noise (nhiễu, gây phân tâm) chính là kỹ năng làm nên một hệ thống vận hành trưởng thành. Chúng ta sẽ không bàn về cách thiết kế SLO (bài 8) hay cách viết postmortem (bài 11) — hôm nay chỉ tập trung vào chiến lược cảnh báo: cái gì nên page, cái gì nên ticket, cái gì chỉ nên nằm im trên dashboard.

Khái niệm cốt lõi

Signal vs Noise — định nghĩa cho rõ

Signal là một sự kiện mà: (1) phản ánh vấn đề đang ảnh hưởng hoặc sắp ảnh hưởng đến người dùng, (2) cần con người ra quyết định hoặc hành động, và (3) hành động đó không thể tự động hóa hoàn toàn ngay lúc này. Nếu thiếu bất kỳ điều kiện nào, đó là noise.

Ví dụ: "Tỷ lệ lỗi checkout tăng lên 15% trong 5 phút qua" — đây là signal, vì khách đang không mua được hàng và cần người vào điều tra. Còn "Disk /var trên server log đầy 71%" — đây là noise ở dạng page, vì nó chưa ảnh hưởng ai và còn cả tuần để xử lý; nó xứng đáng một ticket, không phải một cú đánh thức lúc nửa đêm.

Phân loại cảnh báo theo mức độ hành động

Cách tư duy hiệu quả nhất là phân loại mọi tín hiệu theo hành động cần thiết, không phải theo mức độ "nghiêm trọng nghe có vẻ đáng sợ". Bảng dưới đây là khung tôi khuyên các đội của mình dùng:

LoạiÝ nghĩaCần hành động khi nàoKênh gửi
Page (Critical)Đang/sắp gây hại người dùng, cần xử lý ngayNgay lập tức, kể cả 3h sángGọi điện / PagerDuty / Opsgenie push
Ticket (Warning)Vấn đề thật nhưng có thể chờ giờ hành chínhTrong vài giờ đến 1-2 ngàyJira / Slack channel / email
Log/Dashboard (Info)Dữ liệu để quan sát và điều tra sauKhông cần hành động chủ độngGrafana / Kibana / Datadog dashboard
Quy tắc thực dụng: nếu người nhận cảnh báo không cần làm gì khác ngoài "à, biết rồi", thì đó không phải là cảnh báo — đó là thông tin. Hãy chuyển nó xuống dashboard.

Symptom-based vs Cause-based alerting

Đây là nguyên lý quan trọng bậc nhất từ triết lý SRE của Google. Có hai cách để cảnh báo:

  • Cause-based (dựa trên nguyên nhân): cảnh báo khi một thành phần nội bộ trục trặc — "CPU cao", "số connection database gần max", "queue depth = 5000". Vấn đề: có hàng trăm nguyên nhân có thể xảy ra, và nhiều trong số đó không dẫn đến ảnh hưởng người dùng. Bạn sẽ bị chôn vùi trong noise.
  • Symptom-based (dựa trên triệu chứng): cảnh báo khi người dùng thật sự bị ảnh hưởng — "tỷ lệ HTTP 500 vượt ngưỡng", "độ trễ p99 của API thanh toán > 2 giây", "tỷ lệ đăng nhập thành công tụt xuống dưới 98%".
Nguyên tắc: Page dựa trên symptom, dùng cause để chẩn đoán. Bạn muốn được đánh thức khi khách hàng đau, không phải khi một cái CPU nào đó thở gấp. CPU cao mà người dùng vẫn vui vẻ thì đó là chuyện của giờ hành chính.

Bốn thuộc tính của một cảnh báo tốt

Một cảnh báo đáng để page phải thỏa mãn:

  • Actionable (có thể hành động): người nhận biết phải làm gì, hoặc ít nhất biết bắt đầu điều tra từ đâu (thường qua runbook đính kèm — xem bài 10).
  • Urgent (khẩn cấp): nếu chờ đến sáng thì đã quá muộn.
  • Real (thật): phản ánh vấn đề có thật, không phải trục trặc của chính hệ thống giám sát.
  • Novel (mới): không lặp lại một tình huống đã có cảnh báo khác bao trùm.

Ngưỡng, thời lượng và cửa sổ đánh giá

Một cảnh báo tốt hiếm khi kích hoạt tức thì. Ba tham số bạn phải chỉnh:

  • Threshold (ngưỡng): ví dụ tỷ lệ lỗi > 5%.
  • Duration (thời lượng): phải duy trì trong bao lâu, ví dụ "trong ít nhất 5 phút", để tránh page vì một cú nhấp nháy thoáng qua.
  • Evaluation window (cửa sổ): so với dữ liệu của khoảng thời gian nào — 5 phút gần nhất hay 30 phút?
Cặp for: 5m trong Prometheus Alertmanager chính là công cụ chống nhiễu quan trọng nhất, giúp lọc bỏ các gai tức thời (transient spike).

Tình huống thực tế

Ví dụ 1: Tiki và cơn bão cảnh báo mùa sale 11.11

Một đội hạ tầng tại một sàn thương mại điện tử lớn của Việt Nam (bối cảnh giả định dựa trên các đợt sale thật) chuẩn bị cho ngày 11.11. Họ có 340 quy tắc cảnh báo, phần lớn là cause-based: CPU, RAM, disk, số thread, GC pause của từng service. Đêm sale, lưu lượng tăng gấp 12 lần. Kết quả: trong 3 tiếng đầu, PagerDuty gửi 1.200 cú page. Kỹ sư trực ca không thể phân biệt được cái nào quan trọng, và một sự cố thật — cổng thanh toán VNPay timeout khiến 8% giao dịch thất bại — bị lẫn vào giữa hàng trăm cảnh báo "CPU 90%" vốn là điều hoàn toàn bình thường khi tải cao.

Phải mất 47 phút đội mới nhận ra vấn đề thanh toán, tương đương hàng tỷ đồng doanh thu bị mất trong giờ vàng.

Diễn giải: Sai lầm gốc rễ là họ page dựa trên nguyên nhân chứ không phải triệu chứng. CPU 90% trong đợt sale không phải sự cố — đó là hệ thống đang làm việc. Sau sự kiện, đội tái cấu trúc: tắt gần như toàn bộ cảnh báo cause-based (chuyển xuống dashboard), và chỉ giữ lại 12 cảnh báo symptom-based cấp critical, trong đó có "tỷ lệ giao dịch thanh toán thành công < 95% trong 3 phút". Mùa sale kế tiếp, họ nhận đúng 9 cú page cả đêm — mỗi cái đều là vấn đề thật.

Bài học: Số lượng cảnh báo không tỉ lệ thuận với độ an toàn. Ngược lại, càng nhiều noise càng dễ bỏ lỡ signal.

Ví dụ 2: Grab và câu chuyện "flapping alert"

Một đội tại một siêu ứng dụng gọi xe ở Đông Nam Á gặp tình trạng cảnh báo "API driver-matching latency p99 > 500ms" kích hoạt và tự tắt liên tục — cứ vài phút lại page rồi resolve, page rồi resolve. Hiện tượng này gọi là flapping (nhấp nháy). Trong một ca trực 8 tiếng, kỹ sư nhận 60 cặp page/resolve từ đúng một cảnh báo. Không ai buồn xem nữa.

Nguyên nhân: ngưỡng đặt ngay sát mức latency trung bình bình thường, và không có tham số duration. Độ trễ dao động quanh 500ms nên cảnh báo bật/tắt theo từng cơn.

Diễn giải: Đội áp dụng ba biện pháp. Thứ nhất, thêm for: 10m — chỉ page nếu p99 vượt ngưỡng liên tục 10 phút. Thứ hai, dùng hysteresis: kích hoạt ở 600ms nhưng chỉ giải trừ ở 450ms, tạo vùng đệm chống nhấp nháy. Thứ ba, gộp cảnh báo (grouping) theo dịch vụ để nhiều instance cùng lỗi chỉ tạo một page. Kết quả số page từ cảnh báo này giảm 95%, và quan trọng hơn, khi nó kêu thì mọi người tin đó là thật.

Bài học: Ngưỡng đặt sát mức bình thường + thiếu duration = cỗ máy sản xuất noise. Duration và hysteresis là hai vũ khí chống flapping.

Ví dụ 3: Một startup fintech và cảnh báo "quá tốt bụng"

Một startup fintech Việt (khoảng 15 kỹ sư) muốn "cẩn thận", nên họ cảnh báo mọi thứ ở mức Warning và gửi hết vào một kênh Slack #alerts. Sau 6 tháng, kênh này có trung bình 400 tin nhắn/ngày. Cả team đã tắt thông báo (mute) kênh đó từ lâu. Đây là dạng noise nguy hiểm nhất — cảnh báo tồn tại về mặt kỹ thuật nhưng đã chết về mặt con người.

Diễn giải: Họ chạy một buổi audit đơn giản: xuất toàn bộ cảnh báo 90 ngày, đếm số lần mỗi cảnh báo kích hoạt và số lần thực sự dẫn đến hành động. 78% cảnh báo chưa từng dẫn đến bất kỳ hành động nào. Đội xóa thẳng nhóm này. Với các cảnh báo thật, họ tách ba tier rõ ràng: critical → gọi điện, warning → tạo ticket Jira tự động, info → chỉ lên dashboard. Kênh #alerts còn lại khoảng 8-10 tin/ngày, và cả team bật thông báo lại.

Bài học: Một cảnh báo mà không ai đọc thì tệ hơn không có cảnh báo, vì nó tạo ảo giác an toàn. Hãy đo tỷ lệ actionability (bao nhiêu % cảnh báo dẫn đến hành động) — đây là chỉ số sức khỏe quan trọng nhất của hệ thống alerting.

Hướng dẫn từng bước

Dưới đây là quy trình thiết kế lại chiến lược cảnh báo cho một dịch vụ:

Bước 1 — Bắt đầu từ người dùng, không từ máy chủ. Liệt kê các "user journey" quan trọng: đăng nhập, tìm kiếm, thêm giỏ hàng, thanh toán. Với mỗi journey, xác định triệu chứng đo được khi nó hỏng (tỷ lệ lỗi, độ trễ, throughput). Đây sẽ là nguồn cho các cảnh báo symptom-based.

Bước 2 — Với mỗi tín hiệu tiềm năng, hỏi ba câu. (a) Nếu cái này kêu lúc 3h sáng, người trực có cần dậy làm gì ngay không? Nếu không → không phải page. (b) Có runbook hay ít nhất một bước điều tra đầu tiên không? Nếu không → viết trước khi bật cảnh báo. (c) Nếu bỏ qua đến sáng thì hậu quả là gì? Nếu "không sao" → hạ xuống ticket.

Bước 3 — Phân về đúng kênh. Ánh xạ mỗi cảnh báo vào bảng ba tier: Page / Ticket / Dashboard. Kiên quyết không để bất cứ thứ gì mang danh "để chắc ăn" nằm ở tier Page.

Bước 4 — Thêm duration và ngưỡng hợp lý. Đặt for tối thiểu 5 phút cho hầu hết cảnh báo. Với chỉ số dao động mạnh, thêm hysteresis (ngưỡng bật khác ngưỡng tắt). Đặt ngưỡng cách xa mức "bình thường lúc tải cao" để tránh false positive mùa cao điểm.

Bước 5 — Gộp và định tuyến (grouping & routing). Cấu hình để nhiều cảnh báo liên quan gộp thành một thông báo. Định tuyến theo dịch vụ đến đúng đội sở hữu, tránh page nhầm người.

Bước 6 — Đính kèm ngữ cảnh. Mỗi page phải có: mô tả triệu chứng, link runbook, link dashboard liên quan, và mức độ nghiêm trọng. Kỹ sư nửa tỉnh nửa mê lúc 3h sáng cần được dẫn đường, không phải đoán.

Bước 7 — Đo và lặp lại hàng tháng. Theo dõi: số page mỗi ca, tỷ lệ actionability, thời gian phản hồi, số cảnh báo bị bỏ qua. Định kỳ dọn dẹp cảnh báo chết. Chiến lược cảnh báo là thứ sống, không phải cấu hình một lần rồi quên.

Lỗi thường gặp & mẹo

Lỗi: Page cho mọi thứ "để chắc ăn". Đây là lỗi phổ biến nhất và tai hại nhất. Cẩn thận không có nghĩa là cảnh báo nhiều — nó có nghĩa là cảnh báo đúng. Mẹo: mặc định mọi tín hiệu mới đều vào dashboard; chỉ "thăng cấp" lên page khi có bằng chứng nó cần con người xử lý ngay.

Lỗi: Ngưỡng tĩnh cho hệ thống có mùa vụ. Ngưỡng "requests > 10.000/phút" hợp lý ngày thường nhưng vô nghĩa mùa sale. Mẹo: ưu tiên cảnh báo dựa trên tỷ lệ (error rate, success rate) thay vì con số tuyệt đối, vì tỷ lệ ổn định qua các mức tải.

Lỗi: Không phân biệt page ban đêm và giờ hành chính. Nhiều thứ đáng xử lý trong giờ làm nhưng không đáng đánh thức ai. Mẹo: dùng lịch định tuyến — một số cảnh báo chỉ page trong giờ hành chính, ngoài giờ thì chuyển thành ticket.

Lỗi: Quên xử lý flapping. Mẹo: luôn dùng duration (for) và cân nhắc hysteresis cho các chỉ số dao động.

Lỗi: Cảnh báo giám sát chính hệ thống giám sát. Nếu Prometheus chết, bạn sẽ không nhận được cảnh báo nào cả. Mẹo: dùng dead man's switch — một cảnh báo kêu khi không nhận được tín hiệu "còn sống" đều đặn, để phát hiện chính hệ thống monitoring bị sập.

Mẹo vàng — Quy tắc "one page, one action": mỗi page lý tưởng nên tương ứng với một hành động rõ ràng. Nếu người trực nhận page mà không biết làm gì, cảnh báo đó đã thất bại về mặt thiết kế, dù nó "đúng về mặt kỹ thuật".

Bài tập thực hành

  • Audit cảnh báo hiện tại. Lấy danh sách cảnh báo của một dịch vụ bạn đang vận hành (hoặc dùng danh sách giả định gồm 20 cảnh báo). Với mỗi cảnh báo, phân loại vào một trong ba tier: Page / Ticket / Dashboard. Đếm xem hiện có bao nhiêu % đang ở tier Page mà lẽ ra nên xuống thấp hơn.
  • Viết lại một cause-based thành symptom-based. Cho cảnh báo "Database CPU > 85%". Hãy viết lại thành một hoặc nhiều cảnh báo symptom-based phản ánh ảnh hưởng thật đến người dùng (gợi ý: độ trễ truy vấn, tỷ lệ lỗi của API phụ thuộc database).
  • Thiết kế cảnh báo chống flapping. Cho chỉ số "tỷ lệ lỗi API tìm kiếm" dao động quanh 4-6%. Hãy đề xuất: ngưỡng bật, ngưỡng tắt (hysteresis), giá trị for, và giải thích vì sao mỗi tham số được chọn.
  • Tính chi phí noise. Giả sử một cảnh báo rác page 5 lần/đêm, mỗi lần khiến kỹ sư mất 15 phút và giấc ngủ. Ước tính tác động lên năng suất và tinh thần đội trong một tháng, rồi viết một câu lập luận thuyết phục sếp cho phép xóa nó.

Tóm tắt

  • Nguyên tắc gốc: chỉ page khi cần con người can thiệp NGAY. Mọi thứ còn lại thuộc về ticket, log hoặc dashboard.
  • Signal vs Noise: signal là tín hiệu thật, khẩn cấp, có thể hành động và mới; mọi thứ khác là noise cần loại bỏ khỏi kênh page.
  • Page theo symptom, chẩn đoán bằng cause. Được đánh thức khi người dùng đau, không phải khi một cái CPU thở gấp.
  • Ba tier rõ ràng: Page (gọi điện) / Ticket (giờ hành chính) / Dashboard (quan sát). Kiên quyết không nhồi mọi thứ vào tier Page.
  • Chống noise bằng kỹ thuật: duration (for), hysteresis, grouping, routing theo giờ, và dead man's switch.
  • Alert fatigue giết chết độ tin cậy: một cảnh báo không ai đọc còn tệ hơn không có cảnh báo. Hãy đo tỷ lệ actionability và dọn dẹp cảnh báo chết hàng tháng.
Một hệ thống alerting trưởng thành không phải là hệ thống báo nhiều nhất, mà là hệ thống mà mỗi lần chuông kêu, cả đội đều tin: "Có chuyện thật rồi." Đó chính là đích đến của bài học này.