redis-cli —— Redis 操作与排障

运维工具手册 08-数据库工具 7.5 KB 原文

redis-cli —— Redis 操作与排障

分类:08 数据库工具 适用:Redis 5 / 6 / 7,兼容 KeyDB、Dragonfly 大部分命令 一句话:查内存、找大 key、看慢查询、批量导入、集群操作,Redis 运维的基本盘。

1. 它解决什么问题

  • 内存突然涨了,是哪个 key?
  • 响应变慢,是慢命令、大 key 还是阻塞操作?
  • 连接数打满、主从延迟、集群槽位异常。
  • 批量导入/导出数据、清空测试库。

2. 连接

redis-cli                              # 默认 127.0.0.1:6379
redis-cli -h 10.0.0.5 -p 6379
redis-cli -h 10.0.0.5 -p 6379 -a 'password' --no-auth-warning
redis-cli -n 2                         # 选 db 2
redis-cli -s /var/run/redis/redis.sock # Unix socket
redis-cli --tls --cacert ca.crt -h host -p 6380

# 直接执行命令
redis-cli -h host -a pass --no-auth-warning ping
redis-cli info memory
redis-cli -n 0 keys 'user:*'           # ⚠️ 生产禁用

-a 会把密码写进 shell history 和 ps。生产用 REDISCLI_AUTH 环境变量,或 ~/.redisclirc 配 auth。

export REDISCLI_AUTH='password'
redis-cli -h host ping

3. 基础命令

ping                       # PONG
info                       # 全量信息
info memory                # 内存
info stats                 # 命中率、连接、命令统计
info replication          # 主从
info keyspace              # 各 db 的 key 数
dbsize                     # 当前 db key 数
select 1                   # 切库
time
config get maxmemory
config get '*'
client list
slowlog get 10

常用数据类型操作

# String
set k v EX 3600
get k
incr counter
mset a 1 b 2
mget a b

# Hash
hset user:1 name tom age 18
hgetall user:1
hget user:1 name
hdel user:1 age

# List
lpush queue a b c
lrange queue 0 -1
rpop queue

# Set
sadd tags a b c
smembers tags
sinter tags other

# ZSet
zadd rank 100 alice 90 bob
zrevrange rank 0 9 WITHSCORES
zscore rank alice

# 通用
type k
ttl k
pttl k
exists k
del k
expire k 60
rename old new

4. 内存与大 key

redis-cli info memory | grep -E 'used_memory_human|maxmemory_human|mem_fragmentation_ratio'
redis-cli --bigkeys                    # 扫描并列出各类型最大的 key
redis-cli --memkeys                    # 按内存排序(4.0+,较慢)
redis-cli --hotkeys                    # 热点 key(需 maxmemory-policy 为 lfu)
redis-cli memory usage <key> SAMPLES 0 # 单 key 精确内存
redis-cli object encoding <key>        # 编码(ziplist/quicklist/hashtable)

--bigkeys 输出:

[00.00%] Biggest string found so far '"session:xxx"' with 51200 bytes
[45.00%] Biggest hash   found so far '"user:12345"' with 128 fields
-------- summary -------
Sampled 1000000 keys in the keyspace!
Total key length in bytes is 24000000 (avg len 24.00)
Biggest string found '"session:xxx"' has 51200 bytes
Biggest hash   found '"user:12345"' has 128 fields

大 key 的危害:del/hgetall 会阻塞主线程,导致其他请求超时。处理:

# 删除大 key 用 UNLINK(异步)
redis-cli unlink big:key

# 大 hash 分片遍历,不要 hgetall
redis-cli hscan big:hash 0 COUNT 100

# 大 key 分批删除(lua 或 scan + hdel)

5. 遍历:用 SCAN 不用 KEYS

# ❌ KEYS 会阻塞整个实例
redis-cli keys 'user:*'

# ✅ SCAN 渐进式遍历
redis-cli --scan --pattern 'user:*' --count 1000 | head
redis-cli scan 0 MATCH 'user:*' COUNT 1000

# 脚本里循环直到 cursor 归零
cursor=0
while :; do
  out=$(redis-cli scan $cursor MATCH 'user:*' COUNT 1000)
  cursor=$(echo "$out" | head -1)
  echo "$out" | tail -n +2
  [ "$cursor" = "0" ] && break
done

SCAN 只保证"遍历期间一直存在的元素都会被返回一次",可能重复,需要去重。

6. 性能与阻塞排查

# 实时统计
redis-cli --stat
redis-cli --latency
redis-cli --latency-history
redis-cli --intrinsic-latency 100     # 测系统本身延迟(在服务器上跑)

# 慢查询
redis-cli config get slowlog-log-slower-than
redis-cli config get slowlog-max-len
redis-cli slowlog get 20
redis-cli slowlog reset

# 实时命令流(⚠️ 影响性能,短时使用)
redis-cli monitor

# 大事务/阻塞命令
redis-cli client list | awk '$6 ~ /cmd=/ {print}' | head
redis-cli client list type normal
redis-cli client kill id <id>
redis-cli client kill type pubsub

info stats 关键指标:

指标 含义
instantaneous_ops_per_sec 当前 QPS
keyspace_hits / keyspace_misses 命中率
rejected_connections 被拒连接(超 maxclients)
evicted_keys 被淘汰的 key 数(内存不足)
expired_keys 过期 key 数
blocked_clients 阻塞客户端(BRPOP 等)
total_net_input_bytes 网络流入

7. 主从与集群

# 主从
redis-cli info replication
# role:master / role:slave, master_link_status:up/down, master_last_io_seconds_ago

# 查看从库延迟
redis-cli -h replica info replication | grep -E 'lag|master_link'

# 集群
redis-cli -c -h 10.0.0.5 -p 7000     # -c 自动跟随 MOVED
redis-cli -c cluster info
redis-cli -c cluster nodes
redis-cli -c cluster slots
redis-cli --cluster check 10.0.0.5:7000
redis-cli --cluster reshard 10.0.0.5:7000
redis-cli --cluster rebalance 10.0.0.5:7000

集群模式下,跨 slot 的多 key 操作会报 CROSSSLOT,用 hash tag 固定:{user:1}:name、{user:1}:age。

8. 批量与迁移

# 生成命令流并管道导入(最快)
redis-cli --pipe < commands.txt

# 导出某模式 key 的值
redis-cli --scan --pattern 'cfg:*' | while read k; do
  echo "SET $k $(redis-cli --raw get $k)"
done > dump.txt

# RDB 文件(不落地内存,直接抓快照)
redis-cli --rdb /backup/dump.rdb

# 执行 Lua
redis-cli --eval script.lua key1 key2 , arg1 arg2

# 从库/集群间同步用工具
# redis-shake、redis-migrate-tool(官方/rehash 场景)

9. 实战场景

9.1 内存暴涨定位

redis-cli info memory | grep -E 'used_memory_human|used_memory_peak_human|maxmemory_human|evicted_keys'
redis-cli --bigkeys
redis-cli info keyspace
redis-cli --scan --pattern 'session:*' --count 1000 | wc -l

常见原因:无 TTL 的缓存、大 hash 累积、evicted_keys 为 0 但内存满(noeviction 策略)。

9.2 请求变慢

redis-cli --latency
redis-cli slowlog get 20
redis-cli info stats | grep -E 'instantaneous_ops|rejected'
redis-cli --bigkeys

排查顺序:慢命令 → 大 key → 持久化 fork(info persistence 的 rdb_last_fork_time)→ 网络/客户端。

9.3 连接数打满

redis-cli info clients
redis-cli config get maxclients
redis-cli client list | wc -l
redis-cli client list | awk '{print $2}' | sort | uniq -c | sort -nr | head

client list 第二列是 addr=ip:port,按来源 IP 聚合能看出是哪个应用在刷连接。

9.4 清空测试环境

redis-cli -n 1 flushdb        # 清当前 db(⚠️)
redis-cli flushall            # 清所有 db(⚠️⚠️)
redis-cli -h prod -p 6379 --scan --pattern 'test:*' | xargs -r -n 100 redis-cli del

生产执行前确认连的是哪个实例:redis-cli info server | grep -E 'run_id|tcp_port|config_file'。

9.5 检查淘汰策略

redis-cli config get maxmemory-policy
redis-cli info stats | grep evicted_keys
策略 行为
noeviction 内存满时写入报错(默认,缓存场景不合适)
allkeys-lru 所有 key 按 LRU 淘汰(纯缓存推荐)
volatile-lru 只淘汰设了 TTL 的
allkeys-lfu 按访问频率淘汰(4.0+)
volatile-ttl 优先淘汰快过期的

10. 常见坑

  1. 生产用 KEYS *:单线程阻塞,大库直接卡死几秒到几分钟。用 SCAN。
  2. MONITOR 长时间开:严重拖慢性能,只做秒级抓取。
  3. FLUSHALL 打错实例:先 info server 确认,生产加 rename-command 禁用。
  4. -a 密码进 history:用 REDISCLI_AUTH。
  5. --bigkeys 也是全量扫描:在主库高峰期执行仍会增压,建议在从库跑。
  6. 大 key 用 DEL:同步释放内存会阻塞,用 UNLINK。
  7. 集群模式忘加 -c:报 MOVED 错误,以为 key 不存在。
  8. info 输出解析:不同版本字段有增减,脚本用 grep 而非固定行号。
  9. maxmemory 未设:Redis 会吃满宿主机内存被 OOM Killer 干掉。
  10. mem_fragmentation_ratio < 1:说明用了 swap,性能断崖,需排查内存。
  11. 持久化 fork 阻塞:info persistence 的 latest_fork_usec 过大说明实例内存太大,考虑拆分。
  12. CONFIG SET 不持久化:重启丢失,要同时改 redis.conf 或 CONFIG REWRITE。
  13. 主从切换后客户端未重连:需要哨兵/集群代理,客户端要有重连逻辑。

11. 速查表

redis-cli -h <h> -p <p> -a <pass> --no-auth-warning
export REDISCLI_AUTH=pass

info / info memory / info stats / info replication / info keyspace
dbsize
config get maxmemory / maxmemory-policy
slowlog get 20
client list / client kill id <id>
--bigkeys / --memkeys / --hotkeys
--scan --pattern 'x:*' --count 1000
--stat / --latency / --latency-history
--rdb /backup/dump.rdb
--pipe < cmds.txt
monitor                              # ⚠️ 短时

unlink <bigkey>                      # 异步删除
memory usage <key> SAMPLES 0
object encoding <key>

-c cluster info / nodes / slots
--cluster check <host:port>
flushdb / flushall                   # ⚠️