1. Redis Lock là gì?
Redis Lock, hay còn gọi là Distributed Locking với Redis, là một kỹ thuật dùng để đồng bộ quyền truy cập vào các tài nguyên được chia sẻ trong môi trường hệ thống phân tán.
2. Tầm Quan Trọng Của Khóa Phân Tán Trong Hệ Thống Phân Tán
Trong các hệ thống phân tán, nhiều tiến trình hoặc máy chủ hoạt động đồng thời. Nếu không có cơ chế đồng bộ, việc truy cập vào tài nguyên chung như cơ sở dữ liệu, hàng đợi hay file có thể gây ra:
- Hỏng dữ liệu
- Trạng thái không nhất quán
- Kết quả không thể đoán trước
Khóa phân tán (Distributed Lock) giúp đảm bảo tính loại trừ lẫn nhau (Mutual Exclusion): tại một thời điểm, chỉ một tiến trình được quyền xử lý tài nguyên chung.
3. Redis Lock Hoạt Động Như Thế Nào?
Redis Lock hoạt động theo nguyên lý:
- Ghi một
key
vào Redis với thời gian hết hạn (TTL). - Nếu key đã tồn tại, tiến trình khác không thể ghi đè.
- Khi tiến trình xong việc, key được xóa hoặc hết hạn, tiến trình khác mới có thể chiếm quyền.
Bạn có thể sử dụng thư viện như redislock
để dễ dàng triển khai Redis-based locking trong Node.js.
4. Cách Sử Dụng Redis Lock Trong Node.js (Ví Dụ Thực Tế)
Bài toán đặt ra:
Một hệ thống cần xác minh một giao dịch blockchain thông qua hai nguồn độc lập:
- API từ frontend (
api(txHash)
) - Event listener từ hệ thống (
listenerEvent(txHash)
)
Mục tiêu: tránh xử lý trùng cùng một txHash
khi cả hai nguồn kích hoạt cùng lúc.
5. Cài Đặt Redis Lock Cho Hệ Thống
Hàm xử lý giao dịch: verifyTransactionHash(txHash)
const verifyTransactionHash = async (txHash: string) => {
let transaction: any = await transactionService.getTransactionByTxHash(txHash);
if (!transaction) {
transaction = await transactionService.updateOrCreateTx(
txHash,
TransactionType.BUY_ITEM,
TransactionStatus.PROCESSED
);
}
return transaction;
};
Giải thích:
- Kiểm tra xem
txHash
đã tồn tại trong cơ sở dữ liệu chưa. - Nếu chưa → tạo mới.
- Nếu đã có → trả về bản ghi hiện tại.
Hàm sử dụng Redis Lock: listenerEvent(txHash)
và api(txHash)
let lock;
try {
lock = await redisLock.acquire([`key-${txHash}`], DEFAULT_TIME_LOCK_PROCESS);
await verifyTransactionHash(txHash);
} catch (err) {
// Xử lý lỗi, ví dụ log
} finally {
if (lock) {
await lock.release();
}
}
Giải thích chi tiết:
redisLock.acquire([...])
: Cố gắng chiếm khóa Redis.- Nếu khóa đang được giữ → thất bại hoặc retry (nếu cấu hình).
verifyTransactionHash(txHash)
: Gọi hàm xử lý chính.finally { lock.release() }
: Luôn giải phóng khóa, tránh deadlock.
6. Tình Huống Thực Tế Sử Dụng Redis Lock
Case 1: txHash
chưa có ai xử lý
listenerEvent("0xabc")
được gọi.- Key
key-0xabc
chưa tồn tại trong Redis → chiếm được lock. - Tạo transaction mới trong DB.
- Giải phóng lock.
Case 2: Cả api("0xabc")
và listenerEvent("0xabc")
chạy đồng thời
- Một bên chiếm được Redis lock trước (ví dụ: API).
- Bên còn lại (listener) không chiếm được lock → dừng xử lý.
- Kết quả: chỉ một bên xử lý, đảm bảo không bị trùng.

7. Kết Luận
Redis Lock là một giải pháp hiệu quả để đồng bộ hóa truy cập vào tài nguyên trong môi trường phân tán, giúp ngăn chặn:
- Race condition
- Giao dịch bị xử lý trùng
- Dữ liệu không nhất quán
Với Node.js, việc sử dụng Redis Lock thông qua thư viện như redislock
hoặc node-redlock
là cách tiếp cận phổ biến, đơn giản mà mạnh mẽ.