Redis 性能调优

面试官问:"Redis 性能怎么调优?"

小张说:"加内存,用集群。"

面试官追问:"那命令层面呢?有没有需要注意的?"

小张说:"...用短 key?"

面试官继续追问:"哪些命令要慎用?为什么?"

小陈答不上来。

Redis 性能调优是生产环境中的高频问题。这道题能说清楚多个层面调优策略的候选人,对 Redis 生产运维有系统经验。

一、网络层优化 🔴

1.1 连接配置

# redis.conf 网络配置
bind 127.0.0.1
port 6379

# TCP 连接优化
tcp-backlog 511         # 连接队列长度
tcp-keepalive 300        # TCP 保活(秒)
timeout 0                 # 客户端空闲超时(0=不超时)

# client-output-buffer-limit
client-output-buffer-limit replica 256mb 64mb 60
# replica:主从复制缓冲区限制

1.2Pipeline 优化

# ❌ 低效:逐条命令
for key in keys:
    redis.get(key)

# ✅ 高效:Pipeline
pipe = redis.pipeline()
for key in keys:
    pipe.get(key)
results = pipe.execute()
# 一次网络往返,执行所有命令

二、命令层优化 🔴

2.1 避免 O(n) 命令

-- 危险的 O(n) 命令:
KEYS pattern          -- O(n),全表扫描,阻塞 Redis
SMEMBERS set          -- O(n),返回所有成员
LRANGE list 0 -1      -- O(n),返回所有元素
FLUSHALL              -- O(n),清空所有数据

-- 替代方案:
KEYS → SCAN(增量遍历)
SMEMBERS → SSCAN(增量遍历)
LRANGE → 分批读取

2.2 SCAN 替代 KEYS

# KEYS(阻塞):
KEYS user:*   # 阻塞 Redis

# SCAN(增量,非阻塞):
SCAN 0 MATCH user:* COUNT 100
# 返回一个游标和一个 key 列表
# 继续调用 SCAN,直到游标为 0

# Python:
for key in redis.scan_iter(match='user:*', count=100):
    # 处理 key
    pass

2.3 ❌ 错误示范

候选人原话:"SCAN 和 KEYS 差不多,都是查 key。"

问题诊断:完全不同。KEYS 阻塞 Redis 并一次性返回所有结果;SCAN 分批返回,增量遍历,不阻塞。

【面试官心理】 这道题我会问"哪些命令要避免在生产环境使用"。能说出 KEYS、FLUSHALL、SMEMBERS 的人,是踩过坑的候选人。

三、数据结构优化 🟡

3.1 选择合适的数据结构

-- 场景 1:需要唯一性、查找
# ✅ SET vs String + 去重
SADD tags:article:1 "java" "redis"
SMEMBERS tags:article:1  # 集合操作

-- 场景 2:需要排序
# ✅ ZSET vs String + 排序
ZADD leaderboard 1000 "user:1" 500 "user:2"
ZREVRANGE leaderboard 0 9  # 前 10

-- 场景 3:需要计数
# ✅ String INCR vs 定期统计
INCR page:view:2024-01-01

3.2 字符串压缩

# 大字符串使用压缩
import zlib
import base64

value = "很长的文本..." * 1000
compressed = base64.b64encode(zlib.compress(value.encode()))

# 存压缩数据
redis.set('doc:1', compressed)

# 取数据时解压
compressed = redis.get('doc:1')
value = zlib.decompress(base64.b64decode(compressed))

四、持久化优化 🟡

4.1 持久化配置

# redis.conf 持久化配置

# RDB(定时快照)
save 900 1      # 900 秒内有 1 个 key 变化
save 300 10
save 60 10000

# AOF(追加日志)
appendonly yes
appendfsync everysec  # 推荐,性能和安全平衡

# AOF 重写优化
aof-rewrite-incremental-fsync yes
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

4.2 关闭持久化

# 如果 Redis 纯做缓存,不需要持久化:
# 关闭 RDB 和 AOF
save ""
appendonly no

# 优点:
# - 写入性能提升 20%~30%
# - 减少磁盘 IO

五、监控与诊断 🟡

5.1 关键监控指标

-- INFO commandstats
# 命令执行统计
cmdstat_get:calls=1000000,usec=500000,usec_call=0.5

-- 慢查询日志
slowlog-log-slower-than 10000  # 10ms
slowlog-max-len 128

SLOWLOG GET 10  -- 查看最近 10 条慢查询

5.2 Redis Benchmark

# 测试 Redis 性能
redis-benchmark -h localhost -p 6379 -c 100 -n 100000

# 测试特定命令
redis-benchmark -h localhost -p 6379 -c 50 -n 10000 -t GET,SET,INCR

# 指定 Value 大小
redis-benchmark -h localhost -p 6379 -d 10240  # 10KB Value

六、生产调优 Checklist 🟢

# ✅ 网络层
tcp-backlog 511
tcp-keepalive 300

# ✅ 内存层
maxmemory 8gb
maxmemory-policy allkeys-lru
lazyfree-lazy-eviction yes

# ✅ 持久化层
appendonly yes
appendfsync everysec

# ✅ 命令层
slowlog-log-slower-than 10000
slowlog-max-len 1000

# ✅ 客户端
client-output-buffer-limit replica 256mb 64mb 60

【面试官心理】 Redis 性能调优是生产环境中的综合问题。能从网络、命令、持久化、内存多个层面说清楚调优策略的候选人,说明他对 Redis 生产运维有系统经验。


级别考察重点期望回答
P5基本优化Pipeline、使用短 key
P6命令优化避免 O(n) 命令、SCAN 替代 KEYS
P7系统调优持久化、内存、监控配置