Bạn có biết?
Hai request đồng thời cùng xử lý một đơn hàng, cả hai đều trừ tiền thành công? Hay một cron job chạy lại trên 2 server, gửi email trùng lặp cho khách hàng? Trong hệ thống phân tán, race condition là kẻ thù số một — và Distributed Lock là vũ khí để chống lại nó.
Với một server duy nhất, bạn chỉ cần synchronized hay mutex. Nhưng khi có nhiều server, nhiều instance cùng xử lý chung dữ liệu, lock trong bộ nhớ của từng máy không còn ý nghĩa — bạn cần một lock dùng chung, nằm ngoài mọi instance. Và Redis chính là nơi lý tưởng để đặt nó.
Vấn đề: race condition trong hệ thống phân tán
Hãy nhìn một ví dụ kinh điển — xử lý đơn hàng:
// Giả sử chạy trên 3 server (load balancer phân phối request)
async function processOrder(orderId) {
const order = await db.get(orderId);
if (order.status === 'PAID') return; // chống trùng?
await payment.charge(order.userId, order.amount);
await db.update(orderId, { status: 'PAID' });
}
Hai request cùng lúc cho cùng một đơn hàng đi vào 2 server khác nhau: cả hai đều đọc status = PENDING (vì chưa server nào kịp update), cả hai đều charge tiền. if kiểm tra trong code không cứu được bạn vì nó không atomic.
Giải pháp đúng: trước khi xử lý, mọi server phải giành được lock từ một nơi trung lập — Redis. Server nào giành được lock mới được xử lý, server khác bỏ qua.
SET NX EX: lock cơ bản
Redis cung cấp lệnh SET với 2 option quan trọng:
- NX (Not eXists) — chỉ set nếu key chưa tồn tại
- — đặt TTL (expiration) cho key
0 bình luận
Đang tải bình luận...
Để lại bình luận