How Stripe uses graph search and state machines to auto-remediate a global database fleet
Bài tóm tắt Stripe 2026 4. Điều chỉnh Độ khó: Nâng cao
Stripe · 2026 · 4. Điều chỉnh · Độ khó: Nâng cao — bài gốc
Bối cảnh
- Document Database của Stripe: khoảng 2.000 shard MongoDB, hơn 40 kiểu bố trí shard (từ tối ưu chi phí tới HA cho khôi phục thảm hoạ). Năm 2025 xử lý 1,9 nghìn tỷ USD thanh toán.
- Tình huống điển hình: 2 giờ sáng một shard suy giảm (hai node chết, một node chặn việc build index vì cấu hình vote sai). Người trực mất 15 phút sắp xếp thao tác tay, rồi có khi tới 3 giờ chờ rebuild. Chuyện này lặp lại hàng trăm lần mỗi năm.
- Tự sửa V1: state machine cứng, mỗi plugin sửa một lỗi ("sửa vote", "sửa priority", "dựng lại node") chạy theo thứ tự ưu tiên cố định.
- phụ thuộc ngầm giữa plugin tạo vòng (sửa vote cần không node nào chết, dựng node cần vote đúng);
- nhiều lỗi cùng lúc thì không tìm được thứ tự hợp lệ, phải gọi người;
- mỗi kiểu bố trí mới mất khoảng 1 tuần audit mọi plugin;
- huỷ workflow giữa chừng để lại trạng thái không plugin nào lường trước.
- Trong 6 tháng: 124 lần gọi người vì cấu hình shard sai, 32 lần vì node chết kèm lỗi khác; index build và bảo trì bị chặn trung bình 1 giờ mỗi lần.
Thay đổi chính
- Đổi câu hỏi: thay vì "lỗi nào quan trọng nhất cần sửa ngay" (tham lam, cục bộ), hỏi "chuỗi thao tác nào đưa shard về trạng thái khoẻ mà không bao giờ vi phạm bất biến an toàn". Đó là bài toán tìm đường trên đồ thị.
- Đỉnh: trạng thái shard (vote, priority, hidden của từng node; oplog; phân bố region).
- Cạnh: thao tác nguyên tử (thêm/bớt vote, ẩn node, dựng lại node, đổi kích thước oplog).
- Đích: trạng thái khai báo trong nguồn sự thật.
- Trạng thái cấm: số vote chẵn, thiểu số node vote khoẻ, priority 1 mà vote 0...
- BFS tìm chuỗi ngắn nhất. Ví dụ ba lỗi cùng lúc mà V1 kẹt thì BFS tìm được thứ tự an toàn (sửa vote trước để giữ quorum, rồi dựng node).
- Mô phỏng bằng chính code thật: các bước sửa là workflow Temporal (durable execution, chạy tiếp được sau deploy hay crash). Họ thêm interface
CommonContextcó hai bản: Temporal thật và bản mô phỏng trong bộ nhớ, nên thứ mô phỏng chính là thứ sẽ chạy. Mô phỏng hàng trăm chuyển trạng thái mỗi giây thay vì vài phút I/O cho mỗi bước. - Từ BFS sang Dijkstra: khi không có đường tới trạng thái khoẻ hoàn toàn thì BFS bó tay. Dijkstra với trọng số cạnh = mức sai cấu hình × thời gian ước tính của thao tác tìm được trạng thái ít tệ nhất, tức là sửa được một phần. Mức sai cấu hình là tổng các luật ghép được (node chết, vote, priority, oplog, hidden, lệch AZ).
Kết quả (theo Stripe)
- Số lần gọi người giảm 30% (khoảng 200 lần mỗi năm); lấy lại khoảng 12 ngày sức khoẻ fleet mỗi năm.
- Không phụ thuộc kiểu bố trí: một kiểu mới dùng ngay mà không sửa code.
- Huỷ giữa chừng thì tính lại đường từ trạng thái đang có.
- Hướng tiếp: dùng cùng bộ tìm đường để chuyển đổi bố trí shard, blue-green khi nâng version, gộp bảo trì.
Bài học cho SWE
- Runbook mã hoá cách khôi phục đã biết; state machine + tìm đường tìm ra cách khôi phục mới. Định nghĩa bất biến và thao tác hợp lệ, để thuật toán ghép thành kế hoạch (Độ tin cậy và multi-region).
- Tự động hoá phải xử lý được nhiều lỗi cùng lúc và trạng thái dở dang. Đây đúng là chỗ automation kiểu Pacemaker của GoCardless gãy (GoCardless 2017).
- Dùng chung code cho mô phỏng và thực thi để kế hoạch không lệch khỏi thực tế (Nền tảng nội bộ cho service (đường ray chung)).
Liên quan
Failover, replica và dự phòng dữ liệuNền tảng nội bộ cho service (đường ray chung)Tự động hoá vận hành và auto-remediation
Được nhắc tới trong
Chủ đề (3)
Công ty (1)
Bài tóm tắt (5)