生产环境性能压测:从单机到集群的完整方案
为什么要在生产环境做压测
在开发环境测试 Redis 可能”一切正常”,但生产环境的压力往往是开发环境的 10-100 倍。生产环境压测的目的是:
- 确定当前配置下的极限 QPS
- 发现在高负载下的瓶颈
- 验证扩容效果
- 为容量规划提供依据
压测前的准备
1. 确认不能做的事
# ❌ 绝不能在业务高峰期压测
# ❌ 不能用 KEYS * 等危险命令
# ❌ 不能使用生产数据做破坏性测试
# ❌ 不能忽略带宽和 CPU 监控
2. 压测环境搭建
# 单独准备压测客户端机器(不要和 Redis 在同一台)
# 确保压测客户端性能足够(不会成为瓶颈)
# 千兆网络下,压测客户端需要足够资源
# 检查压测客户端
sysctl -a | grep "net.core.wmem\|net.core.rmem"
# 如果值太小,先优化客户端
3. 监控准备
# 在 Redis 机器上开 3 个终端
# 终端 1:实时 QPS 和延迟
watch -n 1 "redis-cli INFO STATS | grep -E 'instantaneous|rejected'"
# 终端 2:系统资源
htop
# 终端 3:网络
nload
单机压测方案
1. 基础吞吐量测试
# 测试纯 GET/SET 的极限 QPS
redis-benchmark \
-h 127.0.0.1 -p 6379 \
-c 100 \ # 100 并发
-n 1000000 \ # 100 万请求
-r 1000000 \ # 100 万随机 key
-d 50 \ # 50 字节数据
-t SET,GET \ # 只测 SET 和 GET
--csv > benchmark_base.csv
2. 并发数测试
# 不同并发下的表现
for concurrency in 10 50 100 200 500; do
redis-benchmark \
-c $concurrency \
-n 100000 \
-t SET \
-d 100 \
-r 100000 \
-q | grep "SET"
done
预期结果(4 核服务器, 8GB):
并发 10: 22000 QPS (单线程瓶颈,并发帮助有限)
并发 50: 25000 QPS (并发增加,QPS 略有提高)
并发 100: 26000 QPS (接近上限)
并发 200: 26000 QPS (达到上限)
并发 500: 25000 QPS (资源竞争,可能略有下降)
3. 数据大小测试
# 不同 value 大小的影响
for size in 10 100 1000 10000 100000; do
redis-benchmark \
-d $size \
-n 50000 \
-t SET \
-c 100 \
-q | grep "SET"
done
4. Pipeline 优化测试
# Pipeline 对吞吐量的提升
for pipeline in 1 5 10 20 50; do
redis-benchmark \
-P $pipeline \
-n 1000000 \
-t SET \
-c 100 \
-q | grep "SET"
done
5. 混合读写场景
# 模拟实际业务:80% 读,20% 写
redis-benchmark \
-t GET,SET \
--ratio 80:20 \
-n 500000 \
-c 100 \
-q
# 写入密集型:50% 写
redis-benchmark \
-t SET,GET,INCR,LPUSH \
-n 500000 \
-c 100 \
-q
集群压测方案
1. 使用 redis-cli 的集群模式
# 测试 Redis Cluster
redis-benchmark \
--cluster \
-h 192.168.1.100 -p 6379 \
-c 200 \
-n 1000000 \
-r 1000000 \
-d 100 \
-t SET \
-q
2. 多节点压力分布
import redis
from redis.cluster import RedisCluster
import time, threading
def pressure_test(cluster, node, count=10000):
"""对某个节点进行压力测试"""
start = time.time()
for i in range(count):
cluster.set(f"test:{node}:{i}", f"value:{i}")
elapsed = time.time() - start
print(f"Node {node}: {count/elapsed:.0f} QPS")
# 集群压力测试
rc = RedisCluster(host='192.168.1.100', port=6379)
nodes = list(rc.get_nodes())
threads = []
for i, node in enumerate(nodes):
t = threading.Thread(target=pressure_test, args=(rc, i, 10000))
threads.append(t)
t.start()
监控与分析
实时 QPS 监控
# 压测期间监控
watch -n 2 "redis-cli INFO STATS | grep -E 'instantaneous_ops|total_commands'"
延迟百分位
# 压测后的延迟分析
redis-cli --latency-dist -h 127.0.0.1 -p 6379
# 用彩色直方图展示延迟分布
命令耗时统计
redis-cli INFO COMMANDSTATS
# 压测后检查各命令平均耗时
压测报告模板
def generate_report(results):
"""生成压测报告"""
report = f"""
# Redis 性能压测报告
## 测试环境
- Redis 版本: {results['version']}
- 服务器: {results['server_spec']}
- 压测客户端: {results['client_spec']}
- 网络: {results['network']}
## 测试结果
### 纯读 (GET)
| 并发数 | 数据大小 | Pipeline | QPS |
|--------|---------|----------|-----|
"""
for row in results['get_results']:
report += f"| {row['concurrency']} | {row['size']}B | {row['pipeline']} | {row['qps']} |\n"
report += """
### 纯写 (SET)
"""
for row in results['set_results']:
report += f"| {row['concurrency']} | {row['size']}B | {row['pipeline']} | {row['qps']} |\n"
report += f"""
### 混合读写 (80:20)
QPS: {results['mixed_qps']}
### 延迟
P50: {results['p50']}ms
P99: {results['p99']}ms
## 结论
{results['conclusion']}
"""
return report
生产压测注意事项
安全红线和注意事项
# 1. 在业务低峰期进行(建议凌晨 2-6 点)
# 2. 逐步加压,每次观察 5-10 分钟
# 3. 设置合理的告警阈值
# - CPU > 80% 预警
# - 内存使用 > 80% 预警
# - QPS 异常波动预警
# 4. 准备好回退方案
# 5. 准备单独的压测 key 空间(不要影响生产数据)
常见问题
Q: 压测时 Redis 突然变慢怎么办?
# 1. 立即暂停压测
# 2. 检查 slowlog
redis-cli SLOWLOG GET 20
# 3. 检查大 key
redis-cli --bigkeys
# 4. 检查连接数
redis-cli INFO CLIENTS
Q: 压测结果和预期差距大怎么办?
– 检查网络延迟(redis-cli --latency)
– 检查是否绑定 CPU(taskset)
– 检查内存是否够用
– 检查是否有其他进程争抢资源
面试要点
- 生产压测必须在业务低峰期进行
- 监控是压测的一部分,不监控 = 没压测
- 压测要模拟真实业务场景(混合读写)
- 单机器压测需要考虑网络带宽限制
- 渐进式加压,不要一步到位给最大压力
- 准备好应急预案,随时可以终止压测
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END


暂无评论内容