Redis Interview: Model, Patterns and Failures

Single-threaded model, data types, persistence, eviction, cluster/sentinel, and the caching failure modes (penetration/breakdown/avalanche) interviewers drill on.

IntermediateUpdated 2026-10-2965K views

Model and data types

Q1: Single-threaded but fast — why?

Everything runs in one event loop (epoll multiplexing) after 6.0 added thread pools only for network IO, not for command execution — avoiding locks, context switches and race conditions. Speed comes from in-memory + efficient data structures, not threads.

Q2: Type → structure → use case.

TypeStructureClassic use
StringSDS计数器、缓存对象 JSON、分布式锁
Listquicklist(双向链表+ziplist)消息队列、最新 N 条
Hashziplist/hashtable对象属性(比 String 存 JSON 省空间)
Setintset/hashtable标签、共同好友
Zsetziplist/skiplist+hashtable排行榜、延时队列
Streamradix tree消息流 + 消费组(5.0+)

Persistence and eviction

Q3: RDB vs AOF.

RDB is a point-in-time snapshot — compact, fast restart, but loses data since the last snapshot. AOF appends every write command — richer durability, fsync policy (always/everysec/no) controls the trade; AOF rewrite compacts it. Modern Redis 4.0+ supports hybrid: AOF base file is RDB-written, then commands append.

Q4: Eviction policies — which for which workload?

  • noeviction: writes error once full — for databases you must never lose silently
  • allkeys-lru: classic cache workload
  • volatile-lru: mixed instance, only keys with TTL participate
  • allkeys-lfu: skewed access (few hot keys) — Redis 4+
maxmemory-policy is meaningless if maxmemory is 0 (default on some distros): Redis grows until the OOM killer kills it. Set maxmemory explicitly on every cache instance.

Failures: penetration / breakdown / avalanche

FailureCauseFix
Cache penetration 缓存穿透查询不存在的 key,每次都打到 DB(恶意攻击/脏 ID)布隆过滤器 / 查不到也缓存空值(短 TTL)
Cache breakdown 缓存击穿单个热 key 过期瞬间,海量请求打到 DB热 key 永不过期 + 后台刷新 / 互斥锁重建
Cache avalanche 缓存雪崩大量 key 同时过期 or 缓存整体宕机过期时间加随机抖动 / Redis 集群 + Hystrix 限流降级
# 互斥锁防击穿(伪代码)
func get(ctx, key):
    v = redis.get(key)
    if v == nil:
        if redis.setnx(lock(key), 1, TTL 10s):   # 只有一个请求去重建
            v = db.query(key)
            redis.set(key, v, ttl)
            redis.del(lock(key))
        else:
            sleep(50ms); return get(ctx, key)     # 其他请求稍后重试
    return v

Q5: Distributed lock — what can go wrong?

  • No expire → holder crash → lock stuck forever: always SET key val NX PX 30000
  • Timeout while still working → someone else grabs it → two holders: watch-dog renewal thread (Redisson)
  • Unlocking someone else's lock: value = unique id, delete with a Lua CAS check
  • Failover: master dies before replicating the lock — Redlock raises the bar, still contested (Martin Kleppmann's critique)

Friends & Partners