本文是 Redis 运维实战手册,涵盖从基础概念到集群部署、从性能调优到故障排查的全流程。适合 DBA、后端开发和 SRE 日常参考。
一、Redis 基础概览
1.1 Redis 是什么
Redis(Remote Dictionary Server)是一个开源的、基于内存的高性能键值存储系统。它支持多种数据结构,常被用作数据库、缓存和消息中间件。
核心特性:
高性能:纯内存操作,单线程模型避免锁竞争,QPS 可达 10 万+
丰富的数据结构:String、Hash、List、Set、Sorted Set、Stream、HyperLogLog、Bitmap、Geospatial
持久化:支持 RDB 快照和 AOF 日志两种方式
高可用:主从复制、Sentinel 哨兵、Redis Cluster 集群
原子操作:单线程保证命令原子性,支持 Lua 脚本和事务
1.2 数据类型速览
String:最基础的类型,可存储字符串、整数、浮点数,最大 512MB
Hash:键值对集合,适合存储对象(如用户信息)
List:有序链表,支持头尾操作,适合消息队列
Set:无序去重集合,支持交并差运算
Sorted Set (ZSet):带分数的有序集合,适合排行榜
Stream:日志型数据结构,支持消费者组,替代 Kafka 轻量场景
HyperLogLog:基数统计,占用固定 12KB 内存
Bitmap:位操作,适合签到、在线状态等场景
Geospatial:地理位置,支持距离计算和范围查询
1.3 Redis 7.x 新特性
Redis Functions:替代 EVAL 的服务端脚本方案,支持持久化
Multi-part AOF:AOF 文件拆分为多个部分,避免 rewrite 时的磁盘峰值
Shared Pub/Sub:集群模式下的 Pub/Sub 改进
ACL v2:更细粒度的访问控制
二、安装部署
2.1 源码编译安装(推荐)
# 安装依赖
sudo apt-get update && sudo apt-get install -y build-essential tcl pkg-config
# 下载并编译
cd /usr/local/src
wget https://download.redis.io/releases/redis-7.2.5.tar.gz
tar xzf redis-7.2.5.tar.gz
cd redis-7.2.5
make -j$(nproc)
make test
sudo make install PREFIX=/usr/local/redis
# 创建目录
sudo mkdir -p /etc/redis /var/lib/redis /var/log/redis
sudo useradd -r -s /bin/false redis
sudo chown redis:redis /var/lib/redis /var/log/redis2.2 配置文件
# 复制配置文件
sudo cp redis.conf /etc/redis/redis.conf
sudo cp sentinel.conf /etc/redis/sentinel.conf核心配置项(/etc/redis/redis.conf):
# 网络
bind 0.0.0.0
port 6379
protected-mode yes
tcp-backlog 511
timeout 300
tcp-keepalive 300
# 通用
daemonize yes
pidfile /var/run/redis/redis-server.pid
loglevel notice
logfile /var/log/redis/redis-server.log
databases 16
# 持久化
dir /var/lib/redis
dbfilename dump.rdb
save 900 1
save 300 10
save 60 10000
rdbcompression yes
rdbchecksum yes
# AOF
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-use-rdb-preamble yes
# 内存
maxmemory 8gb
maxmemory-policy allkeys-lru
# 安全
requirepass YourStrongPassword123!
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command CONFIG ""
rename-command DEBUG ""
# 慢日志
slowlog-log-slower-than 10000
slowlog-max-len 128
# 客户端
maxclients 100002.3 Systemd 服务管理
# /etc/systemd/system/redis.service
[Unit]
Description=Redis In-Memory Data Store
After=network.target
[Service]
User=redis
Group=redis
ExecStart=/usr/local/redis/bin/redis-server /etc/redis/redis.conf
ExecStop=/usr/local/redis/bin/redis-cli -a 'YourStrongPassword123!' shutdown
Restart=always
RestartSec=3
LimitNOFILE=65535
[Install]
WantedBy=multi-user.targetsudo systemctl daemon-reload
sudo systemctl enable redis
sudo systemctl start redis
sudo systemctl status redis2.4 Docker 部署
# 单节点
docker run -d \
--name redis \
-p 6379:6379 \
-v /data/redis:/data \
-v /etc/redis/redis.conf:/etc/redis/redis.conf \
redis:7.2-alpine \
redis-server /etc/redis/redis.conf
# Docker Compose
cat > docker-compose.yml << 'EOF'
version: '3.8'
services:
redis:
image: redis:7.2-alpine
container_name: redis
ports:
- "6379:6379"
volumes:
- redis-data:/data
- ./redis.conf:/etc/redis/redis.conf
command: redis-server /etc/redis/redis.conf
restart: always
sysctls:
net.core.somaxconn: 1024
volumes:
redis-data:
EOF2.5 内核参数优化
# /etc/sysctl.conf
vm.overcommit_memory = 1
net.core.somaxconn = 1024
vm.swappiness = 1
# 禁用 THP(Transparent Huge Pages)
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
# 文件描述符限制
# /etc/security/limits.conf
redis soft nofile 65535
redis hard nofile 65535三、持久化机制
3.1 RDB 快照
RDB 通过生成内存数据的二进制快照文件来持久化数据。
工作原理:
Redis fork 出子进程
子进程将内存数据写入临时 RDB 文件
写入完成后替换旧的 RDB 文件
配置示例:
# 触发条件:满足任意一条即触发
save 900 1 # 900 秒内至少 1 次写入
save 300 10 # 300 秒内至少 10 次写入
save 60 10000 # 60 秒内至少 10000 次写入
# 压缩与校验
rdbcompression yes
rdbchecksum yes
# 文件名
dbfilename dump.rdb
dir /var/lib/redis手动触发:
# 阻塞式保存(生产慎用)
redis-cli SAVE
# 后台保存(推荐)
redis-cli BGSAVE
# 查看上次保存时间
redis-cli LASTSAVE优缺点:
✅ 文件紧凑,恢复速度快
✅ 对性能影响小(fork 子进程)
❌ 可能丢失最后一次快照后的数据
❌ 数据量大时 fork 耗时较长
3.2 AOF 日志
AOF(Append Only File)以日志追加的方式记录每个写操作。
配置示例:
appendonly yes
appendfilename "appendonly.aof"
# 同步策略
appendfsync always # 每次写入都同步(最安全,最慢)
appendfsync everysec # 每秒同步一次(推荐,最多丢 1 秒数据)
appendfsync no # 由操作系统决定(最快,但不安全)
# AOF 重写
auto-aof-rewrite-percentage 100 # 文件增长 100% 时触发重写
auto-aof-rewrite-min-size 64mb # 最小重写文件大小
# Redis 7.x: 混合持久化
aof-use-rdb-preamble yes手动触发重写:
redis-cli BGREWRITEAOFAOF 文件修复:
# 检查 AOF 文件
redis-check-aof --fix appendonly.aof3.3 混合持久化(推荐)
Redis 4.0+ 支持混合持久化,结合 RDB 和 AOF 的优点:
aof-use-rdb-preamble yes工作原理:
AOF 重写时,前半部分写入 RDB 格式(快速加载)
后半部分追加 AOF 增量日志(数据完整性)
恢复时先加载 RDB 部分,再回放 AOF 部分
3.4 持久化策略选择
场景对照:
纯缓存,丢了重填:关闭持久化,或只用 RDB
数据安全性要求高:AOF +
appendfsync everysec快速恢复 + 数据安全:混合持久化(推荐)
大数据集:RDB 为主,AOF 为辅
四、内存管理
4.1 内存分配策略
# 查看内存使用详情
redis-cli INFO memory
# 关键指标
# used_memory: Redis 分配器分配的内存总量
# used_memory_rss: 操作系统视角的内存占用
# used_memory_peak: 内存使用峰值
# mem_fragmentation_ratio: 内存碎片率(= rss / used)碎片率判断:
> 1.5:碎片严重,考虑开启activedefrag< 1.0:使用了 swap,极其危险
# 开启主动碎片整理(Redis 4.0+)
activedefrag yes
active-defrag-enabled yes
active-defrag-ignore-bytes 100mb
active-defrag-threshold-lower 10
active-defrag-threshold-upper 1004.2 内存淘汰策略
当内存达到 maxmemory 限制时,Redis 的淘汰行为:
noeviction:不淘汰,写入报错(默认)
allkeys-lru:所有 key 中淘汰最近最少使用的(推荐缓存场景)
allkeys-lfu:所有 key 中淘汰最不常用的(Redis 4.0+)
allkeys-random:所有 key 中随机淘汰
volatile-lru:有过期时间的 key 中淘汰 LRU
volatile-lfu:有过期时间的 key 中淘汰 LFU
volatile-random:有过期时间的 key 中随机淘汰
volatile-ttl:淘汰 TTL 最短的 key
# 查看当前策略
redis-cli CONFIG GET maxmemory-policy
# 设置策略
redis-cli CONFIG SET maxmemory-policy allkeys-lru
# 设置最大内存
redis-cli CONFIG SET maxmemory 8gb4.3 大 Key 排查
大 Key 是 Redis 性能杀手,会导致阻塞、网络拥塞和内存不均。
扫描大 Key:
# 使用 redis-cli 内置扫描(Redis 4.0+)
redis-cli --bigkeys
# 更精确的扫描(同时统计内存)
redis-cli --memkeys
# 使用 memory usage 命令检查单个 key
redis-cli MEMORY USAGE mykey
# 使用 debug object 查看序列化长度
redis-cli DEBUG OBJECT mykey使用脚本扫描:
#!/usr/bin/env python3
"""redis_bigkey_scan.py - 扫描 Redis 大 Key"""
import redis
r = redis.Redis(host='localhost', port=6379, password='xxx', decode_responses=True)
THRESHOLD = 1024 # 1KB
cursor = 0
while True:
cursor, keys = r.scan(cursor, count=100)
for key in keys:
key_type = r.type(key)
size = 0
if key_type == 'string':
size = r.strlen(key)
elif key_type == 'hash':
size = r.hlen(key)
elif key_type == 'list':
size = r.llen(key)
elif key_type == 'set':
size = r.scard(key)
elif key_type == 'zset':
size = r.zcard(key)
if size > THRESHOLD:
mem = r.memory_usage(key) or 0
print(f"[{key_type}] {key} -> count={size}, mem={mem/1024:.1f}KB")
if cursor == 0:
break大 Key 治理:
# 删除大 Key(不要直接 DEL!会阻塞)
# Redis 4.0+ 使用 UNLINK(异步删除)
redis-cli UNLINK bigkey
# 对于 Hash 类型,分批删除
redis-cli HSCAN myhash 0 COUNT 100
# 然后逐批 HDEL
# 对于 List 类型,分批裁剪
redis-cli LTRIM mylist 0 -1001 # 每次保留后 1000 个4.4 Key 过期策略
Redis 采用惰性删除 + 定期删除的组合策略:
# 设置过期时间
redis-cli EXPIRE mykey 3600 # 秒
redis-cli PEXPIRE mykey 3600000 # 毫秒
redis-cli EXPIREAT mykey 1735689600 # Unix 时间戳
# 查看剩余 TTL
redis-cli TTL mykey
# 取消过期
redis-cli PERSIST mykey五、主从复制
5.1 架构原理
Master (写) ──复制──> Slave 1 (读)
│
└──复制──> Slave 2 (读)复制流程:
Slave 发送 PSYNC 命令
Master 执行 BGSAVE 生成 RDB,同时记录增量命令
Master 将 RDB 发送给 Slave
Slave 加载 RDB,之后 Master 持续发送增量数据
5.2 配置主从
从节点配置:
# /etc/redis/redis-slave.conf
replicaof 192.168.1.10 6379
masterauth YourStrongPassword123!
replica-read-only yes
# 无盘复制(网络带宽充足时推荐)
repl-diskless-sync yes
repl-diskless-sync-delay 5
# 复制积压缓冲区大小
repl-backlog-size 256mb动态设置:
# 在从节点执行
redis-cli REPLICAOF 192.168.1.10 6379
redis-cli CONFIG SET masterauth 'YourStrongPassword123!'
# 取消复制,变为独立主节点
redis-cli REPLICAOF NO ONE5.3 复制状态监控
# 查看复制信息
redis-cli INFO replication
# 关键指标
# role: master/slave
# connected_slaves: 已连接的从节点数
# master_link_status: up/down(从节点视角)
# master_last_io_seconds_ago: 距上次通信秒数
# repl_backlog_active: 复制积压缓冲区是否活跃5.4 复制常见问题
问题 1:全量复制频繁
# 增大复制积压缓冲区
redis-cli CONFIG SET repl-backlog-size 512mb
# 避免 Master 重启导致 runid 变化
# 使用 redis-shake 等工具做数据迁移问题 2:复制延迟
# 检查主从偏移量差
redis-cli INFO replication | grep -E "master_repl_offset|slave.*offset"
# 开启无盘复制减少磁盘 I/O
redis-cli CONFIG SET repl-diskless-sync yes六、Redis Sentinel(哨兵)
6.1 架构概述
Sentinel 是 Redis 的高可用方案,负责监控、通知和自动故障转移。
最少部署 3 个 Sentinel 节点,采用多数投票机制。
6.2 配置文件
# /etc/redis/sentinel.conf
port 26379
daemonize yes
pidfile /var/run/redis/sentinel.pid
logfile /var/log/redis/sentinel.log
dir /var/lib/redis
# 监控主节点
sentinel monitor mymaster 192.168.1.10 6379 2
sentinel auth-pass mymaster YourStrongPassword123!
# 故障判定
sentinel down-after-milliseconds mymaster 5000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 60000
# 通知脚本
# sentinel notification-script mymaster /opt/redis/notify.sh
# 客户端重配置脚本
# sentinel client-reconfig-script mymaster /opt/redis/reconfig.sh关键参数说明:
sentinel monitor mymaster ... 2:至少 2 个 Sentinel 同意才能判定主观下线down-after-milliseconds:5 秒无响应判定主观下线failover-timeout:故障转移超时时间
6.3 Sentinel 管理
# 启动 Sentinel
redis-sentinel /etc/redis/sentinel.conf
# 或
redis-server /etc/redis/sentinel.conf --sentinel
# 连接 Sentinel
redis-cli -p 26379
# 查看主节点信息
redis-cli -p 26379 SENTINEL master mymaster
# 查看所有被监控的主节点
redis-cli -p 26379 SENTINEL masters
# 查看从节点
redis-cli -p 26379 SENTINEL replicas mymaster
# 获取当前主节点地址
redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster
# 手动触发故障转移
redis-cli -p 26379 SENTINEL failover mymaster
# 检查 Sentinel 状态
redis-cli -p 26379 SENTINEL ckquorum mymaster6.4 客户端连接方式
# Python 示例(使用 redis-py)
from redis.sentinel import Sentinel
sentinel = Sentinel([
('192.168.1.10', 26379),
('192.168.1.11', 26379),
('192.168.1.12', 26379),
], socket_timeout=0.5)
# 获取主节点连接(写)
master = sentinel.master_for('mymaster', password='YourStrongPassword123!')
master.set('key', 'value')
# 获取从节点连接(读)
slave = sentinel.slave_for('mymaster', password='YourStrongPassword123!')
slave.get('key')七、Redis Cluster(集群)
7.1 架构概述
Redis Cluster 是 Redis 的分布式方案,支持数据分片和高可用。
核心概念:
16384 个哈希槽(slot):数据通过 CRC16(key) % 16384 分配到不同节点
最少 3 主 3 从:每个主节点负责一部分槽位
Gossip 协议:节点间通信使用 Gossip 协议
MOVED/ASK 重定向:客户端自动路由到正确的节点
7.2 集群部署
# 创建 6 节点集群(3主3从)
mkdir -p /data/redis-cluster/{7001,7002,7003,7004,7005,7006}
# 生成配置文件模板
for port in 7001 7002 7003 7004 7005 7006; do
cat > /data/redis-cluster/$port/redis.conf << EOF
port $port
bind 0.0.0.0
daemonize yes
pidfile /var/run/redis/redis-$port.pid
logfile /var/log/redis/redis-$port.log
dir /data/redis-cluster/$port
dbfilename dump.rdb
appendonly yes
appendfilename "appendonly.aof"
# 集群配置
cluster-enabled yes
cluster-config-file nodes-$port.conf
cluster-node-timeout 15000
cluster-announce-ip 192.168.1.10
cluster-announce-port $port
cluster-announce-bus-port 1${port#7000}
# 安全
requirepass YourStrongPassword123!
masterauth YourStrongPassword123!
EOF
done
# 启动所有节点
for port in 7001 7002 7003 7004 7005 7006; do
redis-server /data/redis-cluster/$port/redis.conf
done
# 创建集群
redis-cli --cluster create \
192.168.1.10:7001 192.168.1.10:7002 192.168.1.10:7003 \
192.168.1.10:7004 192.168.1.10:7005 192.168.1.10:7006 \
--cluster-replicas 1 \
-a YourStrongPassword123!7.3 集群管理
# 查看集群信息
redis-cli -c -p 7001 CLUSTER INFO
redis-cli -c -p 7001 CLUSTER NODES
# 查看槽位分配
redis-cli --cluster check 192.168.1.10:7001 -a YourStrongPassword123!
# 添加主节点
redis-cli --cluster add-node 192.168.1.10:7007 192.168.1.10:7001 \
-a YourStrongPassword123!
# 添加从节点
redis-cli --cluster add-node 192.168.1.10:7008 192.168.1.10:7001 \
--cluster-slave --cluster-master-id <master-node-id> \
-a YourStrongPassword123!
# 迁移槽位
redis-cli --cluster reshard 192.168.1.10:7001 \
--cluster-from <source-node-id> \
--cluster-to <target-node-id> \
--cluster-slots 1000 \
--cluster-yes \
-a YourStrongPassword123!
# 自动均衡槽位
redis-cli --cluster rebalance 192.168.1.10:7001 \
-a YourStrongPassword123!
# 删除节点(先迁走槽位)
redis-cli --cluster del-node 192.168.1.10:7001 <node-id> \
-a YourStrongPassword123!7.4 集群故障转移
# 手动故障转移(在从节点执行)
redis-cli -p 7004 CLUSTER FAILOVER
# 强制故障转移(不等待数据同步)
redis-cli -p 7004 CLUSTER FAILOVER FORCE
# 模拟故障
redis-cli -p 7001 DEBUG SLEEP 307.5 集群注意事项
不支持跨槽的多 key 操作:使用 Hash Tag
{tag}将相关 key 分配到同一槽位批量操作要小心:MGET/MSET 的 key 必须在同一槽位
Lua 脚本的 key 必须在同一槽位
# Hash Tag 示例
SET {user:1000}.name "Alice"
SET {user:1000}.age "30"
# 这两个 key 会在同一个槽位,可以一起操作
MGET {user:1000}.name {user:1000}.age八、性能优化
8.1 Pipeline 批量操作
Pipeline 将多个命令打包发送,减少网络往返时间。
# Python 示例
import redis
r = redis.Redis(host='localhost', port=6379, decode_responses=True)
# 不使用 Pipeline(10000 次网络往返)
for i in range(10000):
r.set(f'key:{i}', f'value:{i}')
# 使用 Pipeline(1 次网络往返)
pipe = r.pipeline(transaction=False)
for i in range(10000):
pipe.set(f'key:{i}', f'value:{i}')
pipe.execute()# redis-cli 中使用 Pipeline
cat commands.txt | redis-cli --pipe
# commands.txt 格式:
# SET key1 value1
# SET key2 value28.2 Lua 脚本
Lua 脚本在 Redis 服务端原子执行,适合复杂逻辑。
# 原子递增并检查阈值
redis-cli EVAL "
local current = redis.call('INCR', KEYS[1])
if current == 1 then
redis.call('EXPIRE', KEYS[1], ARGV[1])
end
if current > tonumber(ARGV[2]) then
return 0
end
return 1
" 1 rate:api 60 100
# 限流器示例(滑动窗口)
redis-cli EVAL "
local key = KEYS[1]
local now = tonumber(ARGV[1])
local window = tonumber(ARGV[2])
local limit = tonumber(ARGV[3])
redis.call('ZREMRANGEBYSCORE', key, 0, now - window)
local count = redis.call('ZCARD', key)
if count < limit then
redis.call('ZADD', key, now, now .. ':' .. math.random())
redis.call('EXPIRE', key, window / 1000)
return 1
end
return 0
" 1 rate:sliding:api 1718000000000 60000 100脚本缓存:
# 先加载脚本获取 SHA1
redis-cli SCRIPT LOAD "return redis.call('GET', KEYS[1])"
# 返回: "e0e1f9fabfc9d4800c877a703b823ac0578ff831"
# 通过 SHA1 执行
redis-cli EVALSHA e0e1f9fabfc9d4800c877a703b823ac0578ff831 1 mykey8.3 热 Key 问题
热 Key 会导致单节点过载,常见于秒杀、热点新闻等场景。
发现热 Key:
# Redis 4.0+ 使用 LFU 策略时可查看
redis-cli --hotkeys
# 使用 MONITOR 实时分析(生产慎用,影响性能)
redis-cli MONITOR | head -10000 | awk '{print $4}' | sort | uniq -c | sort -rn | head -20
# 使用 keyspace 通知统计
redis-cli CONFIG SET notify-keyspace-events Kg$ # 仅开启 key 事件热 Key 解决方案:
# 方案 1:本地缓存(应用层)
# 在应用中使用 LRU Cache 缓存热 Key
# 方案 2:读写分离
# 从多个从节点读取
# 方案 3:Key 分片
# 将热 Key 拆分为多个子 Key
SET hotkey:1 "value"
SET hotkey:2 "value"
SET hotkey:3 "value"
# 读取时随机选择
GET hotkey:{random(1,3)}8.4 慢查询分析
# 查看慢查询日志
redis-cli SLOWLOG GET 10
# 设置慢查询阈值(微秒)
redis-cli CONFIG SET slowlog-log-slower-than 10000 # 10ms
# 查看慢查询日志长度
redis-cli SLOWLOG LEN
# 清空慢查询日志
redis-cli SLOWLOG RESET8.5 连接池优化
# Python 连接池配置
import redis
pool = redis.ConnectionPool(
host='localhost',
port=6379,
password='YourStrongPassword123!',
max_connections=50,
decode_responses=True,
socket_timeout=5,
socket_connect_timeout=5,
retry_on_timeout=True,
health_check_interval=30
)
r = redis.Redis(connection_pool=pool)九、安全配置
9.1 认证与授权
# 设置密码
redis-cli CONFIG SET requirepass YourStrongPassword123!
# Redis 6.0+ ACL
# 创建用户
redis-cli ACL SETUSER alice on >password123 ~* +@all -@dangerous
# 创建只读用户
redis-cli ACL SETUSER reader on >readpass ~* +@read
# 查看用户列表
redis-cli ACL LIST
# 保存 ACL 配置
redis-cli ACL SAVEACL 配置文件示例:
# /etc/redis/users.acl
user default off
user alice on >StrongPass1 ~* +@all -@dangerous -FLUSHALL -FLUSHDB -DEBUG
user reader on >ReadPass1 ~* +@read
user app on >AppPass1 ~app:* +@read +@write -@admin9.2 网络安全
# 绑定内网 IP
bind 127.0.0.1 192.168.1.10
# 启用保护模式
protected-mode yes
# 修改默认端口
port 16379
# 禁用危险命令
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command CONFIG "CONFIG_b93e7a2d"
rename-command DEBUG ""
rename-command KEYS ""9.3 TLS 加密
# Redis 6.0+ 支持 TLS
tls-port 6380
tls-cert-file /etc/redis/tls/redis.crt
tls-key-file /etc/redis/tls/redis.key
tls-ca-cert-file /etc/redis/tls/ca.crt
tls-auth-clients optional9.4 安全检查清单
# 1. 检查是否设置了密码
redis-cli CONFIG GET requireauth
# 2. 检查绑定地址
redis-cli CONFIG GET bind
# 3. 检查保护模式
redis-cli CONFIG GET protected-mode
# 4. 检查危险命令是否禁用
redis-cli FLUSHALL # 应该报错
# 5. 检查是否暴露在公网
nmap -p 6379 <your-ip>十、监控与告警
10.1 核心监控指标
# 获取所有信息
redis-cli INFO all
# 分类获取
redis-cli INFO server # 服务器信息
redis-cli INFO clients # 客户端连接
redis-cli INFO memory # 内存使用
redis-cli INFO stats # 统计信息
redis-cli INFO replication # 复制状态
redis-cli INFO cpu # CPU 使用
redis-cli INFO keyspace # 数据库 key 统计关键指标清单:
内存:
used_memory、used_memory_rss、mem_fragmentation_ratio连接:
connected_clients、blocked_clients、rejected_connections性能:
instantaneous_ops_per_sec、latency_percentiles命中率:
keyspace_hits、keyspace_misses(命中率 = hits / (hits + misses))持久化:
rdb_last_bgsave_status、aof_last_bgrewrite_status复制:
master_link_status、master_last_io_seconds_ago碎片:
mem_fragmentation_ratio、active_defrag_running
10.2 Prometheus + Grafana 监控
# 部署 redis_exporter
docker run -d \
--name redis_exporter \
-p 9121:9121 \
oliver006/redis_exporter \
--redis.addr redis://192.168.1.10:6379 \
--redis.password 'YourStrongPassword123!'Prometheus 配置:
# prometheus.yml
scrape_configs:
- job_name: 'redis'
static_configs:
- targets: ['192.168.1.10:9121']
metrics_path: /metricsGrafana Dashboard ID: 763(Redis Dashboard for Prometheus)
10.3 告警规则
# Prometheus 命名规则
groups:
- name: redis_alerts
rules:
# 实例宕机
- alert: RedisDown
expr: redis_up == 0
for: 1m
labels:
severity: critical
annotations:
summary: "Redis 实例 {{ $labels.instance }} 宕机"
# 内存使用过高
- alert: RedisHighMemory
expr: redis_memory_used_bytes / redis_memory_max_bytes > 0.9
for: 5m
labels:
severity: warning
annotations:
summary: "Redis 内存使用超过 90%"
# 连接数过高
- alert: RedisHighConnections
expr: redis_connected_clients > 1000
for: 5m
labels:
severity: warning
annotations:
summary: "Redis 连接数过高: {{ $value }}"
# 命中率过低
- alert: RedisLowHitRate
expr: redis_keyspace_hits_total / (redis_keyspace_hits_total + redis_keyspace_misses_total) < 0.8
for: 10m
labels:
severity: warning
annotations:
summary: "Redis 缓存命中率低于 80%"
# 复制断开
- alert: RedisReplicationBroken
expr: redis_connected_slaves < 1
for: 2m
labels:
severity: critical
annotations:
summary: "Redis 主从复制断开"
# 慢查询过多
- alert: RedisTooManySlowQueries
expr: increase(redis_slowlog_length[5m]) > 10
for: 5m
labels:
severity: warning
annotations:
summary: "Redis 5 分钟内慢查询超过 10 条"10.4 Latency 监控
# Redis 内置延迟监控
redis-cli CONFIG SET latency-monitor-threshold 5 # 5ms
# 查看延迟事件
redis-cli LATENCY LATEST
redis-cli LATENCY HISTORY command
redis-cli LATENCY RESET
# 延迟图谱
redis-cli --latency
redis-cli --latency-history
redis-cli --latency-dist十一、常见问题排查
11.1 Redis 响应变慢
排查步骤:
# 1. 查看慢查询
redis-cli SLOWLOG GET 20
# 2. 检查内存碎片
redis-cli INFO memory | grep mem_fragmentation_ratio
# 3. 检查是否在做持久化
redis-cli INFO persistence | grep -E "rdb_bgsave_in_progress|aof_rewrite_in_progress"
# 4. 检查客户端连接数
redis-cli INFO clients | grep connected_clients
# 5. 检查网络延迟
redis-cli --latency-history -i 1
# 6. 检查是否有大 Key 阻塞
redis-cli --bigkeys
# 7. 检查是否使用了 swap
redis-cli INFO memory | grep mem_allocator
# 如果 used_memory > used_memory_rss,可能在用 swap11.2 内存暴涨
# 1. 检查内存使用
redis-cli INFO memory
# 2. 查看内存增长趋势
redis-cli MEMORY STATS
# 3. 扫描大 Key
redis-cli --bigkeys
redis-cli --memkeys
# 4. 检查是否有大量过期 key 未清理
redis-cli INFO keyspace
# 如果 keys 远大于 expires,说明过期清理不及时
# 5. 检查是否有 pub/sub 泄漏
redis-cli PUBSUB CHANNELS | wc -l11.3 主从同步延迟
# 1. 检查复制状态
redis-cli INFO replication
# 2. 查看主从偏移量差
# master_repl_offset - slave_repl_offset = 延迟字节数
# 3. 检查网络带宽
iftop -i eth0
# 4. 增大复制缓冲区
redis-cli CONFIG SET repl-backlog-size 512mb
# 5. 开启无盘复制
redis-cli CONFIG SET repl-diskless-sync yes11.4 集群节点故障
# 1. 查看集群状态
redis-cli -c -p 7001 CLUSTER INFO | grep cluster_state
# cluster_state:ok 表示正常
# 2. 查看节点状态
redis-cli -c -p 7001 CLUSTER NODES | grep -v "handshake"
# 查找 fail 状态的节点
# 3. 检查故障节点
redis-cli -c -p 7001 CLUSTER NODES | grep "fail"
# 4. 尝试恢复节点
redis-cli -c -p 7001 CLUSTER RESET SOFT
# 5. 如果是网络分区,等网络恢复后节点会自动重新加入11.5 持久化导致的延迟
# 1. 检查 fork 耗时
redis-cli INFO stats | grep latest_fork_usec
# 如果 > 100ms,说明 fork 耗时过长
# 2. 减小数据集大小
# 分片或清理不必要的数据
# 3. 使用 SSD 替代 HDD
# RDB 和 AOF 的写入对磁盘 I/O 要求较高
# 4. 调整 AOF 同步策略
redis-cli CONFIG SET appendfsync everysec # 替代 always十二、运维命令速查表
12.1 服务器管理
# 服务启停
systemctl start redis
systemctl stop redis
systemctl restart redis
systemctl status redis
# 热更新配置
redis-cli CONFIG SET <param> <value>
redis-cli CONFIG REWRITE # 写入配置文件
# 关闭 Redis(安全关闭)
redis-cli SHUTDOWN NOSAVE # 不保存直接关闭
redis-cli SHUTDOWN SAVE # 保存后关闭
# 查看服务器信息
redis-cli INFO [section]
redis-cli DBSIZE
redis-cli TIME
redis-cli LASTSAVE12.2 Key 操作
# 基本操作
redis-cli SET key value [EX seconds] [PX milliseconds] [NX|XX]
redis-cli GET key
redis-cli DEL key [key ...]
redis-cli UNLINK key [key ...] # 异步删除
redis-cli EXISTS key [key ...]
redis-cli TYPE key
redis-cli TTL key
redis-cli PTTL key
redis-cli EXPIRE key seconds
redis-cli PERSIST key
# 批量操作
redis-cli MSET key1 val1 key2 val2
redis-cli MGET key1 key2
# 扫描(生产替代 KEYS)
redis-cli SCAN cursor [MATCH pattern] [COUNT count] [TYPE type]
# 查看编码
redis-cli OBJECT ENCODING key
redis-cli OBJECT REFCOUNT key
redis-cli OBJECT IDLETIME key12.3 数据类型操作
# String
redis-cli INCR key / INCRBY key increment
redis-cli DECR key / DECRBY key decrement
redis-cli APPEND key value
redis-cli STRLEN key
redis-cli SETNX key value
redis-cli SETEX key seconds value
# Hash
redis-cli HSET key field value
redis-cli HGET key field
redis-cli HMSET key field1 val1 field2 val2
redis-cli HMGET key field1 field2
redis-cli HGETALL key
redis-cli HDEL key field [field ...]
redis-cli HINCRBY key field increment
redis-cli HLEN key
redis-cli HSCAN key cursor [MATCH pattern] [COUNT count]
# List
redis-cli LPUSH key value [value ...]
redis-cli RPUSH key value [value ...]
redis-cli LPOP key
redis-cli RPOP key
redis-cli LRANGE key start stop
redis-cli LLEN key
redis-cli LINDEX key index
redis-cli LSET key index value
redis-cli BLPOP key [key ...] timeout # 阻塞弹出
# Set
redis-cli SADD key member [member ...]
redis-cli SMEMBERS key
redis-cli SISMEMBER key member
redis-cli SCARD key
redis-cli SREM key member [member ...]
redis-cli SUNION key [key ...]
redis-cli SINTER key [key ...]
redis-cli SDIFF key [key ...]
redis-cli SRANDMEMBER key [count]
# Sorted Set
redis-cli ZADD key [NX|XX] [GT|LT] [CH] [INCR] score member [score member ...]
redis-cli ZRANGE key start stop [WITHSCORES]
redis-cli ZREVRANGE key start stop [WITHSCORES]
redis-cli ZSCORE key member
redis-cli ZRANK key member
redis-cli ZREVRANK key member
redis-cli ZCARD key
redis-cli ZCOUNT key min max
redis-cli ZINCRBY key increment member
redis-cli ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]12.4 事务与发布订阅
# 事务
redis-cli MULTI
redis-cli EXEC
redis-cli DISCARD
redis-cli WATCH key [key ...]
redis-cli UNWATCH
# 发布订阅
redis-cli PUBLISH channel message
redis-cli SUBSCRIBE channel [channel ...]
redis-cli PSUBSCRIBE pattern [pattern ...]
redis-cli UNSUBSCRIBE [channel [channel ...]]
# 查看订阅信息
redis-cli PUBSUB CHANNELS [pattern]
redis-cli PUBSUB NUMSUB [channel [channel ...]]12.5 调试与诊断
# 延迟诊断
redis-cli --latency # 实时延迟
redis-cli --latency-history # 延迟历史
redis-cli --latency-dist # 延迟分布
redis-cli --intrinsic-latency 100 # 系统固有延迟(100秒)
# 内部延迟
redis-cli LATENCY LATEST
redis-cli LATENCY HISTORY event
redis-cli LATENCY RESET
# 监控命令(生产慎用)
redis-cli MONITOR # 实时打印所有命令
redis-cli SLOWLOG GET 20 # 慢查询
redis-cli SLOWLOG LEN
redis-cli SLOWLOG RESET
# 内存分析
redis-cli MEMORY DOCTOR
redis-cli MEMORY STATS
redis-cli MEMORY USAGE key [SAMPLES count]
redis-cli MEMORY PURGE
redis-cli MEMORY MALLOC-STATS
# 客户端管理
redis-cli CLIENT LIST
redis-cli CLIENT GETNAME
redis-cli CLIENT SETNAME myconn
redis-cli CLIENT KILL ID <id>
redis-cli CLIENT PAUSE timeout [ALL|WRITE]12.6 备份与恢复
# RDB 备份
redis-cli BGSAVE
cp /var/lib/redis/dump.rdb /backup/dump-$(date +%Y%m%d).rdb
# AOF 备份
cp /var/lib/redis/appendonly.aof /backup/appendonly-$(date +%Y%m%d).aof
# 恢复(停止 Redis → 替换文件 → 启动)
systemctl stop redis
cp /backup/dump-20260610.rdb /var/lib/redis/dump.rdb
# 或
cp /backup/appendonly-20260610.aof /var/lib/redis/appendonly.aof
systemctl start redis
# RDB 文件检查
redis-check-rdb /var/lib/redis/dump.rdb
# AOF 文件检查与修复
redis-check-aof --fix /var/lib/redis/appendonly.aof12.7 数据迁移
# 使用 redis-shake 迁移
# 下载: https://github.com/tair-opensource/RedisShake
# 全量 + 增量同步配置
cat > shake.toml << 'EOF'
[source]
type = "standalone"
address = "192.168.1.10:6379"
password = "OldPassword"
[target]
type = "standalone"
address = "192.168.1.20:6379"
password = "NewPassword"
[advanced]
dir = "./data"
ncpu = 4
EOF
./redis-shake shake.toml附录:Redis 版本选择建议
Redis 7.2.x:最新稳定版,推荐新项目使用
Redis 7.0.x:成熟稳定,推荐生产环境
Redis 6.2.x:仍广泛使用,ACL 和 TLS 支持完善
Redis 6.0.x:支持 ACL、TLS、多线程 I/O
Redis 5.x:旧版本,建议升级
升级注意事项:
先在测试环境验证兼容性
备份数据后再升级
主从架构中先升级从节点,最后升级主节点
集群架构中逐节点滚动升级