Skip to main content
Documents
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

Redis 基础

1. Redis 基础概念

1.1 Redis 是什么?

  • 开源、基于内存、支持持久化的高性能 Key-Value 数据库
  • 单线程处理命令(6.x 之后引入 I/O 多线程,但核心命令执行仍是单线程)
  • 典型 QPS:10w~50w+

1.2 Redis 适用场景

  • 缓存(热点数据)
  • 排行榜(zset)
  • 分布式锁(set nx ex)
  • 限流(incr + expire / Lua)
  • 会话管理(token/session)
  • 消息队列(Stream/List)
  • 计数器(incr)
  • 地理位置(GEO)

2. Redis 五大核心数据结构(附最佳实践)

2.1 String

适用于:计数器、缓存、分布式锁

常用命令:GET/SET/INCR/INCRBY/SETEX/MSET

最佳实践:

  • 计数用 INCR,不用 GET+SET(避免并发问题)
  • 使用 SET key value NX EX 10 实现分布式锁(RedLock 不推荐)

2.2 Hash

适用于:对象存储(例如用户信息)

最佳实践:

  • 字段不要太多(>5000 会影响性能)
  • 避免大 Key
  • 可使用 HINCRBY 保存数值属性

2.3 List

适用于:消息队列、时间顺序数据

常用命令:LPUSH / RPOP / BLPOP

最佳实践:

  • 不要做大列表,超过 50 万就危险
  • 如果要做队列推荐使用 Stream

2.4 Set

适用于:去重、标签、共同好友等运算

最佳实践:

  • 大集合运算(如 SINTER)非常耗时,会造成阻塞
  • 尽量用 SCARD 判断大小,避免 SMEMBERS 拉全量

2.5 Sorted Set(ZSet)

适用于:排行榜、延迟队列

最佳实践:

  • ZREMRANGEBYSCORE 用于清理过期任务
  • 延迟队列:ZADD + ZRANGEBYSCORE + Lua

3. Redis 高级数据结构

3.1 HyperLogLog

适用于:独立访客 UV、去重计数

误差:0.81% 左右

内存消耗固定:12KB

3.2 Bitmap

适用于:签到、活跃用户统计、是否在线等

节省内存,但不适合存储大量稀疏数据

3.3 Stream(消息队列)

特性:

  • 有消费者组
  • 持久化消息队列
  • 支持 ACK

比 List 更适合消息系统。

4. Redis 持久化:RDB / AOF

4.1 RDB(快照)

优点:恢复快、占用空间小

缺点:可能丢失最近一次快照后的数据

最佳实践:

  • 使用 save "" 禁用相对持久化规则
  • 使用 save 900 1 300 10 60 10000

4.2 AOF

优点:几乎不丢数据

缺点:文件越来越大

推荐模式:appendfsync everysec

AOF 重写(rewrite)最佳实践:

  • 启用 auto-aof-rewrite-percentage 100
  • 启用 auto-aof-rewrite-min-size 64mb

5. Redis 内存管理

5.1 内存淘汰策略(重点)

maxmemory-policy 推荐使用:

  • volatile-lru(只淘汰有 ttl 的 key)
  • allkeys-lru(作为缓存使用时)

不要使用:

  • noeviction(容易导致直接报错)

5.2 大 Key 问题(重点)

危险的大 Key 场景:

  • 一个 Hash 中几十万字段
  • 巨大 List、Set、ZSet

危害:

  • 删除大 Key 时可能阻塞 Redis
  • 网络传输放大

解决方案:

  • 用 SCAN 避免 KEYS
  • 分拆大 key(Hash 分片)
  • UNLINK 异步删除

6. Redis 高可用方案

6.1 单机:不推荐

6.2 主从(Master-Slave):可以读写分离

6.3 Sentinel:主从自动切换,生产可用

6.4 Redis Cluster:分片+高可用,企业级使用

生产常用架构:

  • Redis Cluster(3主3从)
  • Sentinel(主从)

7. Redis 运维最佳实践(最重要部分)

7.1 CPU 100% / 连接数飙高

原因:

  • 使用 KEYS、HGETALL、SMEMBERS 等全量命令
  • Lua 脚本耗时太久
  • 大 key

解决:

  • KEYS 改 SCAN
  • 大 key 分片
  • 使用 slowlog get 分析慢查询
  • 使用 redis-cli –bigkeys 检查大 key

7.2 内存暴涨

原因:

  • Key value 太大
  • 没设置过期
  • 没启动淘汰策略

解决:

  • 给缓存数据都加 TTL
  • 设置 maxmemory 和 maxmemory-policy

7.3 主从延迟

原因:

  • 复制阻塞
  • 网络带宽不足
  • Master 写入太多

解决:

  • 使用 cluster 分片减轻压力
  • 限流写流量
  • 开启 repl-backlog-size

8. Redis 分布式锁(推荐方式)

推荐使用 SET key value NX PX 30000

注意:

  • value 必须是唯一值,用来比对锁是不是自己的
  • 释放锁时必须使用 Lua 脚本保证原子性

示例 Lua 脚本:

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

9. Redis 限流方案

固定窗口(incr + expire)

经典:

INCR key
EXPIRE key 60

滑动窗口(ZSet + 时间戳)

更精准

漏桶/令牌桶(Lua 脚本)

高性能且精准

10. Redis 关键命令禁用列表(生产建议禁用)

在 redis.conf 设置:

rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command KEYS ""
rename-command SHUTDOWN ""