Hai Mô Tả Lỗi Nên Biết
Chào mừng
Các hệ thống phân tán gặp sự cố theo các mô thức. Khi bạn học được các mô thức, mỗi bài viết mortem sẽ trở thành một bài tập nhận biết thay vì một bí ẩn.
Ba khái niệm bao gồm hầu hết những điều quan trọng trong phân tích sự cố sản xuất:
Điểm yếu đơn nhất (SPOF): một thành phần mà sự cố của nó làm sập hệ thống lớn hơn. Thường bị che giấu: máy chủ DNS mà mọi người phụ thuộc; chứng chỉ mà mọi thứ tái sinh chống lại; máy chủ cơ sở dữ liệu duy nhất.
Sự cố lan truyền: một thành phần bị lỗi kích hoạt sự cố của một cái khác, sau đó kích hoạt cái khác. Một cơ sở dữ liệu chậm khiến các tầng API bị timeout, sau đó gây ra các lần thử lại, sau đó tải thêm cơ sở dữ liệu, sau đó gây ra các lần timeout khác. Sóng nổ lan rộng.
Tầm Quả Nổ: bao nhiêu phần của hệ thống bị sập khi một phần nào đó bị lỗi. Các lựa chọn kiến trúc có thể giới hạn hoặc mở rộng tầm quả nổ. Một SPOF có tầm quả nổ không giới hạn. Một dịch vụ bulkheaded có tầm quả nổ giới hạn.
Sau khi hoàn thành bài học này bạn sẽ:
- Nhận biết SPOFs trong kiến trúc bằng cách kiểm tra
- Nhận biết các mô thức sự cố lan truyền: bão táp, cơn lũ thử lại, hàng đợi cái chết
- Đọc một timeline thực tế & tách biệt trigger từ khuyết tật lặng lẽ mà trigger nổi bật
- Viết các mục tiêu không đổ lỗi cho người mà tập trung vào hệ thống, bao gồm phòng ngừa / phát hiện / hồi phục
- Lý giải về bulkheads & circuit breakers như là công cụ hạn chế tầm quả nổ
Nhận Biết Điểm Yếu Đơn Nhất
Kiểm Tra Kiến Trúc Lớp Lồng
Xin xem xét một kiến trúc web nhỏ:
- DNS: api.example.com -> IP máy chủ tên đơn 203.0.113.10 do một nhà cung cấp DNS duy nhất chủ trì
- CDN: nhà cung cấp CDN duy nhất trước api.example.com
- Ingress: hai máy chủ reverse proxy sau một cân bằng tải
- Backend: sáu bản sao API trong hai vùng khả dụng (ba mỗi vùng)
- Cơ sở dữ liệu: một máy chủ chủ + một máy chủ đọc replica, trong cùng một vùng khả dụng
- Cache: cluster Redis, ba nút trải đều trong hai vùng khả dụng giống nhau
Câu hỏi: các thành phần nào là SPOFs? Gợi ý: SPOFs không phải lúc nào cũng là 'thành phần máy đơn'. Một cluster của ba máy trong một vùng khả dụng giống nhau là SPOF cho sự cố của vùng khả dụng đó.
Ba Mô hình Sai lầm Lan truyền Classic
Sai lầm Di chuyển Qua Tương tác
Mô hình 1: Đám cừu sấm sét. Một tài nguyên chung (cache, khóa, cơ sở dữ liệu) bị hỏng hoặc khởi động lại. Mỗi khách hàng phụ thuộc vào nó đều thử lại cùng lúc. Cơn lũ ngập vượt quá khả năng hồi phục của bất kỳ thứ gì được khởi động lại; các lần thử lại chồng chất nhanh hơn tốc độ hồi phục của chúng; hồi phục không bao giờ hoàn thành.
Mô hình 2: Cơn bão thử lại. Một dịch vụ downstream chậm lại. Các nhà gọi lênstream, thay vì thất bại, thử lại. Các lần thử lại nhân lên tải gốc. Dịch vụ chậm hơn còn chậm hơn, kích hoạt thêm các lần thử lại. Cuối cùng, tải vượt quá ngay cả bản sao khỏe mạnh của dịch vụ.
Mô hình 3: Hàng chờ cái chết. Một hàng chờ xử lý không có áp suất ngược lại nhận nhanh hơn nó xử lý. Hàng chờ tăng không giới hạn. Dung lượng hết; tiêu thụ bị tắt; khởi động lại; tìm thấy một hàng chờ lớn hơn; tắt lại lần nữa.
Sợi dây chung: một sự rung chấn ban đầu nhỏ kích hoạt một vòng lặp phản hồi tích cực. Hệ thống phản hồi của nó làm tăng sự thất bại thay vì giảm bớt.
Các cơ chế giảm âm
Tăng tốc độ lùi theo tỷ lệ với nhiễu-random. Các khách hàng thử lại chờ lâu hơn mỗi lần, với độ lệch ngẫu nhiên. Ngăn chặn các vở sóng thử lại đồng bộ.
Circuit Breaker. Một nhà gọi theo dõi tỷ lệ thất bại downstream. Sau một ngưỡng, nhà gọi ngừng gọi trong một khoảng thời gian làm nguội và ngay lập tức thất bại các yêu cầu của mình. Ngăn chặn công việc vô ích, cho phép downstream hồi phục.
Bulkhead. Đảo ngược tài nguyên theo từng phụ thuộc. Bể kết nối A cho cơ sở dữ liệu, bể kết nối riêng biệt B cho cache. Một cơ sở dữ liệu chậm không thể làm nghèo tất cả các kết nối; các cuộc gọi cache tiếp tục.
Giảm tải. Khi quá tải, từ chối yêu cầu ở cạnh thay vì chấp nhận và thất bại chậm rãi. Một 429 trong 1 ms tốt hơn một 500 trong 30 giây.
Áp suất ngược lại. Các nhà sản xuất chậm lại khi các tiêu thụ không thể giữ được. Các hàng chờ trở thành giới hạn; gửi tin nhắn bị chặn; nguồn gốc gốc của công việc cảm nhận được ma sát.
Chẩn đoán một Cơn bão
Một đội API tier tan chảy trong quá trình failover cơ sở dữ liệu hàng ngày. Thời gian:
- 14:00:00 — operator nâng cấp cơ sở dữ liệu dự phòng. Thời gian không khả dụng dự kiến: ~10 giây.
- 14:00:08 — primary không khả dụng. Các yêu cầu API tier bắt đầu gặp lỗi kết nối cơ sở dữ liệu.
- 14:00:08 — API tier thử lại (cấu hình mặc định: 5 lần thử lại, không có backoff, cách nhau 100ms).
- 14:00:11 — standby được nâng cấp, chấp nhận các kết nối mới.
- 14:00:11 — API tier mở hàng nghìn kết nối cơ sở dữ liệu mới đồng thời (mỗi bản sao × mỗi yêu cầu đồng thời × mỗi lần thử lại).
- 14:00:13 — pool kết nối của primary mới hết sạch; các kết nối mới bị từ chối.
- 14:00:13-14:05:00 — các bản sao API tier hết sạch pool kết nối, ném ngoại lệ, tắt, khởi động lại, lặp lại.
- 14:05:00 — operator dừng manual traffic API tier; cơ sở dữ liệu ổn định lại.
- 14:10:00 — quá trình khôi phục traffic dần hoàn tất. Tổng thời gian sự cố: ~10 phút (so với dự kiến ~10 giây).
SERVFAIL DNS: Hai khuyết điểm chồng chéo
Một bài viết Postmortem thực sự
Sau đây là một bản sao được làm sạch của một sự cố thực sự. Tên nhà cung cấp thay đổi, IPs được ẩn danh; hình dạng, timeline, và bài học là thực sự.
Tóm tắt
Mạng example.com trả về SERVFAIL từ tất cả các resolver DNS công khai trong khoảng thời gian 3-4 giờ. Các khu vực khác 46 trên cùng một master DNS không bị ảnh hưởng. Nguyên nhân gốc rễ: hai khuyết điểm chồng chéo.
1. Vendor A (một nhà cung cấp DNS thứ cấp) đã thêm một IP đồng bộ mới trong hệ thống nội bộ mà không có trong allowlist allow-axfr-ips của primary.
2. Khu vực example.com có một xung đột CNAME vi phạm RFC lâu năm (demo.example.com có cả CNAME và MX/TXT ở cùng một label) đã khiến Vendor A từ chối khu vực trong AXFR mới.
Timeline (UTC)
- ~15:00 — Vendor A thêm IP đồng bộ mới 198.51.100.42 vào cơ sở hạ tầng
- 15:02 — đầu tiên AXFR-out denied cho 198.51.100.42 xuất hiện trong nhật ký DNS chính (không cảnh báo tín hiệu này)
- ~18:00 — cửa sổ thời gian hết hạn SOA; Vendor A xóa vùng example.com từ cache
- ~18:30 — phát hiện SERVFAIL từ ngoài
- ~19:45 — xác định nguyên nhân gốc rễ
- 20:00 — 198.51.100.42 được thêm vào allow-axfr-ips; máy chủ chính được khởi động lại
- 20:05 — gửi NOTIFY; bắt đầu AXFR; vùng STILL SERVFAIL (sự xung đột CNAME)
- 20:07 — check-zone tiết lộ 1 lỗi: sự xung đột CNAME trên demo.example.com
- 20:09 — thay thế CNAME bằng bản ghi A; kiểm tra vùng sạch (0 lỗi)
- 20:10 — gửi NOTIFY; AXFR hoàn tất; Vendor A bắt đầu phục vụ vùng
- 20:11 — dig @8.8.8.8 example.com A trả về IP đúng — ĐƯỢC GIẢI QUYẾT
Tại sao chỉ có example.com?
Tổng cộng 47 vùng chia sẻ cùng một DNS chính. IP AXFR bị ảnh hưởng tất cả các vùng. Nhưng chỉ example.com có xung đột CNAME và chỉ example.com cần một AXFR mới tại thời điểm deny được áp dụng. Các vùng khác đã được cập nhật trước khi deny hoặc chưa cần phải cập nhật.
Lỗi tiềm ẩn
Sự xung đột CNAME tại demo.example.com đã tồn tại trong nhiều năm. Nó hoạt động vì máy chủ chính phục vụ vùng từ cơ sở dữ liệu của nó (nghiêm ngặt về vi phạm RFC) và Vendor A đang phục vụ từ dữ liệu cache cũ từ trước khi vi phạm được giới thiệu. Khi Vendor A xóa cache và cần dữ liệu mới, vi phạm xuất hiện.
Cú pháp
Vendor A thêm một IP đồng bộ mới mà không thông báo. Danh sách cho phép của máy chủ chính không bao gồm nó. AXFR bị từ chối. Ba giờ sau (SOA expire), Vendor A xóa vùng. Lỗi tiềm ẩn xuất hiện khi hệ thống cố gắng hồi phục.
Viết các mục hành động vô tội vạ
Vô tội vạ: Target Systems, Not People
Mục hành động vô tội vạ nêu điều hệ thống nên làm khác đi, không phải điều một người nên làm khác đi. 'Dạy cho người vận hành' là điều đáng trách. 'Thêm một kiểm tra tự động phát hiện điều này trước khi triển khai' là vô tội vạ.
Các mục hành động vô tội vạ tốt sẽ rơi vào ba chiều sau:
- Prevention: làm cho điều xấu khó hơn hoặc không thể
- Detection: nhận biết sớm hơn nếu nó xảy ra
- Recovery: hạn chế thiệt hại khi nó xảy ra
Mỗi mục nên nêu (1) thay đổi hệ thống cụ thể, (2) đội ngũ quản lý và (3) chiều nó phục vụ.
Các Khung Kính Gây Chìm mà Con Thuyền Không Chìm
Được Mượn từ Kỹ Thuật Xây Dựng Thuyền
Các thuyền có các bức tường ngăn nước kín: các bức tường đứng chia thuyền thành các khoang. Một khoang có thể bị ngập mà không làm chìm thuyền; một khoang khác có thể bị hỏng mà không ảnh hưởng đến phần còn lại.
Các hệ thống phân tán mượn cùng một từ và cùng một ý tưởng.
MẫuBulkhead: cô lập các nguồn lực theo phụ thuộc. Một dịch vụ gọi ba API downstream sử dụng ba bể kết nối riêng, ba bể luồng thẻ riêng, ba ngân sách thử lại riêng. Một downstream chậm hoặc thất bại không thể sử dụng các nguồn lực được phân bổ cho hai cái khác.
Không cóBulkhead: một phụ thuộc chậm tiêu thụ bể luồng thẻ chung; các cuộc gọi đến các phụ thuộc khác bị đợi vì luồng thẻ; toàn bộ dịch vụ trở nên không phản hồi.
CóBulkhead: một phụ thuộc chậm tiêu thụ bể luồng thẻ của nó; các cuộc gọi đến nó bị dừng ngay lập tức; các cuộc gọi đến các phụ thuộc khác tiếp tục bình thường; phạm vi hủy đao được giới hạn ở phụ thuộc bị lỗi.
Cầu Đập Lực Lượng
MẫuCircuit breaker: một lớp bọc có trạng thái quanh một phụ thuộc downstream mà theo dõi tỷ lệ lỗi. Ba trạng thái:
- Đóng (bình thường): các cuộc gọi đi qua. Các lỗi được tính.
- Mở (bị nổ): sau một ngưỡng lỗi (ví dụ, 50% lỗi trong 30 giây qua), cầu đập mở. Các cuộc gọi bị dừng ngay lập tức mà không thử phụ thuộc. Lưu lại cho người gọi khỏi lãng phí công việc; cứu phụ thuộc khỏi nhận tải trong khi nó không khỏe.
- Rộng một nửa (đo thử): sau một khoảng thời gian chờ, cầu đập cho phép một phần nhỏ các cuộc gọi đi qua. Nếu chúng thành công, nó đóng lại về bình thường. Nếu chúng bị lỗi, nó lại mở để chờ thêm một khoảng thời gian.
Ý tưởng chính: cầu đập lực lượng ngăn lãng phí công việc trong các khoảng thời gian không khỏe được biết, và cho phép downstream một cơ hội hồi phục mà không tiếp tục tải.
Bulkheads giới hạn phạm vi hủy đao. Cầu đập lực lượng ngăn phạm vi hủy đao duy trì chính mình.
Giới hạn Phạm Vi Hủy Đao
Các dịch vụ API của bạn gọi bốn dịch vụ downstream: Dịch vụ User, Dịch vụ Recommendation, Dịch vụ Notification và một API Thanh toán thứ ba. Đội ngũ đã nghe 'Dịch vụ Recommendation có vẻ không ổn định' và muốn đảm bảo rằng khi nó gặp sự cố, hệ thống còn lại vẫn khỏe mạnh.
Hôm nay, dịch vụ sử dụng một bội số luồng một mình có 200 luồng và một bội số kết nối HTTP một mình. Tất cả bốn downstream đều cạnh tranh cho các nguồn lực này. Không có các điểm dừng mạch.
Thiết kế Một Đánh Giá Sự Tiêu Cự
Tổng Hợp
Bạn đã học cách phát hiện SPOFs bằng cách kiểm tra, nhận biết sự tiêu cự lan truyền, tách ra trigger từ lỗi tiềm ẩn khi đọc bài đăng mộ, viết các hành động không đổ lỗi về phòng ngừa / phát hiện / hồi phục và hạn chế phạm vi ảnh hưởng với bulkheads + circuit breakers + graceful degradation.
Áp dụng tất cả năm kỹ thuật.
Đội ngũ của bạn đang tung ra một dịch vụ mới search.example.com phụ thuộc vào ba dịch vụ downstream: một index tìm kiếm chính (index.example.com), một dịch vụ phân tích (analytics.example.com) và một dịch vụ gợi ý (recs.example.com). Đội ngũ muốn bạn lãnh đạo một 'đánh giá sự tiêu cự' trước khi tung ra.
Hướng Tiếp Theo Của Khóa Học
Hướng Tiếp Theo Của Khóa Học
Bạn có thể phát hiện SPOFs, nhận biết một cascade, đọc bài đăng mộ hiệu quả, viết các hành động không đổ lỗi và hạn chế phạm vi ảnh hưởng bằng thiết kế.
Bài học cuối cùng trong khóa học này (cs_distsys_observability_and_capacity) dạy bạn những gì cần đo để bạn biết một vấn đề đang xảy ra trước khi người dùng nhận biết. Kiểm tra sức khỏe, điểm cuối phiên bản, bốn tín hiệu vàng ở tầng proxy, & cách quyết định về dung lượng tăng thêm liên quan lại đến dữ liệu quan sát.
Bài học kèm theo: geometry_of_failure_modes_and_blast_radius tìm hiểu giữa tính trung gian (nút đồ thị nào là nút cổ chai) & min-cut (sự giới hạn trên bán kính nổ).
Chúc mừng. Tiến lên.