maxmemory设置不合理会导致查询变慢,设为0可能触发swap使延迟飙升,建议按物理内存70%-80%设硬上限并配合适当淘汰策略。

maxmemory 设置不合理会导致查询变慢
Redis 所有数据都在内存中,maxmemory 配置不当会直接引发频繁淘汰、内存抖动甚至 OOM。设为 0(不限制)看似安全,但一旦业务突增或缓存未设 TTL,内存会持续上涨,触发操作系统级 swap,查询延迟飙升到毫秒甚至百毫秒级。
建议根据物理内存和业务水位设置硬上限,例如 64GB 机器上设 maxmemory 48gb,并搭配 maxmemory-policy 使用:
-
allkeys-lru:适用于通用缓存场景,但注意它不区分冷热数据,可能误删高频键 -
volatile-lru:仅淘汰带 TTL 的键,适合明确标记过期时间的业务,避免误伤永久键 - 避免用
noeviction—— 写入失败后客户端报(error) OOM command not allowed when used memory > 'maxmemory',查询本身虽不卡,但上游逻辑可能崩溃重试,放大压力
client-output-buffer-limit 触发阻塞式驱逐
当客户端(尤其是订阅 Pub/Sub 或使用 monitor 的调试客户端)消费慢,Redis 会缓存输出数据在内存中。若超出 client-output-buffer-limit 限制,Redis 会强制关闭该连接,或更糟——对 PUBSUB 客户端启用 hard limit 时,会直接阻塞主线程执行驱逐逻辑,导致所有命令排队等待。
典型错误现象:redis-cli --latency 显示延迟突增至 200ms+,INFO clients 中 client_longest_output_list 持续 >10000。
调整建议(以 Pub/Sub 场景为例):
- 确认是否真需长连接接收广播消息;如只是临时调试,改用
redis-cli --csv pubsub channels快速检查 - 生产环境设为:
client-output-buffer-limit pubsub 32mb 8mb 60(软限 32MB、硬限 8MB、超时 60 秒) - 禁用
monitor命令:在redis.conf中添加rename-command MONITOR ""
timeout 和 tcp-keepalive 配置影响连接复用效率
短连接泛滥是百万级查询下的隐形杀手。如果客户端每次查询都新建连接,TCP 握手 + Redis AUTH + SELECT 开销叠加,QPS 上不去,且 TIME_WAIT 连接堆积可能耗尽本地端口。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
timeout 设太小(如 timeout 1),空闲连接 1 秒就断,客户端不得不频繁重建;设太大(如 timeout 0),异常断连的僵尸连接长期滞留,占用 maxclients 资源。
推荐组合:
-
timeout 300(5 分钟):平衡资源回收与连接复用 -
tcp-keepalive 300:内核每 5 分钟探测一次连接活性,及时清理死链 - 配合客户端连接池使用,如 Jedis 的
setMaxIdle(20)、setMinIdle(5),避免池过大撑爆 Redismaxclients
slowlog-log-slower-than 和 latency-monitor-threshold 是性能问题的第一线索
很多团队等到接口超时才查 Redis,其实慢日志和延迟监控早就在报警。默认 slowlog-log-slower-than 10000(10ms)太宽松,百万数据下一条 HGETALL 或 SMEMBERS 就可能超时,但不会记入 slowlog。
建议调紧:
-
slowlog-log-slower-than 1000(1ms):捕获真实瓶颈命令 -
latency-monitor-threshold 10(10ms):开启延迟监控,用LATENCY LATEST查最近异常事件 - 定期执行
SLOWLOG GET 10,重点关注SCAN、KEYS、HGETALL、SMEMBERS等 O(n) 命令出现频次
真正难的不是调参,而是让每个 SCAN 都带 count、每个大 Hash 都拆成小字段、每个业务查询都走索引结构而非暴力遍历——配置只是兜底,设计才是根基。










