Bỏ qua, đến nội dung

Câu hỏi thường gặp (FAQ) — Worker ID Allocator Redis

Cài đặt

Bắt buộc phải cài Redis không?

Plugin yêu cầu Redis để hoạt động đúng. Nếu không có Redis:

  • Plugin fallback sang random ID (0-31) — có thể trùng lặp
  • Chỉ chấp nhận được khi chạy 1 instance

Khuyến nghị: luôn dùng Redis khi chạy cluster.

Không kết nối được đến Redis?

Kiểm tra theo thứ tự:

  1. Redis đang chạy? redis-cli ping phải trả về PONG
  2. URL đúng? Kiểm tra REDIS_URL trong .env
  3. Firewall? Port 6379 có mở cho server Digiforce không?
  4. Password? Nếu Redis có password, thêm vào URL: redis://:password@host:6379

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

Plugin sử dụng app.redisConnectionManager.getConnectionSync() — nếu connection manager hỗ trợ Cluster/Sentinel, plugin cũng hoạt động.

Sử dụng

Redis restart thì sao?

Khi Redis restart:

Tình huốngẢnh hưởng
Instance đang chạyGiữ ID đang dùng, nhưng không gia hạn được — chờ Redis khôi phục
Instance khởi động mớiKhông cấp phát được — lỗi hoặc fallback random
Redis khôi phụcTất cả key đã mất → instance hiện tại cần tạo lease mới (tự động ở lần renewal tiếp)

Mẹo

Cấu hình Redis persistence (RDB hoặc AOF) để giảm thiểu mất dữ liệu khi restart. Tuy nhiên, lease có TTL ngắn nên ảnh hưởng không lớn.

Có hơn 32 instance thì sao?

Plugin giới hạn maxWorkerId = 31 (ID 0-31). Nếu tất cả 32 ID bị chiếm:

Error: Cannot allocate worker Id, all IDs are in use

Giải pháp:

  • Kiểm tra xem có instance nào đã crash mà key chưa hết hạn không — chờ 120 giây
  • Tăng maxWorkerId nếu cần hơn 32 instance (cần thay đổi source code)

Hiệu năng như thế nào?

Thao tácTần suấtThời gian
Cấp phát ID1 lần / instance< 1ms (SET NX)
Gia hạn leaseMỗi 60 giây< 1ms (Lua eval)
Release1 lần / shutdown< 1ms (Lua eval)

Overhead không đáng kể — Redis xử lý tất cả các thao tác này trong memory.

Instance crash thì ID có bị mất không?

Không. Key có TTL = 120 giây. Sau 120 giây không có renewal, key tự hết hạn → ID trở lại khả dụng cho instance khác.

Trong khoảng 120 giây chờ, ID vẫn bị "chiếm" — instance mới sẽ nhận ID khác.

Kỹ thuật

Tại sao dùng Lua script thay vì GET + DEL riêng?

Lua script đảm bảo atomic — kiểm tra identifier và thực hiện hành động trong 1 lệnh. Nếu dùng GET rồi DEL riêng:

  1. Instance A: GET key → "192.168.1.100" (đúng identifier)
  2. Key hết hạn → Instance B: SET key "192.168.1.200"
  3. Instance A: DEL keyxóa nhầm key của Instance B!

Lua script tránh race condition này.

Tại sao renewal interval < lease TTL?

  • Lease TTL: 120 giây — key hết hạn sau 120 giây không gia hạn
  • Renewal interval: 60 giây — gia hạn mỗi 60 giây

Khoảng cách 60 giây cho phép:

  • 1 lần renewal thất bại → vẫn còn 60 giây trước khi hết hạn
  • Retry 3 lần nếu thất bại → tăng khả năng phục hồi

Identifier được dùng như thế nào?

Identifier xác định ai sở hữu lease. Khi gia hạn hoặc release, Lua script kiểm tra identifier khớp → tránh instance A release key của instance B.

Cách xác định:

  1. Kubernetes: POD_IP — mỗi pod có IP khác nhau
  2. Máy vật lý: Local IP — mỗi máy có IP khác nhau
  3. Docker: Hostname — mỗi container có hostname khác nhau

Key prefix có tác dụng gì?

Prefix snowflake:worker:{appName}: phân tách namespace:

  • Nhiều ứng dụng Digiforce dùng chung Redis → không xung đột
  • appName mặc định là main — nếu có nhiều app cùng instance, mỗi app có pool riêng