14.2 Redis Command Model, Transactions, and Persistence
Metadata Card
- Prerequisites: 14.1 Memory-Optimized Database
- Keywords: Redis, atomic commands, MULTI/EXEC, WATCH, RDB, AOF, replication
- Code Language: Redis CLI
Redis's strength lies in its "command model centered around data structures," not in simply moving relational tables into memory. Each data type (string, hash, list, set, sorted set, stream) offers atomic operations tailored to its use case. Choosing the wrong structure undermines memory efficiency, latency, and maintainability alike.
Prefer atomic commands over read (modify) write
INCR item:42:view_count
HINCRBY item:42 stock -1
ZINCRBY ranking 15 player:7These operations are atomically executed at the command boundary. If a client first GET, performs local computation, and then SET, multiple clients may overwrite each other's results.
From the client's perspective, Redis command execution is largely serial. However, modern Redis uses background threads, I/O threads, and child processes to handle other tasks. More accurately, "the core data structure operations for most commands are executed on the main execution thread," rather than "Redis has only one thread." Slow commands, very large keys, or Lua scripts can still block other requests.
MULTI/EXEC is not a relational database transaction
MULTI
DECRBY item:42:stock 1
INCR order:created
EXECCommands queued after MULTI are executed consecutively at EXEC, ensuring no interleaving with commands from other clients. However, it lacks the automatic rollback behavior found in relational databases: if a command fails during execution due to type or other reasons, the remaining commands in the queue can still proceed.
When conditional updates are required, use WATCH for optimistic checking:
WATCH item:42:stock
GET item:42:stock
MULTI
DECRBY item:42:stock 1
EXECIf the monitored key is modified after WATCH, EXEC returns an empty result. The client must then re-read, re-evaluate, and perform bounded retries. For multi-step validations, server-side Lua or Functions are better suited to consolidate the logic into a single atomic operation. However, scripts should remain concise and input sizes should be strictly limited.
RDB: Timepoint Snapshots
RDB periodically generates compact snapshots of the dataset. Typically, a child process writes the snapshot to a temporary file, then atomically replaces the old snapshot, while the parent process continues serving requests. Copy-on-write (COW) allows the parent and child to initially share memory pages.
Key trade-offs of RDB:
- Files are compact, leading to faster backups and quicker restarts for large datasets;
- Writes between snapshots may be lost in the event of a failure;
fork()itself can introduce latency, and during write-intensive periods, COW increases memory consumption;- RDB files still require copying to a separate fault domain; a single-machine file is not sufficient for disaster recovery.
It's not accurate to simply double peak memory usage, actual memory consumption depends on the proportion of memory pages modified during snapshotting, as well as allocator and kernel behavior. Capacity planning should be based on stress-tested peak loads.
AOF: Record Write Commands and Flush According to Strategy
AOF records the commands that modify the dataset and replay them upon restart. Common strategies for appendfsync:
| Strategy | Acknowledgment Path | Typical Data Window |
|---|---|---|
always | Each batch writes requests an fsync before acknowledgment | Minimal, but still constrained by hardware and failure models |
everysec | Background fsync roughly once per second | May lose up to about one second of recent writes in case of failure |
no | Delegated to the operating system for flushing | Window determined by OS-level policies |
AOF grows over time and must be rewritten into a shorter, state-reconstructing form. Starting with Redis 7, multi-part AOF is adopted: a base file, one or more incremental files, and a manifest together describe the valid log set. The older model of simply writing "a single AOF file is replaced" is no longer sufficient.
Enable Both AOF and RDB at the Same Time
Both can be enabled simultaneously; during restart, Redis will prefer recovering from the more complete AOF file. An AOF base can use RDB format, which is not the same as "simultaneously saving independent RDB snapshots for backup."
Persistent configuration should be derived from business tolerance:
- A pure in-memory cache can disable persistence, but you must verify that the database can withstand a full cache loss during a source revalidation;
- When a second-level window is acceptable, AOF
everyseccan be evaluated; - High-value authoritative data still requires replication, backups, recovery drills, and idempotent writes, relying solely on AOF is not sufficient;
WAITCan wait for replica acknowledgments but won't automatically make Redis a strongly consistent CP database; failover may still be affected by persistence and replication configurations.
Eviction and Persistence Are Two Axes
maxmemory-policy The eviction policy determines which keys are removed when memory usage reaches its limit; RDB or AOF determines how existing data is restored. A cache instance that permits eviction of business data (even with AOF writing on every disk flush) may still persist the eviction operation faithfully.
Therefore, the instance's role must be clearly defined:
- Cache: Eviction is allowed; source data can be reconstructed;
- Session or queue: Requires explicit definition of semantics for data loss, duplication, and expiration;
- Authoritative state: Typically disallows arbitrary eviction and demands a reliability design more robust than single-node persistence.
Operations Monitoring
INFO persistence
INFO memory
SLOWLOG GET 20
LATENCY DOCTORMonitor the most recent RDB/AOF status, whether rewrite is stalled, fork/COW memory usage, memory fragmentation, slow commands, and master-slave lag. During recovery drills, actually start a new instance from backup and verify key counts, critical business objects, and application read/write operations, don’t just check that files exist.
References
After completing this chapter, you should be able to decompose a "memory-only" system into four verifiable questions: data layout, execution model, persistence confirmation, and recovery budget.