Thông báo lỗi
Việc di chuyển các key giữa các instance Redis bằng DUMP và RESTORE thường rất đơn giản, cho đến khi bạn gặp phải trở ngại này:
(error) ERR DUMP payload version or checksum are wrong
Tại sao lỗi này xảy ra?
Có khả năng bạn đang gặp phải một trong hai vấn đề phổ biến sau: Hoặc là các phiên bản Redis không tương thích, hoặc dữ liệu nhị phân đã bị hỏng trong quá trình truyền tải.
- Vấn đề tương thích tiến (Forward Compatibility): Redis rất giỏi trong việc đọc dữ liệu cũ (tương thích ngược - backward compatibility), nhưng nó không thể dự đoán tương lai. Nếu bạn dump một key từ Redis 7.0 (sử dụng RDB phiên bản 10) và cố gắng restore nó trên Redis 6.2 (RDB phiên bản 9), nó sẽ thất bại. Server cũ đơn giản là không hiểu định dạng mới hơn.
- Hỏng dữ liệu nhị phân: Lệnh
DUMPxuất ra dữ liệu nhị phân thô. Nếu bạn sao chép và dán dữ liệu này từ terminal hoặc lưu nó dưới dạng tệp văn bản UTF-8 tiêu chuẩn, bạn có thể sẽ mất các byte null hoặc làm hỏng các ký tự đặc biệt. Thậm chí chỉ một thay đổi bit nhỏ cũng làm cho checksum không còn hợp lệ.
Cách khắc phục
1. Kiểm tra phiên bản Redis
Bắt đầu bằng cách kiểm tra phiên bản trên cả máy chủ nguồn và máy chủ đích. Chạy lệnh này trên cả hai instance:
redis-cli INFO Server | grep redis_version
Nếu máy chủ nguồn đang chạy phiên bản chính cao hơn máy chủ đích, lệnh RESTORE chắc chắn sẽ thất bại. Ví dụ, việc chuyển dữ liệu từ Redis 7.2 về 6.0 là không thể đối với các payload của DUMP.
2. Sử dụng lệnh MIGRATE
Nếu các máy chủ có thể giao tiếp trực tiếp qua mạng, hãy ngừng sử dụng DUMP và RESTORE thủ công. Lệnh MIGRATE mang tính nguyên tử (atomic) và xử lý việc truyền tải nội bộ, loại bỏ hoàn toàn các rắc rối về mã hóa.
# Cú pháp: MIGRATE host port key destination-db timeout [COPY] [REPLACE]
Để di chuyển một key có tên user:profile:100 sang máy chủ tại 10.0.0.5, hãy sử dụng:
MIGRATE 10.0.0.5 6379 "user:profile:100" 0 2000 COPY
2000 là thời gian chờ 2 giây. Cờ COPY giữ lại key trên máy chủ nguồn—điều này rất quan trọng để di chuyển dữ liệu an toàn.
3. Xử lý dữ liệu nhị phân đúng cách trong mã nguồn
Khi viết script, hãy xử lý payload như một mảng byte (byte array), tuyệt đối không để dạng chuỗi (string). Trong Python, hãy đảm bảo bạn đang sử dụng chế độ bytes để tránh các chuyển đổi mã hóa không mong muốn:
import redis
# Kết nối mà không tự động giải mã
src = redis.Redis(host='source-db', decode_responses=False)
dst = redis.Redis(host='dest-db', decode_responses=False)
key_name = "session:active:99"
raw_payload = src.dump(key_name)
if raw_payload:
try:
# 0 nghĩa là không hết hạn; dùng replace=True để ghi đè các key hiện có
dst.restore(key_name, 0, raw_payload, replace=True)
print("Truyền dữ liệu thành công")
except redis.exceptions.ResponseError as e:
print(f"Di chuyển thất bại: {e}")
4. Chuyển dữ liệu sang phiên bản cũ hơn
Nếu bạn bắt buộc phải hạ cấp (ví dụ: chuyển từ Redis 7 của nhà cung cấp đám mây sang Redis 6 on-premise), DUMP sẽ không hoạt động. Bạn có hai lựa chọn thực tế:
- Di chuyển logic (Logical Migration): Viết một script để lấy dữ liệu bằng các lệnh đặc thù cho từng loại dữ liệu như
HGETALLcho hash hoặcLRANGEcho list. Sau đó, nạp lại chúng vào đích bằngHSEThoặcRPUSH. Cách này chậm hơn nhưng không phụ thuộc vào phiên bản. - Nâng cấp máy chủ đích: Cách sửa lỗi ổn định nhất là nâng cấp Redis đích để khớp hoặc cao hơn phiên bản nguồn. Điều này giúp tránh mọi vấn đề về tương thích.
Xác minh
Kiểm tra với một chuỗi đơn giản để khoanh vùng vấn đề. Nếu một chuỗi cơ bản cũng thất bại, gần như chắc chắn bạn đang gặp vấn đề không tương thích phiên bản.
# Trên Nguồn
SET debug_key "test"
DUMP debug_key
# Ví dụ đầu ra: "\x00\x04test\n\x00\xbd\xc6\x1e\x96\x9c\x13\xf6\xec"
# Trên Đích
RESTORE debug_key 0 "\x00\x04test\n\x00\xbd\xc6\x1e\x96\x9c\x13\xf6\xec"
# Sẽ trả về OK
Mẹo chuyên sâu và phòng ngừa
Đừng tin tưởng vào clipboard. Việc sao chép dữ liệu nhị phân từ terminal thường thêm các ký tự ẩn hoặc loại bỏ các byte null. Nếu bạn phải sử dụng tệp, hãy dùng redis-cli --raw DUMP key > key.bin để đảm bảo đầu ra không bị thay đổi bởi cài đặt ngôn ngữ (locale) của terminal.
Tôi luôn xác minh các tệp di chuyển của mình trước khi import. Bạn có thể sử dụng Trình tạo mã băm trên ToolCraft để tạo checksum SHA-256 cho dữ liệu đã xuất. Việc so sánh mã băm trước và sau khi truyền đảm bảo không một byte nào bị mất trong quá trình scp hoặc rsync.

