Menu
ESC

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

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

Đang tải...

Bài 10 — Runbook: Cấu trúc và Vận hành

Operations Management for Tech Bài 10/60

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

Hãy hình dung một tình huống rất thực tế. Lúc 2 giờ sáng, điện thoại của bạn rung lên. Cảnh báo: "Database CPU > 90% kéo dài 10 phút". Bạn vừa tỉnh giấc, đầu óc còn mơ màng, tim đập nhanh vì áp lực. Trong khoảnh khắc đó, bạn có hai lựa chọn. Một là ngồi dậy, mở laptop và bắt đầu... đoán mò: đăng nhập vào đâu? Chạy lệnh gì? Query nào đang ngốn tài nguyên? Có được phép kill query không? Hai là bạn mở một tài liệu đã được viết sẵn, làm theo từng bước đã được kiểm chứng, và trong 15 phút hệ thống trở lại bình thường.

Sự khác biệt giữa hai kịch bản đó chính là runbook.

Ở các bài trước, chúng ta đã nói về vòng đời của incident, về văn hóa on-call, về vai trò của người trực. Nhưng có một điểm mấu chốt mà nhiều đội bỏ qua: kiến thức xử lý sự cố không thể chỉ nằm trong đầu một vài người "cứng tay". Khi người đó nghỉ phép, nghỉ việc, hay đơn giản là đang ngủ say lúc 3 giờ sáng, cả đội sẽ khốn khổ. Runbook chính là cách chúng ta chuyển hóa kiến thức cá nhân thành tài sản chung của tổ chức — để bất kỳ ai trực on-call, dù mới hay cũ, đều có thể xử lý một loại sự cố cụ thể một cách bình tĩnh và nhất quán.

Bài học này tập trung hoàn toàn vào runbook: nó là gì, cấu trúc chuẩn ra sao, làm sao viết một runbook thực sự dùng được, và làm sao vận hành để nó không trở thành tài liệu "chết" nằm phủ bụi trong wiki.

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

Runbook là gì

Runbook là một tài liệu hướng dẫn từng bước (step-by-step) giúp người trực on-call xử lý một loại sự cố cụ thể. Điểm nhấn nằm ở chữ "một loại cụ thể". Runbook không phải là cẩm nang tổng quát kiểu "làm sao để vận hành hệ thống". Nó là câu trả lời cho một tình huống được xác định rõ, ví dụ: "Database CPU vượt 90%", "API trả lỗi 5xx tăng đột biến", "Hàng đợi (queue) xử lý đơn hàng bị nghẽn hơn 5000 message", hay "Đĩa của log server đầy 95%".

Mỗi cảnh báo (alert) mà bạn cấu hình lý tưởng nên đi kèm một runbook tương ứng. Khi cảnh báo nổ, người trực chỉ cần bấm vào đường link trong cảnh báo đó và mở đúng runbook cần dùng.

Phân biệt runbook và playbook

Nhiều người dùng lẫn lộn hai từ này. Cách phân biệt phổ biến nhất trong ngành:

  • Runbook thiên về thao tác kỹ thuật cụ thể để xử lý một triệu chứng: chạy lệnh gì, kiểm tra dashboard nào, restart service nào.
  • Playbook thường rộng hơ, mang tính điều phối (orchestration): huy động ai, giao tiếp với khách hàng ra sao, khi nào leo thang (escalate), cách phối hợp giữa nhiều đội trong một sự cố lớn.
Trong thực tế, ranh giới này không tuyệt đối và mỗi công ty có quy ước riêng. Điều quan trọng là bạn nhất quán trong tổ chức của mình. Bài này tập trung vào runbook — tài liệu tác nghiệp kỹ thuật ở tuyến đầu.

Cấu trúc chuẩn của một runbook

Một runbook tốt nên có các phần sau, theo đúng thứ tự mà người đang stress lúc nửa đêm cần đọc:

1. Trigger (Điều kiện kích hoạt). Runbook này dùng khi nào? Mô tả chính xác cảnh báo hoặc triệu chứng dẫn đến việc mở tài liệu này. Ví dụ: "Alert db-cpu-high nổ khi CPU của cụm database production vượt 90% liên tục 5 phút."

2. Impact (Mức độ ảnh hưởng). Nếu không xử lý, chuyện gì xảy ra? Ai bị ảnh hưởng — khách hàng, đơn hàng, doanh thu? Phần này giúp người trực đánh giá mức độ khẩn cấp và quyết định có cần leo thang ngay không.

3. Diagnosis (Chẩn đoán). Các bước để xác nhận vấn đề và tìm nguyên nhân trực tiếp. Kèm theo link tới dashboard, lệnh truy vấn cụ thể, log cần xem. Đây là phần "nhìn" trước khi "làm".

4. Mitigation (Giảm thiểu / Khắc phục tạm thời). Các bước cụ thể để đưa hệ thống trở lại trạng thái ổn định. Ưu tiên hàng đầu là cầm máu (stop the bleeding) — khôi phục dịch vụ cho khách hàng, chưa cần tìm nguyên nhân gốc rễ vội.

5. Escalation (Leo thang). Nếu các bước trên không hiệu quả sau X phút, gọi ai? Số điện thoại, kênh Slack, tên đội chịu trách nhiệm hệ thống.

6. Verification (Xác minh). Làm sao biết vấn đề đã được giải quyết? Chỉ số nào cần trở về ngưỡng bình thường?

7. Rollback / Post-action. Nếu bước khắc phục là tạm thời (ví dụ tăng tài nguyên thủ công), cần làm gì tiếp theo, và ghi chú lại cho postmortem.

Nguyên tắc vàng khi viết

Runbook phải được viết cho người ít kinh nghiệm nhất có thể trực on-call, không phải cho tác giả. Nếu một kỹ sư mới vào 2 tuần đọc runbook mà không hiểu phải làm gì, runbook đó chưa đạt. Lệnh phải copy-paste được, không chứa placeholder mơ hồ kiểu <your-server> mà không giải thích lấy giá trị ở đâu. Mỗi bước nguy hiểm (như xóa dữ liệu, restart production) phải có cảnh báo rõ ràng.

Tình huống thực tế

Ví dụ 1 — Tiki: Database CPU tăng vọt giờ cao điểm

Một sàn thương mại điện tử lớn tại Việt Nam (tạm gọi theo mô hình của Tiki) gặp tình trạng lặp lại: cứ vào khung 20h–22h, cụm database chính báo CPU trên 90%, dẫn đến trang chi tiết sản phẩm chậm, tỷ lệ thêm vào giỏ hàng giảm rõ rệt.

Ban đầu, mỗi lần cảnh báo nổ, người trực lại loay hoay theo cách riêng. Anh A thì restart read replica, chị B thì đi tìm slow query, có người thì gọi ngay cho DBA senior lúc nửa đêm. Thời gian xử lý trung bình (MTTR) dao động từ 20 đến 70 phút tùy vào việc ai đang trực.

Đội quyết định viết một runbook cho chính alert này. Cấu trúc như sau. Trigger: alert prod-db-cpu-high. Diagnosis: bước 1 mở dashboard Grafana theo link, xem panel "Active Queries"; bước 2 chạy đúng câu lệnh SELECT trên pg_stat_activity (đã ghi sẵn trong runbook) để tìm query chạy lâu nhất. Mitigation: nếu phát hiện một query báo cáo phân tích đang chạy nặng, chạy lệnh kill query đó theo cú pháp có sẵn; nếu do lượng truy cập tăng tự nhiên, chuyển traffic đọc sang read replica bằng feature flag đã ghi rõ. Escalation: nếu sau 15 phút CPU chưa giảm, gọi DBA on-call theo số trong PagerDuty.

Bài học rút ra: Sau khi có runbook, MTTR cho loại sự cố này giảm còn khoảng 8–12 phút, và quan trọng hơn là ổn định — không còn phụ thuộc vào việc ai đang trực. Runbook đã biến kiến thức của DBA senior thành tài sản mà cả đội dùng được.

Ví dụ 2 — Startup fintech ở Singapore: sự nguy hiểm của runbook lỗi thời

Một startup fintech tại Singapore có runbook xử lý sự cố "cổng thanh toán trả timeout". Runbook được viết rất kỹ từ 8 tháng trước, hướng dẫn restart service payment-gateway-v1 qua một script cụ thể.

Vấn đề là gì? Ba tháng trước đó, đội đã migrate sang payment-gateway-v2 chạy trên Kubernetes, và script cũ không còn tác dụng. Nhưng runbook thì không ai cập nhật. Đêm xảy ra sự cố thật, một kỹ sư mới trực on-call làm theo đúng runbook, chạy script cũ, không có kết quả, hoang mang mất 25 phút vì "tài liệu bảo làm vậy mà không được". Cuối cùng phải đánh thức tech lead. Trong 25 phút đó, một lượng giao dịch thanh toán bị lỗi, ảnh hưởng trực tiếp đến doanh thu và niềm tin của khách hàng.

Bài học rút ra: Một runbook sai còn nguy hiểm hơn không có runbook, vì nó tạo cảm giác an tâm giả tạo và khiến người trực làm sai một cách tự tin. Từ đó, đội áp dụng quy tắc: mỗi runbook có trường "lần kiểm chứng gần nhất" (last verified), và bất kỳ thay đổi kiến trúc nào (như migrate service) đều phải kèm cập nhật runbook liên quan trong định nghĩa hoàn thành (Definition of Done).

Ví dụ 3 — VNG-style: Runbook cho queue nghẽn trong hệ thống game

Một công ty công nghệ giải trí lớn (theo mô hình VNG) vận hành hệ thống xếp hàng đăng nhập cho game online. Vào ngày ra mắt bản cập nhật lớn, hàng đợi xử lý phiên đăng nhập (login queue) có thể phình lên hàng chục nghìn message, khiến người chơi chờ lâu và bỏ game.

Đội SRE chuẩn bị trước một runbook "Login queue backlog > 20.000". Điểm hay của runbook này là nó có cây quyết định (decision tree): nếu backlog do consumer bị chậm thì scale số consumer lên theo lệnh cho sẵn; nếu do một message "độc" (poison message) gây kẹt thì chuyển nó sang dead-letter queue theo hướng dẫn; nếu do database backend nghẽn thì đây là dấu hiệu khác, chuyển sang runbook database. Runbook cũng ghi rõ ngưỡng an toàn: không được scale consumer quá 50 instance vì sẽ làm sập database phía sau.

Bài học rút ra: Runbook tốt không chỉ liệt kê bước làm mà còn hướng dẫn ra quyết định trong nhiều nhánh tình huống, đồng thời cảnh báo những "cạm bẫy" (như scale quá tay làm sập tầng dưới). Nhờ chuẩn bị trước, ngày ra mắt diễn ra suôn sẻ dù backlog có lúc chạm 35.000 message.

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

Dưới đây là quy trình để bạn tự viết một runbook chất lượng cho đội của mình.

Bước 1 — Chọn đúng đối tượng. Đừng cố viết một runbook cho "mọi sự cố". Bắt đầu từ những alert nổ nhiều nhất hoặc gây đau nhất. Xem lại lịch sử incident 3–6 tháng gần đây, tìm ra top 5 loại sự cố lặp lại. Đó là ứng viên đầu tiên cho runbook.

Bước 2 — Xác định Trigger rõ ràng. Viết chính xác cảnh báo hoặc triệu chứng nào dẫn tới runbook này. Lý tưởng là tên alert khớp đúng với runbook, để việc liên kết một-một dễ dàng.

Bước 3 — Viết phần Diagnosis với công cụ cụ thể. Đừng viết "kiểm tra tình trạng database". Hãy viết: "Mở [link dashboard], xem panel X. Chạy lệnh sau (copy-paste được): .... Nếu thấy Y thì sang bước 4a, nếu thấy Z thì sang bước 4b."

Bước 4 — Viết Mitigation ưu tiên cầm máu trước. Bước đầu tiên luôn nên là khôi phục dịch vụ nhanh nhất có thể (rollback, scale, chuyển traffic, tắt feature flag). Tìm nguyên nhân gốc để sau, khi khách hàng đã hết bị ảnh hưởng.

Bước 5 — Ghi rõ ngưỡng và cảnh báo nguy hiểm. Mỗi lệnh có thể gây hại (xóa, restart, scale) phải kèm cảnh báo và điều kiện an toàn. Ví dụ: "CẢNH BÁO: chỉ chạy lệnh này khi đã xác nhận replica đang đồng bộ, nếu không sẽ mất dữ liệu."

Bước 6 — Định nghĩa Escalation và Verification. Sau bao lâu không giải quyết được thì gọi ai. Chỉ số nào phải trở về bình thường thì mới coi là xong.

Bước 7 — Kiểm chứng runbook bằng người thật. Nhờ một kỹ sư không viết runbook đọc và làm thử trong môi trường staging, hoặc trong một buổi diễn tập. Nếu họ vướng ở đâu, sửa ở đó. Đây là bước quan trọng nhất mà nhiều người bỏ qua.

Bước 8 — Liên kết runbook vào alert. Cấu hình để mỗi cảnh báo có trường "runbook URL" trỏ thẳng tới tài liệu. Người trực không phải đi tìm.

Bước 9 — Đặt lịch review định kỳ. Gán chủ sở hữu (owner) cho mỗi runbook và lịch rà soát (ví dụ mỗi quý), cùng trường "last verified".

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

Lỗi 1 — Runbook lỗi thời. Như ví dụ fintech Singapore, đây là lỗi phổ biến và nguy hiểm nhất. Mẹo: thêm cập nhật runbook vào Definition of Done của mọi thay đổi kiến trúc, và hiển thị "last verified" ngay đầu tài liệu.

Lỗi 2 — Viết quá chung chung. "Kiểm tra hệ thống", "khởi động lại nếu cần" — những câu này vô dụng lúc 3 giờ sáng. Mẹo: mọi bước phải có lệnh copy-paste được hoặc link cụ thể. Test bằng câu hỏi: "Một người mới có làm được đúng bước này mà không hỏi ai không?"

Lỗi 3 — Chỉ tập trung tìm nguyên nhân gốc, quên cầm máu. Người trực lao vào debug nguyên nhân trong khi khách hàng vẫn đang lỗi. Mẹo: luôn đặt bước khôi phục dịch vụ (mitigation) lên trước bước phân tích nguyên nhân.

Lỗi 4 — Runbook nằm ở nơi khó tìm. Có runbook nhưng chôn sâu trong wiki, không ai tìm ra lúc khẩn cấp. Mẹo: nhúng link runbook trực tiếp vào cảnh báo.

Lỗi 5 — Không có lệnh cảnh báo nguy hiểm. Runbook hướng dẫn chạy một lệnh xóa mà không cảnh báo hậu quả. Mẹo: đánh dấu rõ các bước bất khả nghịch (irreversible), bắt buộc xác nhận điều kiện trước khi chạy.

Mẹo nâng cao — Tiến tới tự động hóa. Một runbook mà mọi bước đều rõ ràng, quyết định-dựa-trên-điều-kiện, chính là ứng viên hoàn hảo để tự động hóa thành script hoặc "executable runbook". Runbook viết tốt hôm nay là bản thiết kế cho automation ngày mai, giúp giảm toil về sau.

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

  • Chọn một alert thật. Trong hệ thống bạn đang làm (hoặc một hệ thống giả định), chọn một cảnh báo cụ thể — ví dụ "Disk usage > 90% trên log server". Viết đầy đủ 7 phần của runbook cho nó: Trigger, Impact, Diagnosis, Mitigation, Escalation, Verification, Post-action. Yêu cầu: mọi lệnh phải copy-paste được, không dùng placeholder mơ hồ.
  • Kiểm thử chéo. Đưa runbook vừa viết cho một đồng nghiệp (hoặc bạn học) chưa từng thấy nó. Nhờ họ đọc và mô tả lại họ sẽ làm gì ở từng bước. Ghi lại mọi chỗ họ bối rối hoặc hiểu sai, rồi sửa runbook cho đến khi họ làm được trơn tru.
  • Rà soát runbook cũ. Tìm một runbook đã tồn tại trong tổ chức bạn (hoặc dùng một mẫu tìm được trên mạng). Trả lời: lần cuối nó được kiểm chứng là khi nào? Có lệnh nào đã lỗi thời không? Có thiếu phần Escalation hay cảnh báo nguy hiểm không? Đề xuất bản cập nhật.
  • Thiết kế cây quyết định. Với một loại sự cố có nhiều nguyên nhân khả dĩ (ví dụ "API 5xx tăng đột biến"), vẽ một cây quyết định phân nhánh theo triệu chứng chẩn đoán được, mỗi nhánh dẫn tới một hướng xử lý khác nhau.

Tóm tắt

Runbook là tài liệu hướng dẫn từng bước để người trực on-call xử lý một loại sự cố cụ thể một cách bình tĩnh, nhất quán và không phụ thuộc vào việc ai đang trực. Nó biến kiến thức cá nhân của những người "cứng tay" thành tài sản chung của cả đội.

Một runbook chuẩn gồm các phần: Trigger, Impact, Diagnosis, Mitigation (ưu tiên cầm máu trước), Escalation, Verification và Post-action. Nguyên tắc vàng là viết cho người ít kinh nghiệm nhất — mọi lệnh phải copy-paste được, mọi bước nguy hiểm phải có cảnh báo.

Ba tình huống thực tế cho thấy: runbook tốt giúp giảm mạnh và ổn định MTTR (Tiki), runbook lỗi thời còn nguy hiểm hơn không có (fintech Singapore), và runbook giỏi biết hướng dẫn ra quyết định qua nhiều nhánh cùng cảnh báo cạm bẫy (VNG-style). Cuối cùng, runbook không phải tài liệu viết một lần rồi quên: nó cần chủ sở hữu, lịch review, trường "last verified", được liên kết trực tiếp vào cảnh báo, và về lâu dài là nền tảng để tự động hóa. Viết runbook tốt hôm nay chính là bạn đang tặng cho chính mình một đêm ngon giấc trong tương lai.