Ở bài 1 ta đã cảnh báo: Redis sống trong RAM, dữ liệu sẽ mất khi tiến trình chết nếu không ghi xuống đĩa. Nhưng "mất bao nhiêu" và "làm sao để không mất" phụ thuộc vào persistence — và Redis cho hai cơ chế với hai triết lý khác hẳn nhau. RDB chụp ảnh toàn bộ dữ liệu theo định kỳ (như lưu game thỉnh thoảng). AOF ghi lại mọi lệnh ghi vào một log (như nhật ký giao dịch). Chọn sai hoặc không hiểu đánh đổi là hoặc mất nhiều dữ liệu hơn tưởng, hoặc trả giá hiệu năng không cần thiết. Bài này (phần 10/12) đo thật cả hai trong redis-lab.

RDB và AOF: hai triết lý

Ảnh chụp đoạn mã nền tối minh hoạ persistence Redis có mất dữ liệu khi chết không RDB và AOF, Redis sống trong RAM mất dữ liệu khi tắt nếu không ghi xuống đĩa hai cơ chế hai đánh đổi độ bền vs hiệu năng. RDB ảnh chụp định kỳ snapshot BGSAVE fork tiến trình con ghi toàn bộ dữ liệu ra dump.rdb CONFIG GET save luật tự snapshot 3600 1 300 100 60 10000 snapshot nếu lớn hơn bằng 1 thay đổi mỗi 3600s lớn hơn bằng 100 mỗi 300s lớn hơn bằng 10000 mỗi 60s file nhỏ gọn khởi động lại nhanh nhưng mất dữ liệu từ snapshot cuối tới lúc chết. AOF ghi mọi lệnh ghi vào log CONFIG SET appendonly yes mỗi lệnh ghi SET INCR nối vào AOF appendfsync bằng everysec khi nào ép ghi xuống đĩa fsync always fsync mỗi lệnh không mất nhưng chậm everysec fsync mỗi giây mất tối đa 1s cân bằng tốt mặc định no để OS quyết nhanh nhất mất nhiều nhất. Hybrid Redis 7 mặc định khi bật AOF AOF base bằng snapshot RDB cộng incr.aof bằng lệnh ghi từ đó khởi động nhanh base RDB cộng độ bền cao incr AOF tốt nhất cả hai

Hình 1: RDB chụp snapshot định kỳ (BGSAVE fork tiến trình con ghi dump.rdb, mất dữ liệu giữa hai lần chụp); AOF ghi mọi lệnh ghi (appendfsync always/everysec/no — đánh đổi độ bền vs tốc độ). Redis 7 dùng hybrid: AOF base RDB + incr AOF.

  • RDB (Redis Database): BGSAVE fork một tiến trình con, ghi toàn bộ dữ liệu ra một file nhị phân dump.rdb. Có luật tự snapshot (save). File nhỏ gọn, khởi động lại nhanh (đọc một file). Nhưng mất toàn bộ dữ liệu từ snapshot cuối tới lúc chết.
  • AOF (Append Only File): ghi mọi lệnh ghi (SET/INCR...) vào một log, nối thêm liên tục. Độ bền do appendfsync quyết: always (fsync mỗi lệnh — không mất nhưng chậm), everysec (fsync mỗi giây — mất tối đa ~1s, cân bằng, mặc định), no (để OS quyết — nhanh nhất, mất nhiều nhất).

Đo thật: RDB snapshot và AOF

Nạp 1000 key rồi kiểm cả hai:

Ảnh chụp bảng kết quả đo thật RDB snapshot và AOF trên redis-lab output thật redis:7 1000 key BGSAVE appendonly. Một RDB snapshot BGSAVE luật tự snapshot CONFIG GET save 3600 1 300 100 60 10000 BGSAVE rdb_last_bgsave_status ok file dump.rdb trong data 16.881 byte RDB fork tiến trình con ghi toàn bộ dữ liệu ra một file nhị phân nhỏ gọn luật 60 10000 bằng snapshot nếu có 10.000 thay đổi trong 60 giây giữa hai snapshot dữ liệu mới chưa kịp ghi sẽ mất nếu Redis chết. Hai AOF append-only file CONFIG SET appendonly yes aof_enabled 1 appendfsync độ bền everysec mất tối đa 1s file AOF base.rdb cộng incr.aof cộng manifest aof_last_write_status bằng ok kích thước RDB vs AOF cùng dữ liệu 16.881 vs 21.161 byte AOF ghi mọi lệnh ghi vào log nối thêm nên bền hơn RDB mất tối đa 1s với everysec nhưng file lớn hơn và ghi liên tục Redis 7 dùng hybrid AOF gồm một base RDB cộng phần incr AOF khởi động nhanh đọc base mà vẫn bền replay incr chọn cache thuần RDB hoặc tắt hẳn dữ liệu cần bền AOF everysec

Hình 2: Đo thật. (1) RDB: luật save "3600 1 / 300 100 / 60 10000", BGSAVE status = ok, dump.rdb 16.881 byte. (2) AOF: aof_enabled=1, appendfsync=everysec, file base.rdb+incr.aof+manifest, write status ok; RDB 16.881 vs AOF 21.161 byte cho cùng dữ liệu.

Kết quả thật:

  • ① RDB snapshot: luật tự snapshot là 3600 1 300 100 60 10000 — nghĩa là snapshot nếu có ≥1 thay đổi trong 3600s, ≥100 trong 300s, hoặc ≥10000 trong 60s. BGSAVE chạy xong với rdb_last_bgsave_status = ok, tạo file dump.rdb 16.881 byte. Đây là một ảnh chụp nhỏ gọn của toàn bộ dữ liệu. Rủi ro: giữa hai snapshot, dữ liệu mới chưa kịp ghi sẽ mất nếu Redis chết — ví dụ nếu snapshot cuối cách đây 4 phút, bạn mất tới 4 phút dữ liệu.
  • ② AOF: CONFIG SET appendonly yes → aof_enabled=1, appendfsync=everysec. AOF (Redis 7) gồm ba file: base.rdb (snapshot nền) + incr.aof (lệnh ghi từ đó) + manifest. aof_last_write_status=ok. Cùng dữ liệu, tổng AOF 21.161 byte so với RDB 16.881 byte — AOF lớn hơn vì lưu lệnh, không chỉ trạng thái cuối. Đổi lại bền hơn: với everysec, mất tối đa ~1 giây dữ liệu khi chết.

Điểm hay của Redis 7: hybrid. Khi bật AOF, phần base là một snapshot RDB và incr là các lệnh ghi từ snapshot đó. Khởi động lại nhanh (đọc base RDB) mà vẫn bền (replay incr AOF) — lấy ưu điểm cả hai.

Đánh đổi cần cân nhắc

Chọn persistence theo VAI TRÒ của Redis. Redis làm cache thuần (dữ liệu tái tạo được từ nguồn): có thể tắt hẳn persistence (nhanh nhất, không I/O đĩa) hoặc chỉ RDB thưa (để warm cache nhanh sau restart). Redis chứa dữ liệu cần bền (hàng đợi, session quan trọng): dùng AOF everysec (mất tối đa 1s — chấp nhận được cho hầu hết), hoặc AOF always nếu tuyệt đối không được mất (chịu chậm). Đừng bật AOF always cho một cache — tốn I/O vô ích.

appendfsync always chậm đáng kể — đo trước khi dùng. always fsync mỗi lệnh ghi xuống đĩa, biến mỗi write thành một thao tác đĩa — throughput ghi giảm rất nhiều so với everysec (vốn fsync gom mỗi giây). Với dữ liệu mà "mất 1 giây là thảm hoạ" thì đáng; với phần lớn trường hợp, everysec là điểm cân bằng đúng. Và nhớ: ngay cả always cũng không bằng cam kết ACID của một RDBMS — Redis không phải database giao dịch.

Persistence KHÔNG thay thế backup và replication. RDB/AOF ghi xuống đĩa của chính máy đó — nếu đĩa hỏng hoặc máy cháy, dữ liệu vẫn mất. Độ bền thật cần: replication (bản sao trên máy khác), và backup định kỳ file RDB sang nơi khác (RDB nhỏ gọn rất hợp để backup). BGSAVE fork tiến trình cũng tốn RAM (copy-on-write) và có thể gây nhịp latency khi dữ liệu lớn — cân nhắc lịch snapshot ngoài giờ cao điểm.

Ba ý mang về

  1. Redis có mất dữ liệu khi chết — persistence quyết định mất bao nhiêu. RDB snapshot định kỳ (đo thật: BGSAVE ok, dump.rdb 16.881 byte) mất dữ liệu giữa hai lần chụp; AOF ghi mọi lệnh (đo thật: everysec, 21.161 byte) mất tối đa ~1 giây.
  2. RDB nhỏ gọn/khởi động nhanh, AOF bền hơn/file lớn hơn — Redis 7 hybrid lấy cả hai. Cùng 1000 key, RDB 16.881 vs AOF 21.161 byte. Hybrid (base RDB + incr AOF) khởi động nhanh mà vẫn bền.
  3. Chọn theo vai trò, và persistence không thay backup/replication. Cache thuần → tắt hoặc RDB thưa; dữ liệu cần bền → AOF everysec (always nếu tuyệt đối không mất, chịu chậm). RDB/AOF ghi đĩa cùng máy — độ bền thật vẫn cần replication + backup ra nơi khác.

Nguồn

Phần sau ta đo bộ nhớ Redis sâu hơn: MEMORY USAGE từng key, phát hiện big key gây chậm cả server, và vì sao phải dùng SCAN thay vì KEYS để duyệt không block.