覆盖基础原理、数据结构、持久化、缓存三大问题、分布式锁、高可用架构等核心考点
每题附:答案 + 追问链路 + 面试加分话术


一、基础原理篇

Q1:Redis 为什么这么快?

答: Redis 单线程能支撑 10W+ QPS,核心原因有四:

  1. 纯内存操作:数据全部存在内存中,读写无磁盘 I/O(持久化是异步的)
  2. 单线程模型:避免了多线程的上下文切换和锁竞争开销
  3. I/O 多路复用:基于 epoll/kqueue 实现单线程同时处理大量连接
  4. 高效数据结构:SDS、跳表、压缩列表等底层结构针对场景深度优化

加分话术: “Redis 6.0 引入了多线程 I/O(处理网络读写),但命令执行仍然是单线程,所以不会出现并发安全问题。多线程只是用来解决网络 I/O 瓶颈。”

追问:为什么不用多线程执行命令?

  • 多线程需要加锁,引入锁竞争反而降低性能
  • Redis 的瓶颈在网络 I/O 而非 CPU,单线程足够
  • 单线程模型简单,不会有死锁、上下文切换等问题

Q2:Redis 有哪些数据类型?底层数据结构是什么?

答:

数据类型 底层编码 说明
String int / embstr / raw (SDS) 最常用,可存字符串、整数、浮点数
List listpack(quicklist) 有序列表,支持头尾操作
Hash listpack / hashtable 哈希表,适合存对象
Set intset / hashtable 无序集合,自动去重
ZSet listpack / skiplist+hashtable 有序集合,按 score 排序
Bitmap String 的二进制操作 位图,适合统计在线状态
HyperLogLog 概率算法 基数统计,误差 0.81%,极省内存
Stream radix tree + listpool 消息队列,支持消费者组

底层数据结构对照:

底层结构 说明
SDS (Simple Dynamic String) 二进制安全的动态字符串,O(1) 获取长度
listpack 紧凑列表,替代 ziplist(Redis 7.0+)
quicklist 双向链表 + listpack 的混合结构
skiplist 跳表,ZSet 的核心结构,O(log N) 查找
hashtable 哈希表,渐进式 rehash
intset 整数集合,元素全为整数时使用

加分话术: “Redis 7.0 用 listpack 彻底替代了 ziplist,解决了 ziplist 的级联更新问题。listpack 不保存前一个节点的长度,所以修改一个节点不会导致连锁更新。”


Q3:String 类型的底层 SDS 和 C 字符串有什么区别?

答:

对比项 C 字符串 SDS
获取长度 O(n) 遍历 O(1) 维护 len 字段
二进制安全 ❌ 遇 \0 截断 ✅ 以 len 判断结束
缓冲区溢出 可能 不会(自动扩容)
内存分配 每次修改重新分配 空间预分配 + 惰性释放
减少重分配 扩容时多分配(<1MB 翻倍,≥1MB 加 1MB)

Q4:ZSet 为什么用跳表而不用红黑树?

答:

  1. 范围查询更高效:跳表底层是有序链表,找到起点后沿链表遍历即可;红黑树需要中序遍历
  2. 实现更简单:跳表代码量远小于红黑树,不易出 bug
  3. 插入删除更灵活:跳表只需修改指针,红黑树需要旋转和重着色
  4. 并发友好:跳表可以局部加锁,红黑树旋转影响范围大
  5. 内存友好:跳表可以通过调整层间距平衡空间和时间

加分话术: “跳表的查找时间复杂度也是 O(log N),和红黑树一样,但跳表的常数因子更小,缓存局部性更好。LevelDB 的 memtable 也用了跳表。”


Q5:Redis 的 hashtable 是怎么实现的?什么时候扩容?

答:

Redis 的 hashtable 采用渐进式 rehash

  1. 结构:包含两个哈希表 ht[0] 和 ht[1],正常时只用 ht[0]
  2. 触发扩容
    • 负载因子 > 1(没有 BGSAVE 时)
    • 负载因子 > 5(BGSAVE 时,避免 rehash 与子进程竞争)
  3. 渐进式 rehash
    • 为 ht[1] 分配空间(大小为第一个大于等于 ht[0].used×2 的 2^n)
    • 维护一个 rehashidx 索引,每次 CRUD 操作迁移 ht[0] 的一个桶到 ht[1]
    • 期间的新增操作直接写 ht[1],查找/删除先查 ht[0] 再查 ht[1]
    • 全部迁移完成后,释放 ht[0],ht[1] 变成 ht[0]

加分话术: “渐进式 rehash 避免了一次性 rehash 导致的服务卡顿,类似于 Java ConcurrentHashMap 的分段迁移思想。”


二、持久化篇

Q6:RDB 和 AOF 有什么区别?

答:

对比项 RDB AOF
原理 定时生成内存快照(二进制) 追加写命令日志(文本)
触发方式 save/bgsave/配置自动 每次写/每秒/手动
文件大小 (压缩二进制) 大(文本命令)
恢复速度 慢(重放命令)
数据安全 可能丢失最后一次快照后的数据 最多丢 1 秒(everysec)
fork 开销 有(bgsave 需要 fork 子进程) 无(bgrewriteaof 时有)
适合场景 冷备份、灾难恢复 数据安全性要求高

AOF 重写机制:

  • AOF 文件会不断增长,需要定期重写压缩
  • 重写时 fork 子进程,将当前内存数据转为命令写入新 AOF
  • 重写期间的新命令写入 AOF 重写缓冲区,重写完成后追加

加分话术: “Redis 4.0 引入了混合持久化(aof-use-rdb-preamble yes),AOF 重写时先写 RDB 格式再追加增量 AOF,兼顾了恢复速度和数据安全。”


Q7:RDB 的 bgsave 为什么不会阻塞主线程?

答:

  1. bgsave 调用时,Redis 主进程执行 fork() 创建子进程
  2. fork() 使用写时复制(Copy-On-Write, COW)
    • fork 时父子进程共享同一份内存数据
    • 只有当主进程修改某块内存页时,才会复制该页给子进程
  3. 子进程负责将数据写入 RDB 文件,主进程继续处理命令
  4. 因此 bgsave 期间主进程基本不受影响,只有 fork 瞬间和 COW 时有短暂开销

追问:COW 有什么风险?

  • 如果 fork 之后有大量写操作,会产生大量内存页复制,导致内存占用翻倍
  • 生产环境建议:maxmemory 不要设置超过物理内存的 70%

Q8:AOF 的三种同步策略是什么?

答:

策略 配置 行为 安全性 性能
always appendfsync always 每次写命令都同步磁盘 最高(不丢数据) 最差
everysec appendfsync everysec 每秒同步一次 最多丢 1 秒 推荐
no appendfsync no 由 OS 决定何时同步 可能丢较多数据 最好

生产环境推荐 everysec,兼顾安全性和性能。


三、缓存三大问题篇

Q9:缓存穿透是什么?怎么解决?

答:

定义: 查询一个根本不存在的数据,缓存永远不命中,每次都打到数据库。通常是恶意攻击。

解决方案:

方案 原理 优缺点
缓存空值 查不到也写入缓存(设短 TTL,如 30s) 简单,但浪费内存
布隆过滤器 在缓存前加一层布隆过滤器,拦截不存在的 key 内存极小(0.1% 误判率),但不支持删除
参数校验 接口层校验非法参数(如 id<0) 基本防护

布隆过滤器原理:

  • 一个 bit 数组 + 多个哈希函数
  • 插入元素:用 k 个哈希函数计算 k 个位置,全部置 1
  • 查询元素:k 个位置全为 1 → “可能存在”;有 0 → “一定不存在”
  • 不支持删除(因为可能影响其他元素)

加分话术: “Redis 可以用 RedisBloom 模块实现布隆过滤器,命令是 BF.ADD 和 BF.EXISTS。也可以用 Redisson 的 RBloomFilter。”

// Redisson 布隆过滤器示例
RBloomFilter<String> filter = redisson.getBloomFilter("userFilter");
filter.tryInit(1000000L, 0.01); // 预计100万元素,1%误判率
filter.add("user:1001");
if (!filter.contains("user:9999")) {
    // 一定不存在,直接返回
    return null;
}

Q10:缓存击穿是什么?怎么解决?

答:

定义: 某个热点 key 过期的瞬间,大量并发请求同时打到数据库。

解决方案:

方案 原理 优缺点
互斥锁 缓存 miss 时,用分布式锁保证只有一个线程查 DB 并回写缓存 强一致,但性能差
逻辑过期 key 不设物理 TTL,在 value 中存逻辑过期时间;发现过期时异步更新 高性能,但短暂数据不一致
热点 key 永不过期 不设 TTL,由后台定时刷新 简单,但需要额外维护

互斥锁实现:

public String get(String key) {
    String value = redis.get(key);
    if (value == null) {
        // 尝试获取分布式锁
        String lockKey = "lock:" + key;
        if (redis.setnx(lockKey, "1", 30, TimeUnit.SECONDS)) {
            try {
                value = redis.get(key); // 双重检查
                if (value == null) {
                    value = db.query(key);
                    redis.set(key, value, 60, TimeUnit.SECONDS);
                }
            } finally {
                redis.del(lockKey);
            }
        } else {
            // 未获取到锁,短暂等待后重试
            Thread.sleep(50);
            return get(key);
        }
    }
    return value;
}

Q11:缓存雪崩是什么?怎么解决?

答:

定义: 大量 key 同时过期Redis 宕机,导致请求全部打到数据库。

与穿透/击穿的区别:

问题 触发条件 影响范围
穿透 查询不存在的数据 单个 key
击穿 热点 key 过期 单个热点 key
雪崩 大量 key 同时过期 / Redis 宕机 大面积

解决方案:

方案 原理
随机过期时间 TTL 加随机值,避免集中过期(如 base + random(0, 300))
多级缓存 本地缓存(Caffeine) + Redis + DB,层层拦截
限流降级 对数据库加限流,超过阈值直接返回默认值
集群高可用 Redis Sentinel / Cluster,避免单点故障
熔断机制 数据库压力过大时触发熔断,返回兜底数据

Q12:缓存和数据库的双写一致性怎么保证?

答:

这是经典的分布式一致性问题,没有完美方案,只有权衡。

四种策略:

策略 操作顺序 一致性 性能
Cache Aside 先删缓存 → 更新 DB 最终一致
Read/Write Through 缓存层统一代理读写 强一致
Write Behind 只更新缓存,异步刷 DB 最终一致 最好
延迟双删 先删缓存 → 更新 DB → sleep → 再删缓存 最终一致

Cache Aside 模式(最常用):

读:先读缓存 → miss 则读 DB → 回写缓存
写:先删缓存 → 再更新 DB

延迟双删解决并发问题:

// 1. 先删缓存
redis.del(key);
// 2. 更新数据库
db.update(key, newValue);
// 3. 延迟一段时间(略大于一次读请求的耗时)
Thread.sleep(500);
// 4. 再删一次缓存(删掉并发读请求写入的旧值)
redis.del(key);

追问:延迟双删的延迟时间怎么确定?

  • 略大于一次读请求的总耗时(网络 + DB 查询 + 缓存写入)
  • 一般 300ms ~ 1s,可以通过监控读请求 P99 耗时来确定

加分话术: “如果对一致性要求很高,可以用 Canal 监听 MySQL binlog,通过 MQ 异步更新 Redis,实现最终一致性。这是目前生产环境最主流的方案。”


四、分布式锁篇

Q13:Redis 分布式锁怎么实现?

答:

最基础的实现:SETNX + EXPIRE

# 原子操作:设置 key + 过期时间
SET lock_key unique_value NX PX 30000
# NX: 不存在才设置
# PX: 过期时间(毫秒)

释放锁(Lua 脚本保证原子性):

if redis.call("get", KEYS[1]) == ARGV[1] then
    return redis.call("del", KEYS[1])
else
    return 0
end

为什么不直接用 DEL? 因为要校验 value 是否是自己设置的,防止误删别人的锁。

追问:SETNX 和 EXPIRE 不是两条命令吗?会不会不原子?

  • Redis 2.6.12 之后,SET 命令支持 NX + PX 参数,一条命令搞定,天然原子。

Q14:Redisson 是怎么实现分布式锁的?

答:

Redisson 对 Redis 分布式锁做了大量增强:

特性 实现方式
可重入 Hash 结构记录锁的持有者和重入次数
自动续期(Watch Dog) 后台线程每 10 秒检查锁是否还持有,自动续期 30 秒
阻塞等待 通过 Redis 的 Pub/Sub 订阅锁释放事件,避免忙轮询
主从一致性 RedLock 算法(向 N 个独立 Redis 实例加锁,多数成功才算成功)
RLock lock = redisson.getLock("myLock");
try {
    // 尝试加锁,最多等待 10 秒,自动续期
    if (lock.tryLock(10, -1, TimeUnit.SECONDS)) {
        // 业务逻辑
    }
} finally {
    if (lock.isHeldByCurrentThread()) {
        lock.unlock();
    }
}

Watch Dog 机制详解:

  • tryLock() 传 -1 时,不指定 leaseTime,启用 Watch Dog
  • 默认 lockWatchdogTimeout = 30 秒
  • 每 10 秒(lockWatchdogTimeout / 3)续期一次
  • 如果持有锁的客户端宕机,Watch Dog 停止,30 秒后锁自动释放

Q15:RedLock 算法是什么?有什么争议?

答:

RedLock 步骤:

  1. 获取当前时间 T1
  2. 依次向 N 个(通常 5 个)独立的 Redis 实例加锁,设置较短超时
  3. 获取当前时间 T2,如果在 N/2+1 个以上实例加锁成功,且总耗时 < 锁的 TTL → 加锁成功
  4. 锁的有效时间 = TTL - (T2 - T1)
  5. 如果加锁失败,向所有实例释放锁

争议:

  • Martin Kleppmann(《Designing Data-Intensive Applications》作者)指出 RedLock 有安全问题
    • 依赖时钟同步,如果某节点时钟跳跃,可能导致锁提前过期
    • GC 停顿可能导致客户端认为自己持有锁,但实际上已过期
  • Antirez(Redis 作者)回应:可以通过 fencing token 解决

加分话术: “如果对一致性要求不是特别高,单 Redis 实例 + Redisson 的 Watch Dog 就够了。如果要求极高,应该用 ZooKeeper 或 etcd 的临时节点方案。”


五、高可用篇

Q16:Redis 主从复制是怎么工作的?

答:

全量同步(首次连接):
1. 从节点发送 PSYNC ? -1
2. 主节点执行 BGSAVE 生成 RDB,发送给从节点
3. 从节点加载 RDB
4. 主节点将期间的写命令发送给从节点

增量同步(断线重连):
1. 从节点发送 PSYNC replid offset
2. 主节点检查 replid 是否一致,offset 是否在 repl_backlog 内
3. 如果在,发送 offset 之后的增量数据
4. 如果不在,退化为全量同步

关键配置:

# 主节点:至少 N 个从节点在线才接受写入
min-replicas-to-write 1
min-replicas-max-lag 10

Q17:哨兵模式(Sentinel)是怎么工作的?

答:

Sentinel 负责监控、通知、自动故障转移:

  1. 监控:每秒向主从节点发送 PING,检测是否存活
  2. 通知:主节点下线时,通过 Pub/Sub 通知客户端
  3. 自动故障转移
    • 多个 Sentinel 投票确认主节点下线(客观下线)
    • Sentinel 选举 leader(Raft 算法)
    • Leader 从从节点中选一个升级为主节点(优先级 > offset > runid)
    • 通知其他从节点切换主节点

主观下线 vs 客观下线:

  • 主观下线(SDOWN):单个 Sentinel 认为主节点不可达
  • 客观下线(ODOWN):quorum 个 Sentinel 都认为主节点不可达

Q18:Redis Cluster 分片集群是怎么工作的?

答:

核心原理:

  • 16384 个哈希槽(slot),分布在多个节点上
  • key 通过 CRC16(key) % 16384 计算属于哪个槽
  • 每个节点负责一部分槽
节点 A: 0 ~ 5460
节点 B: 5461 ~ 10922
节点 C: 10923 ~ 16383

客户端请求流程:

  1. 客户端发送命令到任意节点
  2. 节点计算 key 的槽号
  3. 如果在自己负责的槽 → 执行
  4. 如果不在 → 返回 MOVED 重定向到正确节点

ASK 重定向(槽迁移期间):

  • 槽从节点 A 迁移到节点 B 时,A 返回 ASK,客户端需先发 ASKING 到 B 再执行命令

为什么是 16384 个槽?

  • 作者 antirez 的解释:心跳包中需要携带槽信息,16384 个槽只需 2KB(bitmap),163840 个槽需要 20KB,开销太大
  • 对于集群规模不超过 1000 节点的场景,16384 个槽足够

六、内存管理篇

Q19:Redis 的过期删除策略是什么?

答:

Redis 采用惰性删除 + 定期删除的组合策略:

策略 原理 优缺点
惰性删除 访问 key 时才检查是否过期 对 CPU 友好,但可能浪费内存
定期删除 每秒执行 10 次(默认),每次随机抽取 20 个 key 检查 折中方案

定期删除的流程:

每秒执行 10 次:
1. 随机抽取 20 个设置了过期时间的 key
2. 删除其中已过期的 key
3. 如果过期比例 > 25%,重复步骤 1
4. 每次执行时间不超过 25ms(避免阻塞主线程)

追问:如果大量 key 过期但没被访问,会不会撑爆内存?
会。这就是为什么还需要内存淘汰策略


Q20:Redis 的内存淘汰策略有哪些?

答:

Redis 4.0+ 有 8 种淘汰策略(maxmemory-policy):

策略 范围 淘汰依据
noeviction 不淘汰,写入报错(默认)
allkeys-random 所有 key 随机淘汰
allkeys-lru 所有 key LRU(最近最少使用)
allkeys-lfu 所有 key LFU(最不经常使用)
volatile-random 设了 TTL 的 key 随机淘汰
volatile-lru 设了 TTL 的 key LRU
volatile-lfu 设了 TTL 的 key LFU
volatile-ttl 设了 TTL 的 key TTL 越小越先淘汰

推荐: 缓存场景用 allkeys-lfu(Redis 4.0+),它比 LRU 更准确——LRU 可能淘汰掉频繁访问但最近没访问的 key,LFU 综合考虑了访问频率和时间。

Redis 的 LRU 是近似 LRU:

  • 不是维护一个全局 LRU 链表(太耗内存)
  • 而是随机采样 5 个 key(maxmemory-samples),淘汰其中最久未访问的
  • 采样数越大越精确,但越慢

七、实战场景篇

Q21:如何用 Redis 实现延迟队列?

答:

方案一:ZSet 实现

# 添加延迟消息,score 为执行时间戳
ZADD delay_queue 1687000000 "task:1"

# 消费者轮询(每秒一次)
ZRANGEBYSCORE delay_queue 0 <当前时间戳> LIMIT 0 10
# 取出后删除
ZREM delay_queue "task:1"

方案二:Redis Stream(Redis 5.0+)

# 生产者
XADD tasks * name "send_email" delay 60000

# 消费者组
XGROUP CREATE tasks mygroup $
XREADGROUP GROUP mygroup consumer1 COUNT 10 BLOCK 2000 STREAMS tasks >

加分话术: “如果对延迟精度要求高,建议用 RocketMQ 的延迟队列或 Kafka + 时间轮方案。Redis 方案适合对精度要求不高的场景。”


Q22:如何用 Redis 统计网站 UV(独立访客)?

答:

方案 适用场景 内存 精度
Set 精确统计 大(每个用户一个元素) 精确
Bitmap 用户 ID 连续 极小 精确
HyperLogLog 大规模统计 极小(固定 12KB) 0.81% 误差
# HyperLogLog(推荐)
PFADD uv:20260618 "user:1001" "user:1002" "user:1001"  # 自动去重
PFCOUNT uv:20260618  # 返回 2

# Bitmap(用户 ID 为整数时)
SETBIT uv:20260618 1001 1  # 用户 1001 访问
SETBIT uv:20260618 1002 1  # 用户 1002 访问
BITCOUNT uv:20260618  # 返回 2

# 多天合并
BITOP OR uv:week uv:20260616 uv:20260617 uv:20260618

Q23:Redis 的大 key 怎么处理?

答:

什么是大 key?

  • String 类型 value > 10KB
  • Hash/List/Set/ZSet 元素数量 > 5000 个

大 key 的危害:

  • 读写耗时长,阻塞其他请求
  • 内存不均衡(Cluster 模式下某个节点压力大)
  • DEL 删除时阻塞主线程
  • 网络带宽占用大

发现大 key:

redis-cli --bigkeys                    # 扫描大 key
redis-cli --memkeys                    # 按内存排序
MEMORY USAGE <key>                     # 查看单个 key 的内存
DEBUG OBJECT <key>                     # 查看 key 的详细信息

删除大 key(避免阻塞):

# Redis 4.0+:异步删除
UNLINK <key>                           # 非阻塞删除

# Hash:分批删除
HSCAN myhash 0 COUNT 100
HDEL myhash field1 field2 ...

# List:分批删除
LTRIM mylist 0 -101                    # 每次保留前 100 个之外的

# ZSet:分批删除
ZREMRANGEBYRANK myzset 0 99            # 每次删除 100 个

Q24:Redis 的 Pipeline 是什么?为什么能提升性能?

答:

普通模式:

客户端 → 发送命令1 → 等待响应1 → 发送命令2 → 等待响应2 → ...
每次 RTT(Round Trip Time)都是一次网络往返

Pipeline 模式:

客户端 → 批量发送命令1,2,3,...,N → 批量接收响应1,2,3,...,N
只需一次 RTT
// Jedis Pipeline 示例
Pipeline pipeline = jedis.pipelined();
for (int i = 0; i < 1000; i++) {
    pipeline.set("key:" + i, "value:" + i);
}
pipeline.sync();  // 一次性发送

性能对比:

  • 普通模式 10000 次 SET:约 5 秒(每次 0.5ms RTT)
  • Pipeline 10000 次 SET:约 0.1 秒(一次 RTT)

注意: Pipeline 不是原子操作,中间可能插入其他客户端的命令。如果需要原子性,用 Lua 脚本或事务。


Q25:Redis 事务和 Lua 脚本有什么区别?

答:

对比项 MULTI/EXEC 事务 Lua 脚本
原子性 命令排队一起执行,但不支持回滚 真正原子,要么全执行要么全不执行
事务隔离 EXEC 前其他客户端命令可插入 单线程执行,天然隔离
编程能力 只能执行已有命令 支持条件判断、循环等逻辑
性能 一般 更好(减少网络往返)
错误处理 语法错误才中断,运行时错误不回滚 脚本错误全部中断
# Redis 事务
MULTI
SET a 1
SET b 2
EXEC

# Lua 脚本(原子操作)
EVAL "redis.call('SET', KEYS[1], ARGV[1]); redis.call('SET', KEYS[2], ARGV[2])" 2 a b 1 2

加分话术: “Redis 事务的 MULTI/EXEC 不支持回滚,这是设计决策——Redis 认为事务失败应该由应用层处理,而不是数据库回滚。而且运行时错误(如对 String 执行 LPUSH)不应该影响其他正确命令的执行。”


八、高频追问链路

面试官追问路线图

Q: Redis 为什么快?
  → Q: 单线程为什么不用多线程?
    → Q: Redis 6.0 的多线程是什么?
      → Q: I/O 多路复用的原理?

Q: 缓存穿透怎么解决?
  → Q: 布隆过滤器原理?
    → Q: 布隆过滤器误判率怎么控制?
      → Q: 布隆过滤器支持删除吗?用什么替代?

Q: 缓存击穿怎么解决?
  → Q: 分布式锁怎么实现?
    → Q: Redisson 的 Watch Dog 机制?
      → Q: RedLock 算法有争议你怎么看?

Q: Redis 持久化?
  → Q: RDB 的 COW 有什么风险?
    → Q: AOF 重写的原理?
      → Q: 混合持久化怎么配置?

Q: Redis Cluster 怎么分片?
  → Q: 为什么是 16384 个槽?
    → Q: MOVED 和 ASK 重定向的区别?
      → Q: 槽迁移过程中数据会丢吗?

📋 Redis 面试速查表

考点 一句话回答
为什么快 内存 + 单线程 + I/O 多路复用 + 高效数据结构
数据类型 String/List/Hash/Set/ZSet + Stream/Bitmap/HyperLogLog
ZSet 底层 跳表(范围查询快、实现简单、并发友好)
RDB vs AOF RDB 快照恢复快,AOF 日志丢数据少
缓存穿透 查询不存在的数据 → 布隆过滤器 / 缓存空值
缓存击穿 热点 key 过期 → 互斥锁 / 逻辑过期
缓存雪崩 大量 key 同时过期 → 随机 TTL / 多级缓存 / 限流
双写一致性 Cache Aside + 延迟双删 / Canal + MQ
分布式锁 SET NX PX + Lua 释放 / Redisson + Watch Dog
过期策略 惰性删除 + 定期删除
内存淘汰 allkeys-lfu(推荐)
主从复制 全量同步(RDB) + 增量同步(repl_backlog)
哨兵 监控 + 自动故障转移(Raft 选 leader)
Cluster 16384 槽 + CRC16 哈希 + MOVED/ASK 重定向
大 key UNLINK 异步删除 + HSCAN/LTRIM 分批删除
Pipeline 批量发送命令,减少 RTT
事务 vs Lua Lua 更强(真正原子 + 可编程)
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐