Redis 性能优化有哪些策略?
Redis 性能优化是面试中的高频考点,也是生产环境中必须掌握的实战技能。本文从内存、网络、CPU、持久化、集群、监控、OS、客户端、架构九大维度系统梳理优化策略,并结合面试常见追问给出关键知识点。
内存优化
选择合适的数据结构是内存优化的第一步:
- 用 Hash 存储对象字段,比多个 String 节省内存(底层 ziplist/listpack 编码)
- 用 ZSet 做排行榜,避免 List 排序开销
- 用 Bitmap 存布尔型标记位,空间仅为 Set 的 1/64
- 用 HyperLogLog 做基数统计,固定 12KB 即可统计亿级去重
控制键名长度:键名占用内存不可忽视,但不宜过度缩写。user:1001:profile 比 u:1001:pf 更可维护,而 user:profile:1001:detail:info 则过长。
调整紧凑编码阈值:Hash、List 在元素少时自动使用 ziplist(Redis 7.0+ 为 listpack),通过 hash-max-ziplist-entries、hash-max-ziplist-value 调整触发阈值,在内存和性能间取平衡。
设置过期时间:为临时数据设置 TTL,避免无用数据长期占内存。用 EXPIRE/EXPIREAT 管理,配合惰性删除 + 定期删除策略回收内存。
淘汰策略选择:Redis 提供八种淘汰策略(Redis 4.0+),面试常考:
allkeys-lru:通用场景首选,淘汰最久未用的 keyvolatile-lru:只淘汰设了过期时间的 key,适合缓存+持久共存allkeys-lfu(Redis 4.0+):淘汰访问频率最低的 key,热点数据友好noeviction:默认策略,内存满拒绝写入,数据不能丢的场景使用
延迟删除(Lazy Free):Redis 4.0+ 引入异步删除,避免大 key 删除阻塞主线程:
shelllazyfree-lazy-eviction yes lazyfree-lazy-expire yes lazyfree-lazy-server-del yes replica-lazy-free yes
用 UNLINK 替代 DEL 删除大 key,后台线程异步回收内存。
内存碎片治理:监控 INFO memory 中 mem_fragmentation_ratio,超过 1.5 说明碎片严重。开启主动碎片整理:
shellactivedefrag yes
网络优化
Pipeline 批量执行:将多个命令打包一次发送,减少网络 RTT。适合批量写入、批量查询场景:
bash# Pipeline 批量设置 echo -e "SET key1 value1\nSET key2 value2\nSET key3 value3" | redis-cli --pipe
注意 Pipeline 不是原子操作,中间命令失败不影响其他命令执行。
连接池管理:客户端使用连接池复用连接,避免频繁 TCP 握手。池大小建议按 连接数 = (RTT × QPS) / 命令数 估算,一般 50-200 即可覆盖大多数场景。
大 Key 拆分:大 Key 导致网络传输慢、阻塞主线程、影响同步。排查方式:
bashredis-cli --bigkeys # 扫描各类型最大 key redis-cli MEMORY USAGE key # 查看单个 key 内存占用
拆分策略:将大 Hash 拆为多个小 Hash(按字段分桶),大 List 用 LRANGE 分段读取。
禁用 THP:Transparent Huge Pages 会导致 fork 耗时剧增,影响 RDB/AOF 重写:
bashecho never > /sys/kernel/mm/transparent_hugepage/enabled
CPU 优化
禁用 KEYS 命令:KEYS 会遍历所有 key,时间复杂度 O(N),生产环境必须禁用。用 SCAN 增量迭代替代:
bashSCAN 0 MATCH user:* COUNT 100
避免慢命令:SORT 大集合、SUNION/SINTER 大集合操作、LRANGE 0 -1 全量读取等都是常见性能杀手。核心原则:单次操作时间控制在毫秒级。
Lua 脚本减少往返:Lua 在服务端原子执行,减少网络 RTT,适合复合原子操作:
lua-- 原子性扣库存并返回余量 local stock = tonumber(redis.call("GET", KEYS[1])) if stock and stock > 0 then redis.call("DECR", KEYS[1]) return stock - 1 else return -1 end
注意 Lua 脚本执行期间 Redis 阻塞,脚本必须简短。
Redis 6.0+ 多线程 IO:Redis 6.0 引入多线程处理网络读写,命令执行仍是单线程。开启方式:
shellio-threads 4 io-threads-do-reads yes
适合网络 IO 成为瓶颈的场景(高并发小命令),CPU 密集型操作无法加速。
持久化优化
RDB 调优:调整保存频率,低峰期触发;关闭 RDB 压缩(rdbcompression no)可降低 CPU 开销,但文件会变大。save "" 可完全禁用 RDB。
AOF 调优:
appendfsync everysec是性能与安全的平衡点,最多丢 1 秒数据- 调整
auto-aof-rewrite-percentage和auto-aof-rewrite-min-size控制重写触发 - 低峰期手动
BGREWRITEAOF减少影响
混合持久化(Redis 4.0+):aof-use-rdb-preamble yes,AOF 重写时前半段写 RDB 格式(快),后半段写 AOF 增量(全),兼顾恢复速度和数据安全。
纯缓存场景关闭持久化:如果 Redis 只做缓存、数据可从 DB 重建,关闭 RDB 和 AOF 可大幅提升性能。
集群优化
数据分片与避免倾斜:Redis Cluster 按 hash slot 分片(16384 个),用 CLUSTER SLOT 查看分布。避免倾斜的方法:合理设计 key 的 hash tag({tag}),热点 key 拆分为多个 key 分散到不同 slot。
读写分离:从节点分担读流量,注意从节点默认拒绝写操作。复制延迟可能导致读到旧数据,强一致性场景慎用。
故障转移:哨兵模式(Sentinel)适合主从架构的自动故障转移;Redis Cluster 自带故障检测和转移能力。面试常问两者的区别:Sentinel 是独立进程监控主从,Cluster 是去中心化的分片+高可用方案。
监控与调优
慢查询日志:
bashCONFIG SET slowlog-log-slower-than 10000 # 阈值 10ms CONFIG SET slowlog-max-len 128 SLOWLOG GET 10 # 查看最近 10 条慢查询
INFO 命令关键指标:
bashINFO memory # used_memory、fragmentation_ratio INFO commandstats # 命令调用次数和耗时 INFO replication # 主从复制状态和延迟 INFO stats # keyspace_hits/misses 算命中率
redis-benchmark 压测:
bashredis-benchmark -h 127.0.0.1 -p 6379 -c 50 -n 10000 -t set,get
操作系统优化
文件描述符:
bashulimit -n 65535 # 或永久配置 /etc/security/limits.conf
TCP 参数:
bashecho 3 > /proc/sys/net/ipv4/tcp_fastopen # 调整 TCP 缓冲区 sysctl -w net.core.somaxconn=65535
关闭 THP:已在网络优化中提及,这里再次强调,这是 Redis 生产部署的必要步骤。
绑定 CPU:taskset 将 Redis 绑定到特定 CPU 核,减少上下文切换,对延迟敏感场景有效。
客户端优化
客户端选型:
- Jedis:同步阻塞,简单场景够用
- Lettuce:基于 Netty 的异步非阻塞,Spring Boot 2.x 默认
- Redisson:分布式锁、限流器等高级功能开箱即用
多级缓存:本地缓存(Caffeine/Guava Cache)+ Redis 二级缓存,热点数据本地缓存 1-5 秒,减少 Redis 访问量。
避免 N+1 查询:用 MGET/Pipeline 批量查询,用 Hash 结构化存储减少查询次数。
架构优化
Redis Proxy:Twemproxy、Predixy 等代理层实现分片和连接池管理,对客户端透明。缺点是多一跳网络开销。
高可用方案选型:
- 主从 + Sentinel:适合数据量不大、读多写少
- Redis Cluster:适合数据量大、需要水平扩展
- 两者不兼容,架构设计时需提前选型
多实例部署:单机多实例可充分利用多核 CPU,每个实例绑定不同核,独立持久化互不影响。
面试答题思路
面试官问 Redis 性能优化,建议按优先级回答:
- 最优先:禁用 KEYS、大 Key 拆分、Pipeline、设置合理 TTL 和淘汰策略
- 持久化:AOF everysec、混合持久化、纯缓存可关闭
- 架构层:读写分离、Cluster 分片、多级缓存
- 运维层:慢查询监控、内存碎片治理、OS 参数调优
每个点说出原理和具体操作,面试官追问时能展开即可。不要泛泛而谈"多维度优化",要落地到具体配置项和命令。