Kinh nghiệm
6 phút đọc6 tháng 6, 2026340

Redis Persistence: Khi nào dùng AOF, RDB, hay cả hai?

RAM mất điện là mất sạch Redis giải quyết bài toán này thế nào? Cùng mổ xẻ AOF vs RDB và cách setup đúng cho production.

N

Nguyễn Nhật Long

@nguyennhatlong1303

A production Redis architecture diagram showing a primary Redis node with both AOF and RDB enabled, connected to two replica nodes, with a Sentinel cluster monitoring all three nodes, arrows showing replication flow and AOF log files on disk for each node, disaster recovery flow shown at bottom with RDB snapshot restore then AOF replay sequence, professional dark theme technical diagram with red and blue accent colors

Redis nhanh vì mọi thứ nằm trên RAM. Nhưng chính cái điều làm nó nhanh lại là điểm yếu chết người: mất điện, crash, restart dữ liệu bay sạch. Đây là lý do Redis cung cấp hai cơ chế persistence hoàn toàn khác nhau về triết lý thiết kế: AOFRDB. Mình đã từng config sai cả hai cái này trong một dự án production và trả giá khá đắt, nên bài này mình sẽ nói thẳng vào những gì thực sự quan trọng.

AOF Ghi lại từng hơi thở của Redis

AOF (Append-Only File) hoạt động theo kiểu log-structured: mỗi lệnh ghi như SET, HSET, LPUSH,... đều được append vào cuối file appendonly.aof trên đĩa. Đơn giản vậy thôi.

Flow cụ thể là: client gửi command → Redis thực thi ngay trên RAM → sau đó mới append lệnh đó vào file log. Lưu ý là Redis thực thi trước, ghi log sau không phải ngược lại như một số người hay nhầm.

Khi restart, Redis đọc file AOF từ đầu đến cuối và replay lại toàn bộ các lệnh đó để tái tạo state. Nghe có vẻ thô, nhưng nó hoạt động rất tốt trong thực tế.

shown as a config panel on the right, dark background with red Redis logo accent, flat minimal design)

Cái quyết định độ an toàn của AOF chính là config fsync:

Theo kinh nghiệm của mình, everysec là sweet spot cho hầu hết các hệ thống. Bạn chấp nhận mất tối đa 1 giây dữ liệu đổi lấy performance ổn định trade-off này hoàn toàn hợp lý.

fsync modeÝ nghĩaRủi ro mất dataPerformance impact
`always`Fsync sau mỗi lệnh ghiGần như 0Chậm nhất, I/O nặng
`everysec`Fsync mỗi 1 giây một lầnTối đa ~1 giây dataCân bằng tốt ✅
`no`Để OS tự quyết địnhCó thể mất nhiều hơnNhanh nhất

Vấn đề lớn nhất của AOF là file nó phình to theo thời gian cực kỳ nhanh. Hãy tưởng tượng bạn SET key 1, rồi SET key 2, rồi SET key 3 AOF ghi cả ba lệnh, dù thực ra chỉ giá trị cuối cùng mới có ý nghĩa. Redis có cơ chế BGREWRITEAOF để compact file lại, nhưng nếu không monitor cẩn thận, file AOF có thể ăn hết disk lúc nào không hay. Mình đã từng thấy một instance Redis có AOF file lên tới 40GB trong khi actual data chỉ khoảng 3GB đau lòng lắm.

RDB Chụp ảnh, đơn giản và hiệu quả

RDB (Redis Database Snapshot) tiếp cận theo hướng hoàn toàn khác: thay vì ghi từng lệnh, nó chụp lại toàn bộ dataset tại một thời điểm cụ thể và dump ra một file binary duy nhất.

Cái hay nhất của RDB nằm ở cách nó thực hiện việc này mà không block main thread. Redis dùng system call fork() để tạo một child process. Child process này kế thừa toàn bộ memory space của parent nhờ cơ chế Copy-on-Write (COW) của OS nghĩa là OS không thực sự copy toàn bộ RAM ngay lập tức, mà chỉ copy những page nào bị modify trong lúc child đang dump. Main process vẫn tiếp tục serve request bình thường.

RDB snapshot with fork and COW

Config RDB trong redis.conf trông như này:

CONF
1# Tự động snapshot khi có ít nhất N thay đổi trong M giây
2save 900 1 # 900 giây nếu có >= 1 thay đổi
3save 300 10 # 300 giây nếu có >= 10 thay đổi
4save 60 10000 # 60 giây nếu có >= 10000 thay đổi
5
6# Hoặc trigger thủ công
7BGSAVE

Restore từ RDB cực kỳ nhanh Redis chỉ cần load file binary vào RAM là xong, không cần replay bất kỳ lệnh nào. Đây là lý do RDB thắng tuyệt đối về tốc độ recovery.

Nhưng nhược điểm không thể bỏ qua: nếu Redis crash ngay giữa hai chu kỳ snapshot, toàn bộ dữ liệu từ sau lần snapshot cuối sẽ mất. Với config save 300 10, bạn có thể mất đến 5 phút dữ liệu. Với một số use case, đây là điều chấp nhận được. Với một số khác thì không.

Một điểm nữa anh em cần lưu ý: trên dataset lớn (vài chục GB trở lên), cái fork() call đó có thể gây ra micro-stutter main thread bị pause vài millisecond đến vài giây tùy kích thước data và tốc độ đĩa. Mình đã từng thấy latency spike rõ ràng trên Grafana mỗi khi RDB snapshot chạy. Không phải lúc nào cũng nghiêm trọng, nhưng cần biết để không bị bất ngờ.

Vậy production thì setup thế nào?

Câu trả lời phụ thuộc hoàn toàn vào Redis đang đóng vai trò gì trong hệ thống của bạn.

Trường hợp 1: Redis chỉ làm cache thuần túy

Nếu data trong Redis chỉ là cache và khi cache miss bạn có thể query lại từ database gốc thì thực ra bạn không cần persistence mạnh. Hai option:

  • Dùng RDB với interval dài (backup định kỳ phòng trường hợp cần warm-up nhanh)
  • Hoặc tắt hoàn toàn persistence để đạt max performance

Tắt persistence trong config:

CONF
1# Tắt RDB
2save ""
3
4# Tắt AOF
5aoppenonly no

Trường hợp 2: Redis làm primary store hoặc cần durability cao

Đây là lúc bạn bật cả hai và đây cũng là pattern mình recommend cho hầu hết các hệ thống fintech, e-commerce mà mình từng làm:

CONF
1# Bật AOF với everysec
2appendonly yes
3appendfsync everysec
4
5# Giữ RDB làm backup định kỳ
6save 3600 1
7save 300 100

Lý do dùng cả hai: RDB đóng vai trò disaster recovery khi cần restore toàn bộ hệ thống sau sự cố lớn, load RDB nhanh hơn replay AOF rất nhiều. AOF đóng vai trò bảo hiểm cho những giây cuối cùng trước khi crash. Khi Redis restart với cả hai file, nó sẽ ưu tiên dùng AOF (vì AOF có data mới hơn).

Redis persistence architecture for production

Mình thấy cái pattern này hay ở chỗ nó cover được cả hai scenario: crash nhỏ (AOF handle) và disaster recovery toàn bộ hệ thống (RDB handle). Hai cơ chế bổ sung cho nhau thay vì cạnh tranh.

Một vài thứ hay bị bỏ qua

Monitor AOF file size thường xuyên và setup auto-aof-rewrite-percentage để trigger rewrite tự động:

CONF
1auto-aof-rewrite-percentage 100 # Rewrite khi file tăng gấp đôi
2auto-aof-rewrite-min-size 64mb # Nhưng chỉ khi file >= 64MB

Với RDB, nếu bạn đang chạy Redis trên instance có RAM lớn (32GB+), hãy test thử latency spike khi BGSAVE chạy trước khi đưa lên production. Đôi khi cần tune lại schedule để tránh giờ cao điểm.

Cuối cùng đừng quên copy file RDB ra ngoài instance định kỳ. File RDB nằm trên cùng máy với Redis mà máy đó chết cứng thì backup cũng vô nghĩa. S3, GCS, hay bất kỳ object storage nào đều được, miễn là off-instance.

NN

Nguyễn Nhật Long

@nguyennhatlong1303

Nguyễn Nhật Long is a Senior Frontend Engineer and Frontend Team Leader with 7 years of experience building real-time fintech platforms. Specializing in React, Next.js, TypeScript, and React Native, shipping 10+ products across Web, Mobile, Telegram Mini-Apps, and Web3.

Thấy hay? Chia sẻ cho bạn bè!