Bỏ qua, đến nội dung

Câu hỏi thường gặp (FAQ) — Lock Adapter Redis

Cài đặt và cấu hình

Có bắt buộc phải cài Redis không?

Không bắt buộc nếu bạn chỉ chạy một instance duy nhất. Khi đó, lock adapter mặc định (in-memory) hoạt động tốt. Tuy nhiên, khi chạy nhiều instance (cluster, horizontal scaling), bạn cần Redis để đảm bảo distributed locking — tránh nhiều instance chạy cùng một tác vụ đồng thời.

Không kết nối được đến Redis — phải kiểm tra gì?

Thực hiện theo thứ tự:

  1. Kiểm tra Redis đang chạy:
    bash
    redis-cli ping
    # Kết quả: PONG
  2. Kiểm tra biến môi trường LOCK_ADAPTER_REDIS_URL đã cấu hình đúng chưa
  3. Kiểm tra firewall/security group cho phép kết nối từ server Digiforce đến Redis (port 6379)
  4. Kiểm tra mật khẩu nếu Redis yêu cầu xác thực (requirepass trong redis.conf)
  5. Kiểm tra DNS/hostname — đảm bảo hostname trong URL có thể resolve được từ server Digiforce

Plugin báo lỗi LOCK_ADAPTER_REDIS_URL is not configured?

Plugin đọc URL từ hai nguồn (ưu tiên theo thứ tự):

  1. this.options.url — truyền qua cấu hình plugin
  2. process.env.LOCK_ADAPTER_REDIS_URL — biến môi trường

Nếu cả hai đều trống, plugin sẽ ghi log lỗi và không đăng ký adapter. Hệ thống sẽ fallback về lock adapter mặc định (in-memory).

Cách khắc phục: Thêm biến môi trường vào file .env:

bash
LOCK_ADAPTER_REDIS_URL=redis://localhost:6379

Vận hành và hiệu năng

Redis restart thì có ảnh hưởng gì?

Khi Redis restart:

  • Tất cả lock hiện tại bị mất (lock lưu trong memory của Redis)
  • Plugin sẽ tự động kết nối lại nhờ ioredis có sẵn reconnect strategy
  • Các tác vụ đang chờ lock sẽ tự retry nhờ cơ chế retryCount: -1 (retry vô hạn)
  • Có thể xảy ra race condition tạm thời trong khoảng thời gian Redis đang restart

Cảnh báo

Trong khoảng thời gian Redis chưa khởi động lại xong, nhiều instance có thể cùng thực thi một tác vụ. Nếu tác vụ không idempotent, cần xử lý thêm ở tầng application.

Hiệu năng của Redis lock như thế nào?

Redis hoạt động hoàn toàn trên memory nên rất nhanh:

Thao tácThời gian trung bình
acquire (SET NX)< 1ms
release (DEL)< 1ms
extend (PEXPIRE)< 1ms
Network roundtrip0.1–2ms (cùng datacenter)

Overhead so với in-memory lock chủ yếu đến từ network latency, không phải từ Redis processing.

Có thể dùng Redis Cluster hoặc Sentinel không?

Có. Cấu hình URL theo định dạng tương ứng:

  • Sentinel: redis+sentinel://sentinel1:26379,sentinel2:26379/mymaster/0
  • Cluster: redis://node1:6379,node2:6379,node3:6379

Thư viện ioredis hỗ trợ cả hai mode. Tuy nhiên, khi sử dụng Redis Cluster cần lưu ý rằng Redlock algorithm yêu cầu các key nằm trên cùng một shard.

Lỗi thường gặp

Lỗi ECONNREFUSED

Nguyên nhân: Redis không chạy hoặc không lắng nghe trên port/host đã cấu hình.

Cách khắc phục:

bash
# Kiểm tra Redis đang chạy
systemctl status redis
# hoặc
docker ps | grep redis

# Kiểm tra port đang listen
netstat -tlnp | grep 6379

Lỗi NOAUTH hoặc ERR invalid password

Nguyên nhân: Redis yêu cầu mật khẩu nhưng URL không có hoặc sai password.

Cách khắc phục: Thêm password vào URL:

bash
LOCK_ADAPTER_REDIS_URL=redis://:dung_password@localhost:6379

Lỗi OOM command not allowed

Nguyên nhân: Redis hết memory (vượt quá maxmemory).

Cách khắc phục:

  • Tăng maxmemory trong redis.conf
  • Cấu hình maxmemory-policy phù hợp (ví dụ: allkeys-lru)
  • Kiểm tra xem có key nào bị leak không bằng redis-cli info memory

Lỗi LockAcquireError: lock is locked

Nguyên nhân: Gọi tryAcquire nhưng lock đang bị instance khác giữ và timeout đã hết.

Cách khắc phục:

  • Tăng timeout khi gọi tryAcquire
  • Kiểm tra xem task giữ lock có bị treo (stuck) không
  • Đảm bảo TTL đủ ngắn để lock tự hết hạn nếu instance crash

So sánh In-memory Lock vs Redis Lock

Tiêu chíIn-memory LockRedis Lock
Phạm viMột process duy nhấtNhiều process/instance
Tốc độNhanh nhất (không có network)Rất nhanh (< 1ms + network)
Chịu lỗiMất lock khi process restartMất lock khi Redis restart
Phù hợpSingle instance, developmentMulti-instance, production cluster
DependenciesKhông cần gì thêmCần Redis server