Databases 36 min read

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.

ITFLY8 Architecture Home
ITFLY8 Architecture Home
ITFLY8 Architecture Home
Why Redis Dominates Modern Caching: Features, Architecture, and 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) 56

11. 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) 1

16. 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.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

performanceCachedatabaseredisData Structures
ITFLY8 Architecture Home
Written by

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.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.