跪拜 Guibai
← All articles
Redis

Redis Beyond the Cache: Data Structures, Persistence, and the Line It Won't Cross

By 大大大大晴天 ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

Choosing Redis means accepting a specific failure boundary: asynchronous replication can lose recent writes, AOF's everysec policy can lose about a second, and Cluster is not strongly consistent. This article spells out those boundaries so teams know where Redis belongs and where they still need a database with stronger guarantees.

Summary

This guide lays out Redis as a memory-primary data structure server, not just a key-value cache. It explains the event-driven, non-blocking I/O model and why "single-threaded" is an oversimplification: core command execution is serialized, but background tasks like persistence and async deletion run on separate threads. The article then surveys the nine data types, from String and Sorted Set to Stream and HyperLogLog, showing how each maps to a concrete use case.

The middle sections draw the line between expiration and memory eviction, then compare RDB snapshots with AOF logs, including the loss windows each one tolerates. It walks through replication, Sentinel, and Cluster, clarifying that async replication can lose acknowledged writes and that Cluster is not strongly consistent. The final part covers classic failure patterns, cache penetration, breakdown, and avalanche, plus operational problems like big keys and hot keys, each with mitigation strategies. A decision tree at the end maps Redis's proper place: cacheable state, short-term state, or ephemeral messages, not authoritative data needing strict ACID.

Takeaways
— Redis stores its primary data in memory; disk is used for persistence, recovery, and backup, not for random reads.
— Core command execution is serialized, but Redis also uses background processes and threads for persistence, async deletion, and some I/O, so calling it single-threaded oversimplifies the model.
— Redis's speed comes from memory residency, purpose-built data structures, reduced lock contention, non-blocking I/O, a compact protocol, and pipelining.
— The nine data types are String, Hash, List, Set, Sorted Set, Stream, Bitmap, HyperLogLog, and Geospatial, each with typical commands and caveats.
— Single commands like INCR are atomic against concurrent clients, but MULTI/EXEC transactions do not auto-rollback on runtime errors like relational transactions do.
— Expiration is a business lifecycle attribute of a key; eviction is what happens when memory reaches maxmemory, and eviction policy should not manage data that cannot be rebuilt.
— RDB snapshots can lose all writes made between snapshots; AOF's everysec policy can lose about one second of data, and that is a design target, not an absolute guarantee.
— Redis replication is asynchronous by default, so an acknowledged write may not be persisted on a replica; failover can lose recent writes.
— Redis Cluster divides the keyspace into 16384 hash slots and relies on async replication, so it is not strongly consistent and may stop serving when a majority of primaries fail.
— Cache penetration, breakdown, and avalanche each have countermeasures: validating inputs, caching empty results, mutex rebuilds, random expiration jitter, and rate limiting.
— Big keys and hot keys create latency spikes and bottlenecks; mitigation includes splitting data, using UNLINK, adding local caches, and monitoring with SLOWLOG and MEMORY USAGE.
— Pub/Sub is at-most-once and drops messages if subscribers disconnect; Redis Streams support consumer groups and acks but still require application-level idempotency, retry, and trimming.
— The selection decision tree asks whether data is rebuildable, whether brief loss is acceptable, and whether data exceeds a single node, leading to cache, persistence plus replication, Sentinel, or Cluster.
Conclusions

Redis's guarantees are weaker than they first appear: AOF can lose a second, replication is asynchronous, and Cluster is not strongly consistent, so treating Redis as a durable store will surprise teams that assume database-like durability.

The distinction between expiration and eviction is a frequent source of configuration mistakes; using maxmemory eviction to manage data that cannot be rebuilt is effectively choosing silent data loss.

The article's threading nuance shows why performance claims like 'single-threaded' hide real complexity; serialized command execution avoids locks, but background work on other threads means the behavior is not a simple global lock.

Cluster's 16384-slot design forces application-level decisions about hash tags and multi-key operations, so jumping to Cluster for 'production' adds complexity that may not be justified when a single node plus Sentinel suffices.

Concepts & terms
RDB snapshot
A point-in-time binary dump of the entire Redis dataset, used for backups and faster restart recovery, but it can lose writes made after the last snapshot.
AOF log
Append-only file that records every write command; on restart Redis replays those commands. Sync policies trade durability against write overhead, with everysec typically losing about a second on catastrophic failure.
Hash Slot
Redis Cluster divides the keyspace into 16384 logical slots; each key maps to a slot via CRC16(key) mod 16384, and each primary node owns a range of slots. This is how data is sharded across the cluster.
Hash Tag
A syntax like {tag} inside a key name; only the tag is hashed to a slot. Keys with the same hash tag end up in the same slot, enabling multi-key commands like transactions and pipelined operations.
Pub/Sub at-most-once
A delivery semantic where a message is sent once and never retried; if the subscriber is offline or fails to process it, the message is lost. Fits transient notifications, not reliable business messaging.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗