Why Redis Dominates Modern Caching: Features, Architecture, and Best Practices
Redis, an in‑memory C‑language database, offers ultra‑fast read/write speeds, rich data structures, persistence, clustering, and multi‑threaded I/O, making it ideal for distributed caching, locks, queues, and more; this guide explains its fundamentals, comparisons with Memcached, data types, eviction policies, and operational best practices.
1. Simple Introduction to Redis
In short, Redis is a database written in C , but unlike traditional databases its data resides in memory, making it an in‑memory database with extremely fast read/write speed, widely used for caching.
Besides caching, Redis is also frequently used for distributed locks and message queues.
Redis provides many data types, supports transactions, persistence, Lua scripting, and various clustering solutions.
2. Common Distributed Cache Options
The two most widely used distributed cache technologies are Memcached and Redis . Nowadays most projects choose Redis directly; Memcached is rarely seen in new projects.
Distributed caching solves the problem of single‑machine cache capacity limits and the inability to share cache data across multiple service instances.
3. Redis vs. Memcached: Similarities and Differences
Common points :
Both are memory‑based databases commonly used as caches.
Both support expiration policies.
Both have very high performance.
Differences :
Redis supports richer data types (list, set, sorted set, hash, etc.) while Memcached only supports simple key/value.
Redis can persist data to disk; Memcached stores data only in memory.
Redis provides disaster‑recovery mechanisms via persistence.
When memory is exhausted, Redis can swap data to disk; Memcached simply throws an error.
Redis has native cluster mode; Memcached requires client‑side sharding.
Memcached uses a multithreaded, non‑blocking I/O model; Redis is single‑threaded with an event‑driven reactor (multithreading added in 4.0 for heavy‑key deletion and in 6.0 for network I/O).
Redis supports pub/sub, Lua scripts, transactions, and many client languages; Memcached does not.
Expiration deletion: Memcached uses lazy deletion only, while Redis uses both lazy and periodic deletion.
Given these advantages, Redis is the preferred choice for most distributed caching scenarios.
4. Cache Data Processing Flow
The typical workflow is:
If the requested data exists in the cache, return it directly.
If the cache misses, check the database.
If the database has the data, update the cache and return the data.
If the database also misses, return an empty result.
5. Why Use Redis / Why Use Cache?
Cache improves user experience and supports higher concurrency.
High performance: Frequently accessed, rarely changing data can be stored in memory, allowing subsequent requests to be served instantly.
High concurrency: A single Redis instance can handle 100k+ QPS, far exceeding typical MySQL performance (≈10k QPS on a 4‑core, 8 GB machine).
QPS (Queries Per Second): the number of queries a server can execute per second.
6. Common Redis Data Structures and Use Cases
6.1 String
Introduction : Redis implements its own Simple Dynamic String (SDS) which stores binary data and provides O(1) length retrieval.
Common commands : set, get, strlen, exists, decr, incr, setex etc.
Use case : Counters such as page views, likes, etc.
127.0.0.1:6379> set key value # set key‑value
OK
127.0.0.1:6379> get key
"value"
127.0.0.1:6379> exists key
(integer) 1
127.0.0.1:6379> strlen key
(integer) 5
127.0.0.1:6379> del key
(integer) 1
127.0.0.1:6379> get key
(nil)6.2 List
Introduction : Implemented as a doubly linked list, suitable for queue or stack operations.
Common commands : rpush, lpop, lpush, rpop, lrange, llen.
Use case : Message queues, slow query logs, pagination.
127.0.0.1:6379> rpush myList value1
(integer) 1
127.0.0.1:6379> rpush myList value2 value3
(integer) 3
127.0.0.1:6379> lpop myList
"value1"
127.0.0.1:6379> lrange myList 0 -1
1) "value2"
2) "value3"6.3 Hash
Introduction : A map of field‑value pairs, ideal for storing objects.
Common commands : hset, hmset, hexists, hget, hgetall, hkeys, hvals.
Use case : User profiles, product information, etc.
127.0.0.1:6379> hset userInfoKey name "guide" description "dev" age "24"
OK
127.0.0.1:6379> hget userInfoKey name
"guide"
127.0.0.1:6379> hgetall userInfoKey
1) "name"
2) "guide"
3) "description"
4) "dev"
5) "age"
6) "24"6.4 Set
Introduction : Unordered collection without duplicates, useful for membership tests and set operations.
Common commands : sadd, spop, smembers, sismember, scard, sinterstore, sunion.
Use case : Storing follower lists, computing intersections/unions.
127.0.0.1:6379> sadd mySet value1 value2
(integer) 2
127.0.0.1:6379> smembers mySet
1) "value1"
2) "value2"6.5 Sorted Set
Introduction : Set with a score, enabling ordered retrieval.
Common commands : zadd, zcard, zscore, zrange, zrevrange, zrem.
Use case : Leaderboards, real‑time ranking, delayed jobs.
127.0.0.1:6379> zadd myZset 3.0 value1
(integer) 1
127.0.0.1:6379> zrange myZset 0 -1
1) "value1"7. Redis Single‑Threaded Model
Redis uses a reactor‑based event loop (similar to Netty) that runs in a single thread, handling file events (socket reads/writes) via I/O multiplexing (epoll/select).
8. Why Redis Was Initially Single‑Threaded
Reasons include simpler code maintenance, the performance bottleneck being memory/network rather than CPU, and avoiding thread‑related issues such as deadlocks and context switches.
9. Introduction of Multi‑Threading in Redis 6.0
Redis 6.0 adds multi‑threaded network I/O to improve read/write performance, while command execution remains single‑threaded, preserving atomicity.
To enable it, set io-threads-do-reads yes and configure io-threads in redis.conf.
10. Why Set Expiration on Cached Data
Expiration prevents memory exhaustion and supports use cases such as one‑time verification codes or time‑limited tokens.
127.0.0.1:6379> expire key 60
(integer) 1
127.0.0.1:6379> ttl key
(integer) 5611. How Redis Determines Expiration
Redis stores expiration timestamps in a separate hash table (the "expires" dictionary) inside each redisDb structure.
typedef struct redisDb {
...
dict *dict; // key‑value store
dict *expires; // expiration timestamps
...
} redisDb;12. Expiration Deletion Strategies
Lazy deletion : Keys are removed only when accessed.
Periodic deletion : Redis samples a subset of keys at intervals and deletes expired ones.
Redis combines both strategies.
13. Memory Eviction Policies
When memory is insufficient, Redis can evict keys according to one of six policies:
volatile‑lru
volatile‑ttl
volatile‑random
allkeys‑lru
allkeys‑random
no‑eviction
volatile‑lfu (since 4.0)
allkeys‑lfu (since 4.0)
14. Persistence Mechanisms
Redis supports two persistence methods:
RDB (snapshotting) : Periodic point‑in‑time snapshots configured via save directives.
AOF (append‑only file) : Logs every write command; can be configured with appendfsync policies (always, everysec, no).
Since Redis 4.0, mixed RDB+AOF persistence is available via aof-use-rdb-preamble.
15. Transactions
Redis provides transactional semantics with MULTI, EXEC, DISCARD, and WATCH. Commands are queued after MULTI and executed atomically on EXEC, but Redis does not support rollback.
> MULTI
OK
> INCR foo
QUEUED
> INCR bar
QUEUED
> EXEC
1) (integer) 1
2) (integer) 116. Cache Penetration
When a request queries a non‑existent key, it bypasses the cache and hits the database, potentially causing overload.
Mitigation strategies include:
Cache a placeholder for missing keys with a short TTL.
Use a Bloom filter to pre‑filter illegal keys.
17. Cache Avalanche
A cache avalanche occurs when many keys expire simultaneously, flooding the database with requests.
Solutions:
Deploy Redis clusters to avoid single‑point failures.
Apply rate limiting.
Stagger expiration times (randomized TTL) or keep hot data permanently cached.
18. Ensuring Cache‑Database Consistency
The common pattern is Cache‑Aside : on a write, update the database first, then delete or update the cache. If cache deletion fails, retry mechanisms or short TTLs can be used.
Overall, Redis offers a rich feature set that makes it the de‑facto choice for high‑performance caching, data structures, and lightweight persistence in modern backend systems.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
ITFLY8 Architecture Home
ITFLY8 Architecture Home - focused on architecture knowledge sharing and exchange, covering project management and product design. Includes large-scale distributed website architecture (high performance, high availability, caching, message queues...), design patterns, architecture patterns, big data, project management (SCRUM, PMP, Prince2), product design, and more.
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.
