4 điểm bởi GN⁺ 2024-10-21 | 1 bình luận | Chia sẻ qua WhatsApp

Triển khai khóa phân tán

  • Tác giả phát hiện thuật toán Redlock trên trang web Redis, thuật toán này tuyên bố triển khai khóa phân tán chịu lỗi trên Redis.
  • Đã có nhiều triển khai độc lập của Redlock, và có thể đã có người đang phụ thuộc vào thuật toán này, nên tác giả quyết định chia sẻ các ghi chú của mình.
  • Redis hữu ích khi chia sẻ dữ liệu tạm thời và thay đổi nhanh giữa các máy chủ, nhưng việc mở rộng nó sang lĩnh vực quản lý dữ liệu đòi hỏi tính nhất quán mạnh và độ bền là điều đáng lo ngại.

Mục đích của khóa

  • Khóa có vai trò bảo đảm chỉ một trong nhiều nút thực hiện một công việc cụ thể.
  • Nếu dùng khóa vì hiệu quả, có thể sẽ tốt hơn khi dùng một instance Redis đơn lẻ.
  • Nếu dùng khóa vì tính chính xác, Redlock không phù hợp.

Bảo vệ tài nguyên bằng khóa

  • Khóa trong hệ thống phân tán khác với mutex trong ứng dụng đa luồng.
  • Nó ngăn các client khác thực hiện cùng một thao tác trong khi một client đang đọc, sửa rồi ghi lại tệp.

Triển khai khóa an toàn bằng fencing

  • Có thể triển khai khóa an toàn bằng cách dùng fencing token và đưa nó vào các yêu cầu ghi.
  • Redlock không an toàn vì không có khả năng tạo fencing token.

Dùng thời gian cho đồng thuận

  • Khác với các thuật toán trong mô hình bất đồng bộ, Redlock đặt ra nhiều giả định về thời gian.
  • Nếu đồng hồ hệ thống hoạt động bất thường, thời điểm hết hạn của khóa có thể nhanh hơn hoặc chậm hơn dự kiến.

Phá vỡ các giả định thời gian của Redlock

  • Redlock giả định mô hình hệ thống đồng bộ và chỉ hoạt động đúng khi độ trễ mạng, việc tạm dừng tiến trình và lỗi đồng hồ đều bị giới hạn.
  • Những trường hợp như sự cố trì hoãn gói tin 90 giây của GitHub có thể đe dọa tính an toàn của Redlock.

Kết luận

  • Redlock quá nặng một cách không cần thiết cho các khóa tối ưu hiệu quả, và lại không đủ an toàn cho những tình huống đòi hỏi tính chính xác.
  • Nếu cần khóa vì tính chính xác, nên dùng một hệ thống đồng thuận phù hợp như ZooKeeper.

Tóm tắt của GN⁺

  • Thuật toán Redlock mang lại một cuộc thảo luận quan trọng về cách triển khai khóa trong hệ thống phân tán.
  • Bài viết này nhấn mạnh các vấn đề về giả định thời gian và an toàn trong hệ thống phân tán, đồng thời giải thích tầm quan trọng của việc triển khai khóa đúng cách.
  • Bài viết khuyến nghị các hệ thống thay thế như ZooKeeper và giúp hiểu rõ hơn sự phức tạp của hệ thống phân tán.

1 bình luận

 
GN⁺ 2024-10-21
Ý kiến trên Hacker News
  • Đã có kinh nghiệm triển khai khóa phân tán bằng Temporal và đến nay nó vẫn hoạt động tốt. Việc triển khai khóa phân tán khá đơn giản nhờ tận dụng các tính năng của Temporal
  • Đã để lại ý kiến trong phần bình luận blog rằng bài viết đã bỏ lỡ một điểm quan trọng của thuật toán, từ đó chỉ ra rằng lập luận bác bỏ thuật toán dựa trên một điểm yếu
  • Với máy tính và API hiện đại, có thể chờ thời gian gần đúng; thời gian dừng GC là có giới hạn và đồng hồ đơn điệu hoạt động bình thường. Đây là một giả định có thể chấp nhận được
  • Chỉ trích cơ chế tự động giải phóng là một vấn đề khác với việc chỉ trích mục tiêu của thuật toán và mô hình hệ thống
  • Redlock đã được dùng thành công trong nhiều trường hợp sử dụng khác nhau, và nếu đặt timeout hợp lý thì rất khó tạo ra race condition. Đặt timeout quá nhỏ là lỗi thiết kế
  • Đang cập nhật kiến thức về mức thấp và thuật toán, muốn tự làm gì đó cho vui nhưng phần lớn tài liệu либо ở mức đồ chơi либо quá phức tạp
  • Triển khai khóa phân tán bằng PostgreSQL: bắt đầu transaction, lấy advisory lock và giữ trạng thái khóa cho đến khi transaction được giải phóng
  • Nhận ra rằng mình đã không kiểm tra trạng thái kết nối cơ sở dữ liệu; nếu công việc không liên quan đến cơ sở dữ liệu thì có thể đã bị mất khóa
  • Đã triển khai khóa phân tán bằng Deno và Deno KV, vốn dựa trên FoundationDB
  • Đã xem xét Redis, nhưng giải quyết vấn đề tính đúng đắn bằng cách dùng PostgreSQL để biến yêu cầu thành thao tác SET
  • Nhiều kỹ sư không coi trọng vấn đề tính đúng đắn, trong khi vẫn tồn tại các trường hợp biên nơi thông điệp có thể bị mất hoặc sai thứ tự
  • Việc đặt timeout cho khóa là một ý tưởng hay; nếu client bị crash thì OS hoặc supervisor sẽ giải phóng khóa
  • Khi không cần khóa, có thể dùng version token để giữ toàn vẹn dữ liệu. Có thể sử dụng giá trị duy nhất như UUID