Mastering Redis Persistence: RDB, AOF, and Hybrid Strategies Explained
This article provides a comprehensive guide to Redis persistence mechanisms, covering the internal database structure, detailed operations of RDB snapshotting and AOF command logging, their configurations, advantages, drawbacks, hybrid persistence, and practical strategy recommendations for various deployment scenarios.
Preface
Redis is an in‑memory database; to avoid permanent data loss when the process exits, it must periodically persist data to local disk either as snapshots (RDB) or as a log of write commands (AOF). This article explains both mechanisms, their operation, and underlying principles.
Body
Redis stores data as key‑value pairs. Understanding its internal structure helps to grasp the persistence mechanisms.
1. Redis Database Structure
A single Redis instance has 16 logical databases by default (configurable). Each database is represented by a
redisDbstructure that tracks the keyspace, expiration times, blocked keys, watched keys, eviction pool, database ID, and average TTL.
<code>typedef struct redisDb {
dict *dict; // key‑value pairs
dict *expires; // key expiration timestamps
dict *blocking_keys; // keys currently blocked
dict *ready_keys; // keys ready to be unblocked
dict *watched_keys; // keys watched by WATCH
struct evictionPoolEntry *eviction_pool;
int id; // database number
long long avg_ttl; // average TTL
} redisDb;
</code>The
dictholds all key‑value pairs, where keys are strings and values can be strings, lists, hashes, sets, or sorted sets.
2. RDB Persistence
RDB (snapshot) persistence writes the entire dataset to a compressed binary
.rdbfile. The core functions are
rdbSave(create file) and
rdbLoad(load file on restart).
RDB files are full‑dataset snapshots, suitable for backup and fast recovery. Redis can generate RDB files manually (SAVE, BGSAVE) or automatically based on configured
saveconditions.
2.1 RDB Creation and Loading
Default configuration in
redis.conf:
<code># RDB file name
dbfilename dump.rdb
# Directory for RDB and AOF files
dir /usr/local/var/db/redis/
</code>1. SAVE command
SAVE is synchronous and blocks the server until the RDB file is created.
Client command:
127.0.0.1:6379> SAVE <code>127.0.0.1:6379> SAVE
OK
</code>2. BGSAVE command
BGSAVE forks a child process to create the RDB file, allowing the parent to continue serving clients.
Client command:
127.0.0.1:6379> BGSAVE <code>127.0.0.1:6379> BGSAVE
Background saving started
</code>The forked child writes the snapshot, then notifies the parent.
2.2 Automatic Saving
Redis checks the
saveconditions every 100 ms via
serverCron. If any condition (e.g., 900 seconds with at least 1 change) is met, BGSAVE is triggered automatically.
<code>save 900 1
save 300 10
save 60 10000
</code>2.3 RDB File Structure
An RDB file consists of a header ("REDIS"), version, auxiliary metadata, database entries, EOF marker, and checksum. Each non‑empty database contains a SELECTDB marker, database number, and a series of key‑value pairs, where each pair may include an expiration time and a type identifier.
3. AOF Persistence
AOF logs every write command to an append‑only file. When enabled, Redis replays the AOF on restart to reconstruct the dataset.
3.1 AOF Creation and Loading
Enable AOF by setting
appendonly yesin
redis.conf. The server then writes each write command to
appendonly.aof.
<code># Enable AOF
appendonly yes
appendfilename appendonly.aof
dir /usr/local/var/db/redis/
</code>Example AOF content after a few commands:
<code>*2 $6 SELECT $1 0
*5 $4 SADD $6 fruits $5 apple $6 banana $6 orange
*5 $5 LPUSH $7 numbers $3 128 $3 256 $3 512
*3 $3 SET $3 msg $5 hello
</code>3.2 AOF Execution Flow
All write commands are first appended to an in‑memory buffer
aof_buf. Depending on the
appendfsyncpolicy, the buffer is flushed to disk using
write(),
fsync(), or both.
appendfsync always
Every command triggers an immediate
fsync, guaranteeing at most one lost command but causing high I/O latency.
appendfsync no
Commands are written without explicit
fsync; the OS syncs periodically, risking more data loss.
appendfsync everysec
Default setting: writes are flushed each second, balancing performance and safety.
3.3 AOF Rewrite
When the AOF grows large, Redis can rewrite it: a child process creates a new compacted AOF from the current dataset, while the parent continues to serve clients and buffer new commands. After the child finishes, the new file replaces the old one.
4. Hybrid Persistence (RDB + AOF)
Redis 4.0 introduces a hybrid mode where the AOF file starts with an RDB snapshot (preamble) followed by incremental AOF commands. Enable with
aof-use-rdb-preamble yes.
<code># Enable hybrid persistence
aof-use-rdb-preamble yes
</code>5. Choosing a Persistence Strategy
Both RDB and AOF incur performance overhead. RDB is heavier on CPU during snapshot but has fast recovery; AOF writes more frequently, impacting I/O but offering finer‑grained durability. In practice, choose based on data‑loss tolerance, workload, and deployment topology (single‑node, master‑slave, disaster‑recovery).
Cache‑only use‑case: disable persistence.
Single‑node with acceptable minutes‑level loss: prefer RDB.
Require second‑level durability: prefer AOF.
Combine both for safety, accepting higher I/O.
Conclusion
The article introduced Redis’s internal database layout and detailed its three persistence mechanisms—RDB snapshots, AOF command logging, and the hybrid RDB‑AOF mode—covering creation, loading, file formats, configuration options, advantages, disadvantages, and practical strategy recommendations for various deployment scenarios.
macrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.