Jepsen: NATS 2.12.1

Bài tóm tắt Jepsen 2025 3. Quy mô lớn Độ khó: Khó

Jepsen · 2025 · 3. Quy mô lớn · Độ khó: Khó — bài gốc

Bối cảnh

  • NATS JetStream nhân bản stream bằng Raft, hứa giao "ít nhất một lần" (không mất message đã ack), log có thứ tự toàn phần, và tài liệu nói vừa "linearizable" vừa "tự lành và luôn sẵn sàng"; theo Jepsen, CAP cho thấy chỉ một trong hai có thể đúng.

Thay đổi chính (kết quả)

  • 2.10.22: crash process có thể làm JetStream quên luôn stream (NATS tự tìm ra, sửa ở 2.10.23, 12/2024).
  • 2.12.1: không mất dữ liệu với partition, pause, crash process đơn giản. Nhưng bitflip hoặc cắt cụt file .blk hay snapshot, kể cả trên thiểu số node, làm mất một message, cả dải message, hoặc node xoá sạch dữ liệu stream; message có ở node này mà mất ở node khác.
  • Mặc định fsync mỗi 2 phút nhưng ack ngay: nhiều node mất điện/kernel crash gần nhau là mất ghi đã commit. Một crash OS duy nhất kết hợp crash process, pause hoặc partition có thể gây mất message đã ack và split-brain kéo dài.
  • Jepsen khuyến nghị đổi mặc định fsync sang always hoặc ghi rõ rủi ro; NATS đã bổ sung tài liệu. Cụm 3 và 5 node nhìn chung chạy như Raft thông thường: thiểu số bị cô lập thì không phục vụ.
  • Công cụ chính: LazyFS (INESC TEC) giả lập mất điện bằng cách bỏ ghi chưa fsync sau khi kill process.

Vì sao

  • Hệ không mất dữ liệu khi kill -9 vẫn có thể mất khi máy mất điện: crash process giữ page cache của OS, crash OS thì không.

Bài học cho SWE

  • Test độ bền phải giả lập crash cấp OS và hỏng file, không chỉ kill process.
  • "Ack" và "bền" phải nói về cùng một thứ; lịch fsync lười là đánh đổi phải ghi rõ.

Liên quan