Sử dụng PostgreSQL Advisory Locks để lập lịch công việc phân tán
Đừng thêm Redis hay SQS vào stack của bạn chỉ để lập lịch công việc.
Thay vào đó, bạn có thể sử dụng PostgreSQL advisory locks. Cách tiếp cận này giúp loại bỏ nhu cầu về hạ tầng mới.
Trong các thử nghiệm của tôi, thiết lập này có thể xử lý 10.000 công việc mỗi phút trên một instance cơ sở dữ liệu duy nhất. Nó thường vượt qua Redis về độ trễ vì các worker của bạn đã nắm giữ sẵn các kết nối cơ sở dữ liệu. Bạn sẽ tránh được một bước nhảy mạng (network hop) không cần thiết.
Cách triển khai:
• Sử dụng pg_try_advisory_xact_lock để nhận công việc (job claiming).
• Sử dụng FOR UPDATE SKIP LOCKED để xử lý tranh chấp hàng (row contention).
• Sử dụng biến thể giao dịch (transactional variant) để tránh rò rỉ khóa (lock leaks).
Tại sao khóa giao dịch (transactional locks) lại quan trọng:
Khóa giao dịch sẽ tự động được giải phóng khi một giao dịch commit hoặc rollback. Điều này ngăn chặn tình trạng khóa mồ côi (orphaned locks) nếu ứng dụng của bạn bị crash. Nó cũng hoạt động an toàn với PgBouncer ở chế độ transaction.
Tránh sử dụng session locks nếu bạn dùng PgBouncer. PgBouncer sẽ gán lại các kết nối giữa các giao dịch. Điều này làm phá vỡ các khóa cấp session và gây ra các lỗi âm thầm (silent failures).
Nếu bạn cần session locks, hãy tạo một connection pool riêng cho các worker của mình. Đừng trộn lẫn traffic của web và traffic của job worker trong cùng một pool.
Mở rộng với các key:
Advisory locks sử dụng một bigint hoặc hai số nguyên. Việc sử dụng hai số nguyên sẽ cung cấp khả năng phân vùng tên (namespacing) một cách tự nhiên. Nếu bạn hash các text key thành một bigint, hãy chú ý đến các xung đột (collisions). Tỷ lệ xung đột sẽ ở mức thấp cho đến khi bạn đạt tới 100.000 ID khóa riêng biệt. Vượt quá con số đó, hãy sử dụng dạng hai số nguyên để đảm bảo an toàn.
Sự đánh đổi:
• Advisory locks thắng về sự đơn giản và chi phí vận hành thấp. • Redis thắng về thông lượng thô (raw throughput) và khả năng mở rộng hàng ngang (horizontal scaling).
Hầu hết các đội ngũ không cần quá 10.000 công việc mỗi phút. Nếu bạn dưới giới hạn đó, hãy trung thành với PostgreSQL. Nó giúp kiến trúc của bạn gọn gàng và chi phí thấp.
Nguồn: https://dev.to/software_mvp-factory/postgresql-advisory-locks-for-distributed-job-scheduling-15kp