Redis常见问题排查手册

前言

Redis用着用着总会遇到各种问题:连接超时、内存暴涨、主从不同步、缓存雪崩...

这篇整理Redis常见问题的排查思路和解决方案,线上出问题时能快速定位。


一、连接问题

1.1 连接超时

现象 :客户端报Connection timed outJedisConnectionException

排查步骤

bash 复制代码
# 1. 检查Redis是否存活
redis-cli ping

# 2. 检查端口是否监听
ss -tlnp | grep 6379

# 3. 检查连接数
redis-cli info clients
# connected_clients:150  ← 当前连接数

# 4. 查看最大连接数配置
redis-cli config get maxclients
# maxclients: 10000

# 5. 检查是否有慢查询阻塞
redis-cli slowlog get 10

常见原因

  1. 连接数打满
bash 复制代码
# 查看客户端列表
redis-cli client list

# 找到空闲时间长的连接
redis-cli client list | awk -F'[ =]' '{print $4, $10}' | sort -k2 -rn | head

解决:增大maxclients,或检查客户端连接池配置。

  1. 网络问题
bash 复制代码
# 测试网络延迟
redis-cli --latency

# 持续监控
redis-cli --latency-history
  1. Redis阻塞
bash 复制代码
# 检查阻塞操作
redis-cli info stats | grep blocked

1.2 连接被拒绝

现象Connection refused

bash 复制代码
# 检查绑定地址
redis-cli config get bind
# 如果是 127.0.0.1,远程无法连接

# 修改配置
# /etc/redis/redis.conf
bind 0.0.0.0  # 或具体IP

# 检查防火墙
iptables -L -n | grep 6379
firewall-cmd --list-ports | grep 6379

二、内存问题

2.1 内存暴涨

排查步骤

bash 复制代码
# 1. 查看内存使用
redis-cli info memory
# used_memory_human: 2.5G
# used_memory_peak_human: 3.1G
# maxmemory_human: 4G

# 2. 查看各类型key的内存占用
redis-cli memory doctor

# 3. 分析大key
redis-cli --bigkeys

# 4. 扫描特定前缀的key数量
redis-cli keys "user:*" | wc -l
# 注意:生产环境用 scan 代替 keys
redis-cli scan 0 match "user:*" count 1000

找出大key

bash 复制代码
# 分析RDB文件(推荐)
# 安装 rdb-tools
pip install rdbtools python-lzf

# 导出大key报告
rdb -c memory /var/lib/redis/dump.rdb --bytes 10240 -f memory.csv

或者用Redis自带命令:

bash 复制代码
# 查看某个key的内存占用
redis-cli memory usage mykey

# 批量分析
redis-cli --bigkeys -i 0.1  # 每100ms扫描一次,降低影响

2.2 内存淘汰

现象 :写入失败,报OOM command not allowed

bash 复制代码
# 查看淘汰策略
redis-cli config get maxmemory-policy
# volatile-lru / allkeys-lru / noeviction 等

# 查看淘汰统计
redis-cli info stats | grep evicted
# evicted_keys: 12345

淘汰策略说明

策略 说明
noeviction 不淘汰,内存满了报错
volatile-lru 淘汰有过期时间的key(LRU)
allkeys-lru 淘汰所有key(LRU)
volatile-ttl 淘汰TTL最短的key
volatile-random 随机淘汰有过期时间的key
allkeys-random 随机淘汰

建议配置

bash 复制代码
# redis.conf
maxmemory 4gb
maxmemory-policy allkeys-lru

2.3 内存碎片

bash 复制代码
# 查看碎片率
redis-cli info memory | grep mem_fragmentation_ratio
# mem_fragmentation_ratio: 1.52

# 大于1.5说明碎片较多

解决方案:

bash 复制代码
# Redis 4.0+ 支持在线碎片整理
redis-cli config set activedefrag yes

# 或者重启Redis

三、主从问题

3.1 主从不同步

现象:从库数据和主库不一致

bash 复制代码
# 查看复制状态
redis-cli info replication

# 主库显示
role:master
connected_slaves:1
slave0:ip=192.168.1.2,port=6379,state=online,offset=123456,lag=0

# 从库显示
role:slave
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0

关键指标

  • master_link_status:up正常,down断开
  • master_last_io_seconds_ago:与主库最后通信时间
  • lag:复制延迟

常见原因

  1. 网络问题
bash 复制代码
# 从库上检查
redis-cli info replication | grep master_link_down_since_seconds
  1. 复制缓冲区溢出
bash 复制代码
# 主库配置
redis-cli config get repl-backlog-size
# 默认1MB,高并发写入需要调大

# 建议配置
repl-backlog-size 256mb
  1. 从库复制超时
bash 复制代码
# 检查超时配置
redis-cli config get repl-timeout
# 默认60秒

# 大数据量同步可能需要调大
repl-timeout 300

3.2 主从切换后数据丢失

原因:异步复制导致主库写入未同步到从库就宕机了

解决方案

bash 复制代码
# 配置最少从库数量
min-replicas-to-write 1
min-replicas-max-lag 10

# 含义:至少1个从库延迟不超过10秒,否则主库拒绝写入

四、性能问题

4.1 慢查询

bash 复制代码
# 查看慢查询日志
redis-cli slowlog get 10

# 输出示例
1) 1) (integer) 123          # ID
   2) (integer) 1609459200   # 时间戳
   3) (integer) 15000        # 耗时(微秒)
   4) 1) "keys"              # 命令
      2) "*"

# 配置慢查询阈值(微秒)
redis-cli config set slowlog-log-slower-than 10000  # 10ms
redis-cli config set slowlog-max-len 1000

常见慢操作

命令 问题 替代方案
keys * 全库扫描 scan
hgetall 大hash hscan / 只取需要的字段
smembers 大set sscan
lrange 0 -1 大list 分页获取
del bigkey 阻塞删除 unlink(异步删除)

4.2 热点key

现象:QPS很高但集群负载不均

bash 复制代码
# 开启热点key统计(Redis 4.0+)
redis-cli --hotkeys

# 或者用monitor采样(生产慎用)
redis-cli monitor | head -10000 > monitor.log
awk '{print $4}' monitor.log | sort | uniq -c | sort -rn | head

解决方案

  1. 本地缓存:热点数据在应用层缓存
  2. 读写分离:读请求分散到从库
  3. key拆分hotkeyhotkey:1, hotkey:2...

4.3 大key删除阻塞

bash 复制代码
# 查看key元素数量
redis-cli llen mylist
redis-cli hlen myhash
redis-cli scard myset

# 异步删除(Redis 4.0+)
redis-cli unlink bigkey

# 或者分批删除
# Hash
redis-cli hscan myhash 0 count 100
# 然后 hdel 分批删

# List
redis-cli ltrim mylist 0 -1001  # 每次删1000个

五、持久化问题

5.1 RDB持久化失败

现象 :日志报Background saving error

bash 复制代码
# 查看最近一次持久化状态
redis-cli info persistence
# rdb_last_bgsave_status: ok/err
# rdb_last_bgsave_time_sec: 5

# 查看日志
tail -100 /var/log/redis/redis-server.log

常见原因

  1. 磁盘空间不足
bash 复制代码
df -h
  1. fork失败(内存不足)
bash 复制代码
# 检查overcommit配置
cat /proc/sys/vm/overcommit_memory
# 0: 默认,可能导致fork失败
# 1: 允许overcommit

# 修改
echo 1 > /proc/sys/vm/overcommit_memory
# 或永久修改 /etc/sysctl.conf
vm.overcommit_memory = 1
  1. 透明大页导致延迟
bash 复制代码
# 禁用透明大页
echo never > /sys/kernel/mm/transparent_hugepage/enabled

5.2 AOF重写阻塞

bash 复制代码
# 查看AOF状态
redis-cli info persistence | grep aof

# 手动触发重写
redis-cli bgrewriteaof

# 配置自动重写
auto-aof-rewrite-percentage 100  # 增长100%触发
auto-aof-rewrite-min-size 64mb   # 最小64MB才触发

六、集群问题

6.1 集群状态异常

bash 复制代码
# 查看集群状态
redis-cli cluster info
# cluster_state:ok/fail
# cluster_slots_assigned:16384
# cluster_slots_ok:16384
# cluster_slots_fail:0

# 查看节点
redis-cli cluster nodes

常见问题

  1. slot未分配
bash 复制代码
# 检查slot覆盖
redis-cli cluster slots

# 手动分配
redis-cli cluster addslots 0 1 2 ...
  1. 节点故障
bash 复制代码
# 查看失败节点
redis-cli cluster nodes | grep fail

# 手动故障转移
redis-cli cluster failover

6.2 MOVED/ASK错误

客户端报MOVEDASK错误,说明请求到了错误的节点。

解决:使用集群模式的客户端

bash 复制代码
# 命令行用-c参数
redis-cli -c -h host -p port

# 客户端库要用cluster模式
# Java: JedisCluster
# Python: redis-py-cluster

6.3 跨机房/跨网络访问

多个机房部署的Redis需要互通,或者本地开发需要连远程Redis。

方案1:SSH隧道

bash 复制代码
ssh -L 6379:redis-server:6379 user@跳板机 -N
redis-cli -h 127.0.0.1

方案2:VPN/组网

如果经常需要访问多个内网Redis,用组网工具更方便。WireGuard、ZeroTier、星空组网这类工具配置一次,后续直接用内网IP访问,不用每次建隧道。


七、快速诊断脚本

bash 复制代码
#!/bin/bash
# redis_check.sh

REDIS_CLI="redis-cli"
HOST=${1:-127.0.0.1}
PORT=${2:-6379}

echo "=== Redis诊断 $HOST:$PORT ==="

echo -e "\n[1] 连通性"
$REDIS_CLI -h $HOST -p $PORT ping

echo -e "\n[2] 内存使用"
$REDIS_CLI -h $HOST -p $PORT info memory | grep -E "used_memory_human|maxmemory_human|mem_fragmentation_ratio"

echo -e "\n[3] 连接数"
$REDIS_CLI -h $HOST -p $PORT info clients | grep connected_clients

echo -e "\n[4] 复制状态"
$REDIS_CLI -h $HOST -p $PORT info replication | grep -E "role|master_link_status|connected_slaves"

echo -e "\n[5] 持久化"
$REDIS_CLI -h $HOST -p $PORT info persistence | grep -E "rdb_last_bgsave_status|aof_enabled"

echo -e "\n[6] 慢查询(最近5条)"
$REDIS_CLI -h $HOST -p $PORT slowlog get 5

echo -e "\n[7] Key数量"
$REDIS_CLI -h $HOST -p $PORT dbsize

echo -e "\n[8] QPS"
$REDIS_CLI -h $HOST -p $PORT info stats | grep instantaneous_ops_per_sec

echo -e "\n=== 诊断完成 ==="

总结

Redis问题排查思路:

问题类型 排查命令 关键指标
连接问题 info clients connected_clients
内存问题 info memory used_memory, fragmentation
主从问题 info replication master_link_status, lag
性能问题 slowlog get 慢查询命令
持久化 info persistence rdb/aof状态
集群问题 cluster info cluster_state

核心命令:

bash 复制代码
redis-cli info          # 整体状态
redis-cli info memory   # 内存
redis-cli info clients  # 连接
redis-cli info replication  # 主从
redis-cli slowlog get 10    # 慢查询
redis-cli --bigkeys     # 大key分析
redis-cli monitor       # 实时命令监控(慎用)

遇到问题先看info,90%的问题都能从这里找到线索。


有问题评论区交流。

相关推荐
计算机程序设计小李同学1 小时前
基于SpringBoot的个性化穿搭推荐及交流平台
java·spring boot·后端
用户47949283569151 小时前
同事一个比喻,让我搞懂了Docker和k8s的核心概念
前端·后端
li.wz3 小时前
Spring Bean 生命周期解析
java·后端·spring
sanggou3 小时前
【实战总结】Spring Boot 后端接口防抖详解与实现方案(含注解 + Redis)
spring boot·后端
Victor3564 小时前
Hibernate(26)什么是Hibernate的透明持久化?
后端
盖世英雄酱581364 小时前
不是所有的this调用会导致事务失效
java·后端
Victor3564 小时前
Hibernate(25)Hibernate的批量操作是什么?
后端
Thetimezipsby4 小时前
Go(GoLang)语言基础、知识速查
开发语言·后端·golang
为自己_带盐5 小时前
从零开始玩转 Microsoft Agent Framework:我的 MAF 实践之旅-第二篇
后端·microsoft·ai·.net
乌日尼乐5 小时前
【Java基础整理】java数组详解
java·后端