Skip to content

性能优化

1. Pipeline

原理

批量执行命令,减少网络往返。

使用

python
# Redis-py
pipe = redis.pipeline()
pipe.get("key1")
pipe.get("key2")
pipe.get("key3")
result = pipe.execute()

对比

方式N次操作耗时
普通N * RTT
Pipeline1 * RTT

优点

优点说明
减少RTTN条命令只需要1次网络往返
提高吞吐量批量执行,QPS大幅提升
简单易用只需封装执行,不需要改服务

缺点

缺点说明
不保证原子性与MULTI/EXEC不同,命令逐条执行
内存占用服务端需要缓存所有响应
错误处理复杂单条命令失败不影响其他
无回滚中间失败无法撤销

注意事项

1. 命令数量控制

python
# ❌ 太多命令在一次pipeline中
pipe = redis.pipeline()
for key in keys:  # 10万条
    pipe.get(key)
results = pipe.execute()  # 内存爆炸!

# ✅ 分批执行
batch_size = 5000
for i in range(0, len(keys), batch_size):
    pipe = redis.pipeline()
    for key in keys[i:i+batch_size]:
        pipe.get(key)
    pipe.execute()

2. 大key问题

python
# ❌ pipeline中包含大key
pipe.get("big_key_100mb")  # 响应很大

# ✅ 先拆分检查
if redis.memory_usage(key) > 10000:  # 太大就分开
    # 单独处理

3. 错误处理

python
# ✅ 正确处理错误
pipe = redis.pipeline()
pipe.set("k1", "v1")
pipe.get("k1")
pipe.incr("k2")  # k2不是数字,会失败

results = pipe.execute()
for i, result in enumerate(results):
    if isinstance(result, Exception):
        print(f"命令{i}失败: {result}")

4. 事务命令不能用Pipeline

python
# ❌ 这样没有原子性
pipe = redis.pipeline()
pipe.multi()
pipe.incr("key")
pipe.exec()  # 返回的是结果列表,不是事务

# ✅ 用execute的transaction参数
pipe = redis.pipeline(transaction=True)
pipe.multi()
pipe.incr("key")
pipe.execute()  # 真正的事务

适用场景

场景推荐不推荐
批量读取✅ GET批量-
批量写入✅ MSET-
计数器✅ INCR批量-
事务❌ 用MULTI事务性操作
大key包含大value

2. Lua脚本

原子执行

lua
-- 一次网络往返执行多条命令
local m = redis.call('get', KEYS[1])
if m then
    redis.call('incr', KEYS[1])
end
return m

优点

  • 减少网络往返
  • 原子执行
  • 可复用

3. 集群分片

客户端分片

python
# CRC16取模分配
slot = CRC16(key) % 16384

代理分片

客户端 -> Proxy(Redis Cluster/Sentinel) -> Redis

4. 其他优化

1. 连接池

python
pool = redis.ConnectionPool(host='localhost', port=6379, max_connections=10)
r = redis.Redis(connection_pool=pool)

2. 压缩keys

# 不用
user:1000000001:profile:name
# 用
u:1:p:n

3. 选择数据结构

  • String vs Hash:字段多时用Hash
  • Set vs List:需要去重用Set

面试考点

Q: Pipeline vs Lua?

  • Pipeline:简单批量
  • Lua:复杂逻辑+原子

Q: 集群分片方式?

  • 客户端分片:Codis
  • 代理分片:Twemproxy
  • 服务端分片:Redis Cluster

最后更新: