Skip to content

Redis 命令行诊断

基本诊断命令

基本诊断命令是Redis故障排查的基础,用于快速了解Redis的运行状态、连接情况和配置信息。

1. 连接与状态检查

这部分命令用于检查Redis的基本连接状态和服务器信息:

bash
# 测试Redis连接是否正常,返回PONG表示连接正常
redis-cli ping

# 查看Redis版本信息
redis-cli info server | grep redis_version

# 查看Redis完整运行状态,包括版本、运行时间、内存使用等
redis-cli info server

# 查看Redis所有配置项
redis-cli config get *

# 查看特定配置项,如最大内存配置
redis-cli config get maxmemory
# 查看AOF持久化配置
redis-cli config get appendonly

2. 客户端连接检查

客户端连接问题是Redis常见故障之一,这部分命令用于监控和管理客户端连接:

bash
# 查看客户端连接统计信息,包括连接数、阻塞连接数等
redis-cli info clients

# 查看当前连接的客户端数量
redis-cli info clients | grep connected_clients

# 查看客户端详细列表,包括每个客户端的IP、端口、空闲时间等
redis-cli client list

# 查看长连接客户端,筛选出空闲时间大于60秒的客户端
redis-cli client list | grep -i idle | awk -F' ' '$3 ~ /idle=[0-9]+/ && substr($3,6) > 60 {print $0}'

# 关闭指定IP和端口的客户端连接
redis-cli client kill <ip>:<port>

# 关闭所有空闲连接,释放资源
redis-cli client list | grep -i idle | awk -F' ' '{print $2}' | awk -F'=' '{print $2}' | xargs -I {} redis-cli client kill {}

内存诊断

内存问题是Redis常见故障之一,包括内存使用率过高、内存泄漏、内存碎片率过高等。以下命令用于诊断和分析Redis的内存使用情况。

1. 内存使用概览

这部分命令用于查看Redis的整体内存使用情况:

bash
# 查看内存使用的详细信息,包括使用量、碎片率、峰值等
redis-cli info memory

# 查看内存使用率相关指标
redis-cli info memory | grep used_memory
# 查看内存碎片率,碎片率过高(>1.5)可能需要优化
redis-cli info memory | grep mem_fragmentation_ratio

# 查看内存使用峰值
redis-cli info memory | grep used_memory_peak

# 查看当前的内存淘汰策略
redis-cli config get maxmemory-policy

2. 内存分析工具

redis-cli --bigkeys

bigkeys命令用于查找Redis中的大键,这些大键可能导致内存使用过高或性能问题:

bash
# 查找大键(耗时较长,生产环境谨慎使用)
redis-cli --bigkeys

# 带密码的情况
redis-cli -a <password> --bigkeys

# 非交互模式,将结果保存到文件
redis-cli --bigkeys > bigkeys.txt

自定义脚本分析内存

可以使用自定义脚本来更详细地分析Redis的内存使用情况:

bash
# 简单的内存分析脚本示例,查看前1000个键的内存使用
redis-cli --scan | head -1000 | xargs -I {} redis-cli debug object {}

# 更详细的内存分析,仅查看键名和序列化长度
redis-cli --scan | xargs -I {} redis-cli debug object {} | grep -E '^(key|serializedlength)'

3. 内存泄漏检测

内存泄漏是指Redis内存使用持续增长而不释放的情况,可以通过以下命令进行检测:

bash
# 实时监控内存使用趋势,每秒刷新一次
watch -n 1 "redis-cli info memory | grep used_memory_human"

# 查看键过期情况,包括过期的键数量和被淘汰的键数量
redis-cli info stats | grep expired_keys
redis-cli info stats | grep evicted_keys

# 检查内存碎片率,碎片率过高会导致实际使用内存大于数据占用内存
redis-cli info memory | grep mem_fragmentation_ratio

性能诊断

1. 性能指标概览

bash
# 查看性能统计信息
redis-cli info stats

# 查看命令执行速度
redis-cli info stats | grep instantaneous_ops_per_sec

# 查看命中率
redis-cli info stats | grep -E '(keyspace_hits|keyspace_misses)'

# 计算命中率百分比
redis-cli --raw info stats | awk '/keyspace_hits|keyspace_misses/ {a[$1]=$2} END {print "Hit rate: " (a["keyspace_hits"]/(a["keyspace_hits"]+a["keyspace_misses"])*100) "%"}'

2. 慢查询分析

bash
# 查看慢查询配置
redis-cli config get slowlog*

# 设置慢查询阈值(微秒)
redis-cli config set slowlog-log-slower-than 10000

# 设置慢查询日志长度
redis-cli config set slowlog-max-len 1000

# 查看慢查询日志
redis-cli slowlog get

# 查看指定数量的慢查询
redis-cli slowlog get 10

# 查看慢查询日志长度
redis-cli slowlog len

# 重置慢查询日志
redis-cli slowlog reset

3. 命令统计分析

bash
# 查看命令统计信息
redis-cli info commandstats

# 按调用次数排序命令
redis-cli --raw info commandstats | sort -rn -k3

# 按执行时间排序命令
redis-cli --raw info commandstats | sort -rn -k5

持久化诊断

1. RDB 诊断

bash
# 查看RDB配置
redis-cli config get save

# 手动触发RDB备份
redis-cli bgsave

# 查看RDB备份状态
redis-cli info persistence | grep rdb_

# 查看最后一次RDB备份时间
redis-cli lastsave

# 检查RDB文件是否存在
ls -la /var/lib/redis/dump.rdb

2. AOF 诊断

bash
# 查看AOF配置
redis-cli config get append*

# 手动触发AOF重写
redis-cli bgrewriteaof

# 查看AOF重写状态
redis-cli info persistence | grep aof_

# 检查AOF文件完整性
redis-check-aof --check /var/lib/redis/appendonly.aof

# 修复AOF文件
redis-check-aof --fix /var/lib/redis/appendonly.aof

复制诊断

1. 主从状态检查

bash
# 查看复制信息
redis-cli info replication

# 查看从节点状态
redis-cli info replication | grep slave

# 查看主节点状态
redis-cli info replication | grep master

# 查看复制偏移量
redis-cli info replication | grep offset

2. 复制延迟检查

bash
# 在主节点查看偏移量
MASTER_OFFSET=$(redis-cli -h <master-ip> -p <master-port> info replication | grep master_repl_offset | cut -d: -f2)

# 在从节点查看偏移量
SLAVE_OFFSET=$(redis-cli -h <slave-ip> -p <slave-port> info replication | grep slave_repl_offset | cut -d: -f2)

# 计算复制延迟
DELAY=$((MASTER_OFFSET - SLAVE_OFFSET))
echo "Replication delay: $DELAY bytes"

3. 复制故障排查

bash
# 检查从节点是否连接到主节点
redis-cli -h <slave-ip> -p <slave-port> info replication | grep master_link_status

# 查看从节点复制错误
redis-cli -h <slave-ip> -p <slave-port> info replication | grep master_link_down_since_seconds

# 重新配置从节点
redis-cli -h <slave-ip> -p <slave-port> slaveof no one
redis-cli -h <slave-ip> -p <slave-port> slaveof <master-ip> <master-port>

Redis Cluster 诊断

1. 集群状态检查

bash
# 查看集群状态
redis-cli -c cluster info

# 查看集群节点信息
redis-cli -c cluster nodes

# 查看集群槽分配
redis-cli -c cluster slots

# 检查集群键分布
redis-cli -c cluster countkeysinslot <slot>

2. 集群故障排查

bash
# 查看集群健康状态
redis-cli -c cluster info | grep cluster_state

# 查看故障节点
redis-cli -c cluster nodes | grep fail

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

# 强制故障转移(危险操作)
redis-cli -c cluster failover force

3. 集群性能检查

bash
# 查看集群中每个节点的性能
for node in $(redis-cli -c cluster nodes | grep master | awk '{print $2}'); do
  ip=$(echo $node | cut -d: -f1)
  port=$(echo $node | cut -d: -f2 | cut -d@ -f1)
  echo "=== Node $ip:$port ==="
  redis-cli -c -h $ip -p $port info stats | grep instantaneous_ops_per_sec
  redis-cli -c -h $ip -p $port info memory | grep used_memory_human
  echo

done

Redis Sentinel 诊断

1. Sentinel 状态检查

bash
# 查看Sentinel信息
redis-cli -p <sentinel-port> info sentinel

# 查看Sentinel监控的主节点
redis-cli -p <sentinel-port> sentinel masters

# 查看Sentinel监控的从节点
redis-cli -p <sentinel-port> sentinel slaves <master-name>

# 查看Sentinel集群成员
redis-cli -p <sentinel-port> sentinel sentinels <master-name>

2. Sentinel 故障排查

bash
# 查看Sentinel日志
redis-cli -p <sentinel-port> debug log

# 手动触发故障转移
redis-cli -p <sentinel-port> sentinel failover <master-name>

# 检查Sentinel配置
redis-cli -p <sentinel-port> sentinel get-master-addr-by-name <master-name>

慢查询诊断

1. 慢查询配置与查看

bash
# 设置慢查询阈值(10毫秒)
redis-cli config set slowlog-log-slower-than 10000

# 设置慢查询日志长度
redis-cli config set slowlog-max-len 1000

# 查看慢查询日志
redis-cli slowlog get

# 查看慢查询统计
redis-cli slowlog len

# 按执行时间排序慢查询
redis-cli slowlog get | sort -rn -k3

2. 慢查询分析

bash
# 提取慢查询命令
redis-cli slowlog get | awk -F'"' '{print $8}' | sort | uniq -c | sort -rn

# 分析慢查询的键模式
redis-cli slowlog get | grep -oE '"[a-zA-Z0-9_:-]+"' | grep -v '"COMMAND"' | sort | uniq -c | sort -rn | head -20

# 导出慢查询到文件
redis-cli slowlog get > slowlog.txt

系统级诊断

1. Redis 进程诊断

bash
# 查看Redis进程信息
ps -ef | grep redis

# 查看Redis进程状态
top -p <redis-pid>

# 查看Redis进程的系统调用
strace -p <redis-pid> -c

# 查看Redis进程的文件句柄
lsof -p <redis-pid>

# 查看Redis进程的网络连接
lsof -p <redis-pid> | grep -i ipv4

2. 系统资源诊断

bash
# 查看系统内存使用情况
free -h

# 查看系统CPU使用情况
top

# 查看系统负载
uptime

# 查看磁盘使用情况
df -h

# 查看磁盘I/O
iotop

# 查看网络流量
iftop

# 查看TCP连接状态
ss -s
ss -tuln

3. 网络诊断

bash
# 测试Redis端口连通性
telnet <redis-ip> <redis-port>
nc -zv <redis-ip> <redis-port>

# 测试Redis连接延迟
redis-cli --latency -h <redis-ip> -p <redis-port>

# 持续测试Redis延迟
redis-cli --latency-history -h <redis-ip> -p <redis-port>

# 测试Redis吞吐量
redis-benchmark -h <redis-ip> -p <redis-port> -c 100 -n 100000

高级诊断技巧

1. 调试命令

bash
# 调试指定键
redis-cli debug object <key>

# 调试原始键值
redis-cli debug raw <key>

# 模拟崩溃(危险操作,仅测试环境使用)
redis-cli debug segfault

# 查看Redis堆信息
redis-cli debug hdrhistogram <metric>

2. 监控命令

bash
# 实时监控Redis命令执行
redis-cli monitor

# 监控特定命令
redis-cli monitor | grep SET
redis-cli monitor | grep DEL

# 限制监控输出
redis-cli monitor | head -100

3. 统计命令

bash
# 统计数据库键数量
redis-cli dbsize

# 统计匹配模式的键数量
redis-cli --scan --pattern "user:*" | wc -l

# 统计不同数据类型的键数量
for type in string list set hash zset; do
  count=$(redis-cli --scan --pattern "*" | xargs -I {} redis-cli type {} | grep -c $type)
  echo "$type: $count"
done

4. 批量操作

bash
# 批量获取键
redis-cli mget key1 key2 key3

# 批量设置键
redis-cli mset key1 value1 key2 value2 key3 value3

# 批量删除键
redis-cli keys "temp:*" | xargs redis-cli del

# 批量重命名键
redis-cli keys "old:*" | sed 's/old:/new:/' | xargs -n 2 redis-cli rename

诊断脚本示例

1. 简单的健康检查脚本

bash
#!/bin/bash

REDIS_HOST="127.0.0.1"
REDIS_PORT="6379"
REDIS_PASSWORD=""

# 测试连接
CONNECTION=$(redis-cli -h $REDIS_HOST -p $REDIS_PORT -a $REDIS_PASSWORD ping 2>/dev/null)
if [ "$CONNECTION" != "PONG" ]; then
  echo "Redis connection failed!"
  exit 1
fi

# 检查内存使用率
MEMORY_USAGE=$(redis-cli -h $REDIS_HOST -p $REDIS_PORT -a $REDIS_PASSWORD info memory | grep used_memory_rss_human | cut -d: -f2 | tr -d ' ')
MAX_MEMORY=$(redis-cli -h $REDIS_HOST -p $REDIS_PORT -a $REDIS_PASSWORD config get maxmemory | grep -v maxmemory)

# 检查连接数
CONNECTED_CLIENTS=$(redis-cli -h $REDIS_HOST -p $REDIS_PORT -a $REDIS_PASSWORD info clients | grep connected_clients | cut -d: -f2 | tr -d ' ')
MAX_CLIENTS=$(redis-cli -h $REDIS_HOST -p $REDIS_PORT -a $REDIS_PASSWORD config get maxclients | grep -v maxclients)

# 检查命中率
KEYSPACE_HITS=$(redis-cli -h $REDIS_HOST -p $REDIS_PORT -a $REDIS_PASSWORD info stats | grep keyspace_hits | cut -d: -f2 | tr -d ' ')
KEYSPACE_MISSES=$(redis-cli -h $REDIS_HOST -p $REDIS_PORT -a $REDIS_PASSWORD info stats | grep keyspace_misses | cut -d: -f2 | tr -d ' ')
HIT_RATE=0
if [ $((KEYSPACE_HITS + KEYSPACE_MISSES)) -gt 0 ]; then
  HIT_RATE=$(echo "scale=2; $KEYSPACE_HITS / ($KEYSPACE_HITS + $KEYSPACE_MISSES) * 100" | bc)
fi

echo "Redis Health Check Results:"
echo "- Connection: OK"
echo "- Memory Usage: $MEMORY_USAGE"
echo "- Connected Clients: $CONNECTED_CLIENTS/$MAX_CLIENTS"
echo "- Hit Rate: $HIT_RATE%"

2. 内存泄漏检测脚本

bash
#!/bin/bash

REDIS_HOST="127.0.0.1"
REDIS_PORT="6379"

# 记录初始内存使用情况
INITIAL_MEMORY=$(redis-cli -h $REDIS_HOST -p $REDIS_PORT info memory | grep used_memory | cut -d: -f2 | tr -d ' ')

# 监控内存变化
echo "Monitoring Redis memory usage... (Press Ctrl+C to stop)"
echo "Initial memory: $INITIAL_MEMORY bytes"
echo "Timestamp       Memory Used       Difference"
echo "-------------------------------------------"

while true; do
  CURRENT_MEMORY=$(redis-cli -h $REDIS_HOST -p $REDIS_PORT info memory | grep used_memory | cut -d: -f2 | tr -d ' ')
  DIFFERENCE=$((CURRENT_MEMORY - INITIAL_MEMORY))
  TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
  echo "$TIMESTAMP   $CURRENT_MEMORY bytes   $DIFFERENCE bytes"
  sleep 60
done

常见问题(FAQ)

Q1: 如何快速定位Redis性能瓶颈?

A1: 可以通过以下步骤:

  1. 使用 redis-cli info stats 查看命令执行速度和命中率
  2. 使用 redis-cli --bigkeys 查找大键
  3. 使用 redis-cli slowlog get 分析慢查询
  4. 使用 redis-cli info memory 检查内存使用情况
  5. 使用 tophtop 查看Redis进程的CPU和内存使用率

Q2: 如何识别Redis连接泄露?

A2: 可以通过以下方法:

  1. 监控 connected_clients 指标,看是否持续增长
  2. 使用 redis-cli client list 查看长时间空闲的连接
  3. 分析客户端连接池配置,检查是否正确关闭连接
  4. 使用 lsof -p <redis-pid> 查看文件句柄数量

Q3: 如何排查Redis复制延迟问题?

A3: 可以通过以下步骤:

  1. 检查主从节点的网络连接和延迟
  2. 查看主节点的 master_repl_offset 和从节点的 slave_repl_offset
  3. 检查主节点的写入负载是否过高
  4. 检查从节点的内存和CPU使用率
  5. 查看主节点的 backlog_size 配置是否合适

Q4: 如何处理Redis内存碎片率过高的问题?

A4: 可以采取以下措施:

  1. 重启Redis实例,重建内存分配
  2. 调整 maxmemory-policy 配置,选择合适的内存淘汰策略
  3. 优化键的设计,减少内存碎片
  4. 考虑使用Redis 4.0+ 的自动内存碎片整理功能:config set activedefrag yes

Q5: 如何分析Redis慢查询日志?

A5: 可以通过以下方法:

  1. 设置合适的慢查询阈值:config set slowlog-log-slower-than 10000
  2. 使用 redis-cli slowlog get 查看慢查询
  3. 分析慢查询命令的类型和频率
  4. 检查慢查询涉及的键的大小和类型
  5. 优化慢查询命令,如拆分大键、使用管道命令等

Q6: 如何安全地在生产环境使用 redis-cli --bigkeys

A6: 可以采取以下措施:

  1. 在业务低峰期执行
  2. 使用 --scan 选项替代 keys *,减少对Redis的阻塞
  3. 限制扫描范围:redis-cli --scan --pattern "user:*" | head -1000 | xargs redis-cli debug object
  4. 考虑使用 redis-cli --bigkeys --bytes 选项,查看键的字节大小

Q7: 如何监控Redis Cluster的健康状态?

A7: 可以通过以下方法:

  1. 检查集群状态:redis-cli -c cluster info | grep cluster_state
  2. 查看集群节点状态:redis-cli -c cluster nodes
  3. 检查槽分配情况:redis-cli -c cluster slots
  4. 监控每个节点的性能指标
  5. 使用监控工具如Prometheus + Grafana进行持续监控

Q8: 如何调试Redis客户端连接问题?

A8: 可以通过以下步骤:

  1. 检查Redis服务器的 maxclients 配置
  2. 查看客户端连接数:redis-cli info clients | grep connected_clients
  3. 检查客户端连接列表:redis-cli client list
  4. 检查防火墙规则,确保允许客户端连接
  5. 使用 telnetnc 测试网络连通性
  6. 检查客户端代码,确保正确处理连接超时和重试

Q9: 如何使用 redis-cli monitor 而不影响性能?

A9: 可以采取以下措施:

  1. 限制监控时间:redis-cli monitor | head -1000
  2. 过滤特定命令:redis-cli monitor | grep SET
  3. 在业务低峰期使用
  4. 不要在生产环境长时间运行
  5. 考虑使用更轻量级的监控工具,如Prometheus

Q10: 如何排查Redis持久化失败问题?

A10: 可以通过以下步骤:

  1. 检查Redis日志,查找持久化相关错误
  2. 查看持久化配置:redis-cli config get saveredis-cli config get append*
  3. 检查磁盘空间是否充足:df -h
  4. 检查磁盘I/O性能:iotop
  5. 手动触发持久化操作,观察是否成功:redis-cli bgsaveredis-cli bgrewriteaof