1 环境准备
1.1 系统要求
- 操作系统:Linux (推荐 Ubuntu 20.04+ 或 CentOS 7+)
- 内存:至少 2GB
- Redis 版本:6.x 或 7.x
1.2 安装 Redis
Ubuntu/Debian 系统
# 更新包管理器
sudo apt update
# 安装 Redis
sudo apt install redis-server -y
# 或者从源码编译最新版本
wget https://download.redis.io/redis-stable.tar.gz
tar -xzf redis-stable.tar.gz
cd redis-stable
make
sudo make install
CentOS/RHEL 系统
# 安装 EPEL 仓库
sudo yum install epel-release -y
# 安装 Redis
sudo yum install redis -y
# 或使用 dnf (CentOS 8+)
sudo dnf install redis -y
macOS 系统
# 使用 Homebrew 安装
brew install redis
# 或者使用 MacPorts
sudo port install redis
1.3 Redis 安装验证和故障排除
# 创建 Redis 安装检查脚本
cat > ~/redis-practice/check-redis-installation.sh << 'EOF'
#!/bin/bash
echo "=== Redis 安装状态检查 ==="
# 检查 redis-server
if command -v redis-server >/dev/null 2>&1; then
echo "✅ redis-server 已安装: $(which redis-server)"
redis-server --version
else
echo "❌ redis-server 未找到"
REDIS_MISSING=1
fi
# 检查 redis-cli
if command -v redis-cli >/dev/null 2>&1; then
echo "✅ redis-cli 已安装: $(which redis-cli)"
else
echo "❌ redis-cli 未找到"
REDIS_MISSING=1
fi
# 检查 redis-sentinel
if command -v redis-sentinel >/dev/null 2>&1; then
echo "✅ redis-sentinel 已安装: $(which redis-sentinel)"
else
echo "⚠️ redis-sentinel 未找到,将使用 redis-server --sentinel 模式"
if command -v redis-server >/dev/null 2>&1; then
echo "✅ 可以使用 redis-server --sentinel 启动哨兵"
else
REDIS_MISSING=1
fi
fi
if [ "$REDIS_MISSING" = "1" ]; then
echo ""
echo "❌ Redis 未正确安装,请选择以下安装方式:"
echo ""
echo "Ubuntu/Debian:"
echo " sudo apt update && sudo apt install redis-server -y"
echo ""
echo "CentOS/RHEL:"
echo " sudo yum install epel-release -y && sudo yum install redis -y"
echo ""
echo "macOS:"
echo " brew install redis"
echo ""
echo "从源码编译:"
echo " wget https://download.redis.io/redis-stable.tar.gz"
echo " tar -xzf redis-stable.tar.gz"
echo " cd redis-stable && make && sudo make install"
echo ""
exit 1
else
echo ""
echo "✅ Redis 安装检查完成,可以开始架构搭建实践"
fi
EOF
chmod +x ~/redis-practice/check-redis-installation.sh
# 运行安装检查
~/redis-practice/check-redis-installation.sh
1.4 创建工作目录
mkdir -p ~/redis-practice
cd ~/redis-practice
mkdir -p {master-slave,cluster,sentinel}/{conf,data,logs}
1.5 Redis 版本兼容性检查
# 创建版本兼容性检查脚本
cat > ~/redis-practice/check-redis-version.sh << 'EOF'
#!/bin/bash
echo "=== Redis 版本检查 ==="
REDIS_VERSION=$(redis-server --version | grep -oE "[0-9]+\.[0-9]+" | head -1)
echo "检测到 Redis 版本: $REDIS_VERSION"
MAJOR_VERSION=$(echo $REDIS_VERSION | cut -d. -f1)
MINOR_VERSION=$(echo $REDIS_VERSION | cut -d. -f2)
echo "主版本号: $MAJOR_VERSION, 次版本号: $MINOR_VERSION"
if [ $MAJOR_VERSION -ge 5 ]; then
echo "✅ Redis 5.0+ 版本,支持 replica-* 指令"
echo "建议使用: replicaof, replica-serve-stale-data, replica-read-only"
else
echo "⚠️ Redis 4.x 版本,需要使用 slave-* 指令"
echo "必须使用: slaveof, slave-serve-stale-data, slave-read-only"
fi
echo ""
echo "当前指南已针对 Redis 4.x 兼容性进行配置"
echo "如果您使用 Redis 5.0+,配置文件仍然有效(向后兼容)"
EOF
chmod +x ~/redis-practice/check-redis-version.sh
# 运行版本检查
~/redis-practice/check-redis-version.sh
2 主从复制架构 (Master-Slave)
2.1 架构说明
- 1个主节点 (Master):负责写操作
- 2个从节点 (Slave):负责读操作,从主节点同步数据
2.2 配置文件准备
主节点配置 (redis-master.conf)
cat > ~/redis-practice/master-slave/conf/redis-master.conf << 'EOF'
# 基本配置
port 6379
bind 0.0.0.0
protected-mode no
# 数据持久化
dir /home/$(whoami)/redis-practice/master-slave/data/master
dbfilename dump-master.rdb
appendonly yes
appendfilename "appendonly-master.aof"
# 日志配置
logfile /home/$(whoami)/redis-practice/master-slave/logs/redis-master.log
loglevel notice
# 主从复制配置
# 允许从节点连接 (Redis 5.0+ 使用 replica-*, 4.0 使用 slave-*)
replica-serve-stale-data yes
replica-read-only yes
# 安全配置
requirepass redis123
masterauth redis123
# 性能优化
maxmemory 256mb
maxmemory-policy allkeys-lru
EOF
从节点1配置 (redis-slave1.conf)
cat > ~/redis-practice/master-slave/conf/redis-slave1.conf << 'EOF'
# 基本配置
port 6380
bind 0.0.0.0
protected-mode no
# 数据持久化
dir /home/$(whoami)/redis-practice/master-slave/data/slave1
dbfilename dump-slave1.rdb
appendonly yes
appendfilename "appendonly-slave1.aof"
# 日志配置
logfile /home/$(whoami)/redis-practice/master-slave/logs/redis-slave1.log
loglevel notice
# 主从复制配置
replicaof 127.0.0.1 6379
replica-serve-stale-data yes
replica-read-only yes
# 安全配置
requirepass redis123
masterauth redis123
# 性能优化
maxmemory 256mb
maxmemory-policy allkeys-lru
EOF
从节点2配置 (redis-slave2.conf)
cat > ~/redis-practice/master-slave/conf/redis-slave2.conf << 'EOF'
# 基本配置
port 6381
bind 0.0.0.0
protected-mode no
# 数据持久化
dir /home/$(whoami)/redis-practice/master-slave/data/slave2
dbfilename dump-slave2.rdb
appendonly yes
appendfilename "appendonly-slave2.aof"
# 日志配置
logfile /home/$(whoami)/redis-practice/master-slave/logs/redis-slave2.log
loglevel notice
# 主从复制配置
replicaof 127.0.0.1 6379
replica-serve-stale-data yes
replica-read-only yes
# 安全配置
requirepass redis123
masterauth redis123
# 性能优化
maxmemory 256mb
maxmemory-policy allkeys-lru
EOF
2.3 关键命令详解
在使用脚本之前,让我们先了解主从复制的核心命令:
Redis 主从复制核心命令
# 1. 启动 Redis 服务器的基本命令
redis-server [配置文件路径] # 启动Redis服务器
redis-server --port 6379 # 指定端口启动
redis-server --daemonize yes # 后台运行模式
# 2. 主从复制配置命令
# 在从节点上执行,建立主从关系
REPLICAOF 127.0.0.1 6379 # Redis 5.0+ 建立主从关系
SLAVEOF 127.0.0.1 6379 # Redis 4.x 建立主从关系
SLAVEOF NO ONE # 取消主从关系,提升为主节点
# 3. 认证命令
AUTH redis123 # 客户端认证
CONFIG SET masterauth redis123 # 设置主节点认证密码
CONFIG SET requirepass redis123 # 设置访问密码
# 4. 复制状态查看命令
INFO replication # 查看复制状态信息
INFO server # 查看服务器信息
PING # 测试连接
# 5. 数据同步相关
PSYNC <replication_id> <offset> # 部分重同步命令(内部使用)
FULLRESYNC # 全量重同步(内部使用)
# 6. 配置文件中的关键参数
# replicaof <masterip> <masterport> # 指定主节点
# replica-read-only yes # 从节点只读
# replica-serve-stale-data yes # 从节点在连接断开时是否提供旧数据
# repl-diskless-sync no # 是否使用无盘复制
# repl-diskless-sync-delay 5 # 无盘复制延迟时间
手动建立主从复制示例
# 1. 启动主节点(端口6379)
redis-server --port 6379 --requirepass redis123 --masterauth redis123 \
--dir /tmp/master --dbfilename master.rdb \
--logfile /tmp/master.log --daemonize yes
# 2. 启动从节点1(端口6380)
redis-server --port 6380 --requirepass redis123 --masterauth redis123 \
--dir /tmp/slave1 --dbfilename slave1.rdb \
--logfile /tmp/slave1.log --daemonize yes
# 3. 在从节点建立主从关系
redis-cli -p 6380 -a redis123 REPLICAOF 127.0.0.1 6379
# 4. 验证主从状态
redis-cli -p 6379 -a redis123 INFO replication # 查看主节点状态
redis-cli -p 6380 -a redis123 INFO replication # 查看从节点状态
# 5. 测试数据同步
redis-cli -p 6379 -a redis123 SET test_key "hello world" # 主节点写入
redis-cli -p 6380 -a redis123 GET test_key # 从节点读取
# 6. 停止服务
redis-cli -p 6379 -a redis123 SHUTDOWN # 关闭主节点
redis-cli -p 6380 -a redis123 SHUTDOWN # 关闭从节点
启动主从架构
# 创建启动脚本
cat > ~/redis-practice/master-slave/start-master-slave.sh << 'EOF'
#!/bin/bash
BASE_DIR=~/redis-practice/master-slave
echo "=== 启动 Redis 主从架构 ==="
# 创建数据目录
echo "创建数据目录..."
mkdir -p $BASE_DIR/data/{master,slave1,slave2}
# 检查配置文件是否存在
for conf in redis-master.conf redis-slave1.conf redis-slave2.conf; do
if [ ! -f "$BASE_DIR/conf/$conf" ]; then
echo "错误: 配置文件 $conf 不存在!"
exit 1
fi
done
# 启动主节点
echo "启动主节点 (端口 6379)..."
redis-server $BASE_DIR/conf/redis-master.conf &
MASTER_PID=$!
# 等待主节点启动
sleep 3
if ! redis-cli -p 6379 -a redis123 ping >/dev/null 2>&1; then
echo "错误: 主节点启动失败!"
exit 1
fi
echo "✅ 主节点启动成功 (PID: $MASTER_PID)"
# 启动从节点1
echo "启动从节点1 (端口 6380)..."
redis-server $BASE_DIR/conf/redis-slave1.conf &
SLAVE1_PID=$!
sleep 2
if ! redis-cli -p 6380 -a redis123 ping >/dev/null 2>&1; then
echo "错误: 从节点1启动失败!"
exit 1
fi
echo "✅ 从节点1启动成功 (PID: $SLAVE1_PID)"
# 启动从节点2
echo "启动从节点2 (端口 6381)..."
redis-server $BASE_DIR/conf/redis-slave2.conf &
SLAVE2_PID=$!
sleep 2
if ! redis-cli -p 6381 -a redis123 ping >/dev/null 2>&1; then
echo "错误: 从节点2启动失败!"
exit 1
fi
echo "✅ 从节点2启动成功 (PID: $SLAVE2_PID)"
# 等待主从同步
echo "等待主从同步..."
sleep 5
# 验证主从关系
echo "=== 验证主从复制状态 ==="
echo "主节点信息:"
redis-cli -p 6379 -a redis123 info replication | grep -E "role|connected_slaves"
echo "\n从节点1信息:"
redis-cli -p 6380 -a redis123 info replication | grep -E "role|master_host|master_port"
echo "\n从节点2信息:"
redis-cli -p 6381 -a redis123 info replication | grep -E "role|master_host|master_port"
echo "\n=== 主从架构启动完成!==="
echo "主节点: 127.0.0.1:6379"
echo "从节点1: 127.0.0.1:6380"
echo "从节点2: 127.0.0.1:6381"
echo "密码: redis123"
# 保存进程ID
echo "$MASTER_PID $SLAVE1_PID $SLAVE2_PID" > $BASE_DIR/redis-pids.txt
EOF
chmod +x ~/redis-practice/master-slave/start-master-slave.sh
# 运行启动脚本
~/redis-practice/master-slave/start-master-slave.sh
停止主从架构
# 创建停止脚本
cat > ~/redis-practice/master-slave/stop-master-slave.sh << 'EOF'
#!/bin/bash
BASE_DIR=~/redis-practice/master-slave
echo "=== 停止 Redis 主从架构 ==="
# 优雅关闭 Redis 实例
echo "正在停止 Redis 实例..."
for port in 6379 6380 6381; do
if redis-cli -p $port -a redis123 ping >/dev/null 2>&1; then
echo "停止端口 $port 上的 Redis 实例"
redis-cli -p $port -a redis123 shutdown
else
echo "端口 $port 上没有运行的 Redis 实例"
fi
done
# 等待进程结束
sleep 2
# 检查是否还有残留进程
REMAINING=$(ps aux | grep -E "redis-server.*master-slave" | grep -v grep | wc -l)
if [ $REMAINING -gt 0 ]; then
echo "强制终止残留进程..."
pkill -f "redis-server.*master-slave"
fi
# 清理 PID 文件
if [ -f "$BASE_DIR/redis-pids.txt" ]; then
rm $BASE_DIR/redis-pids.txt
fi
echo "✅ 主从架构已停止"
EOF
chmod +x ~/redis-practice/master-slave/stop-master-slave.sh
主从架构管理命令
# 启动主从架构
~/redis-practice/master-slave/start-master-slave.sh
# 停止主从架构
~/redis-practice/master-slave/stop-master-slave.sh
# 重启主从架构
~/redis-practice/master-slave/stop-master-slave.sh && sleep 2 && ~/redis-practice/master-slave/start-master-slave.sh
2.4 验证主从复制
# 连接主节点并写入数据
redis-cli -p 6379 -a redis123 set test-key "hello from master"
# 在从节点验证数据同步
redis-cli -p 6380 -a redis123 get test-key
redis-cli -p 6381 -a redis123 get test-key
# 查看复制状态
redis-cli -p 6379 -a redis123 info replication
2.5 测试读写分离
# 主节点写入测试
redis-cli -p 6379 -a redis123 << 'EOF'
set user:1 "张三"
set user:2 "李四"
hmset product:1 name "iPhone" price 8999
EOF
# 从节点读取测试
echo "从 slave1 读取数据:"
redis-cli -p 6380 -a redis123 get user:1
redis-cli -p 6380 -a redis123 hgetall product:1
echo "从 slave2 读取数据:"
redis-cli -p 6381 -a redis123 get user:2
3 Redis Cluster 集群架构
- 6个节点:3个主节点 + 3个从节点
- 每个主节点负责一部分槽位 (0-16383)
- 自动故障转移和数据分片
3.1 Redis Cluster 核心命令详解
在使用脚本创建集群之前,让我们先了解集群的核心命令:
Cluster 管理命令
# 1. 集群创建命令
# Redis 5.0+ 使用 redis-cli
redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 \
127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 \
--cluster-replicas 1 -a redis123
# Redis 4.x 使用 redis-trib.rb
redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 \
127.0.0.1:7002 127.0.0.1:7003 \
127.0.0.1:7004 127.0.0.1:7005
# 2. 集群状态查看命令
CLUSTER NODES # 查看所有节点信息
CLUSTER INFO # 查看集群整体状态
CLUSTER SLOTS # 查看槽位分配情况
INFO cluster # 查看集群相关信息
# 3. 集群节点管理
CLUSTER MEET <ip> <port> # 添加节点到集群
CLUSTER FORGET <node-id> # 从集群中移除节点
CLUSTER REPLICATE <node-id> # 设置当前节点为指定节点的从节点
CLUSTER RESET [HARD|SOFT] # 重置节点集群状态
# 4. 槽位管理命令
CLUSTER ADDSLOTS <slot> [slot ...] # 为节点分配槽位
CLUSTER DELSLOTS <slot> [slot ...] # 删除节点的槽位
CLUSTER SETSLOT <slot> NODE <node-id> # 将槽位分配给指定节点
CLUSTER SETSLOT <slot> MIGRATING <destination-node-id> # 开始迁移槽位
CLUSTER SETSLOT <slot> IMPORTING <source-node-id> # 准备接收槽位
# 5. 数据迁移命令
CLUSTER GETKEYSINSLOT <slot> <count> # 获取槽位中的键
MIGRATE <host> <port> <key> <destination-db> <timeout> # 迁移单个键
# 6. 集群配置文件关键参数
# cluster-enabled yes # 启用集群模式
# cluster-config-file nodes.conf # 集群配置文件
# cluster-node-timeout 15000 # 节点超时时间
# cluster-announce-ip 127.0.0.1 # 对外公布的IP
# cluster-announce-port 7000 # 对外公布的端口
# cluster-require-full-coverage no # 是否要求全部槽位可用
手动创建集群示例
# 1. 启动所有节点(不组成集群)
for port in 7000 7001 7002 7003 7004 7005; do
redis-server --port $port --cluster-enabled yes \
--cluster-config-file nodes-$port.conf \
--cluster-node-timeout 5000 \
--requirepass redis123 --masterauth redis123 \
--daemonize yes --dir /tmp/cluster-$port
done
# 2. 手动组建集群(逐步建立)
# 第一步:让节点相互认识
redis-cli -p 7000 -a redis123 CLUSTER MEET 127.0.0.1 7001
redis-cli -p 7000 -a redis123 CLUSTER MEET 127.0.0.1 7002
redis-cli -p 7000 -a redis123 CLUSTER MEET 127.0.0.1 7003
redis-cli -p 7000 -a redis123 CLUSTER MEET 127.0.0.1 7004
redis-cli -p 7000 -a redis123 CLUSTER MEET 127.0.0.1 7005
# 第二步:分配槽位(共 16384 个槽位,编号 0-16383)
redis-cli -p 7000 -a redis123 CLUSTER ADDSLOTS {0..5461} # 节点 7000
redis-cli -p 7001 -a redis123 CLUSTER ADDSLOTS {5462..10922} # 节点 7001
redis-cli -p 7002 -a redis123 CLUSTER ADDSLOTS {10923..16383} # 节点 7002
# 第三步:设置主从关系(需要先获取节点 ID)
NODE_7000=$(redis-cli -p 7000 -a redis123 CLUSTER NODES | grep myself | awk '{print $1}')
NODE_7001=$(redis-cli -p 7001 -a redis123 CLUSTER NODES | grep myself | awk '{print $1}')
NODE_7002=$(redis-cli -p 7002 -a redis123 CLUSTER NODES | grep myself | awk '{print $1}')
# 设置 7003 为 7000 的从节点
redis-cli -p 7003 -a redis123 CLUSTER REPLICATE $NODE_7000
# 设置 7004 为 7001 的从节点
redis-cli -p 7004 -a redis123 CLUSTER REPLICATE $NODE_7001
# 设置 7005 为 7002 的从节点
redis-cli -p 7005 -a redis123 CLUSTER REPLICATE $NODE_7002
# 3. 验证集群状态
redis-cli -c -p 7000 -a redis123 CLUSTER NODES
redis-cli -c -p 7000 -a redis123 CLUSTER INFO
# 4. 测试数据分片(使用 -c 参数启用集群模式)
redis-cli -c -p 7000 -a redis123 SET user:1001 "Alice"
redis-cli -c -p 7000 -a redis123 SET user:1002 "Bob"
redis-cli -c -p 7000 -a redis123 GET user:1001
redis-cli -c -p 7000 -a redis123 GET user:1002
# 5. 查看键的槽位分布
redis-cli -c -p 7000 -a redis123 CLUSTER KEYSLOT user:1001
redis-cli -c -p 7000 -a redis123 CLUSTER KEYSLOT user:1002
3.2 集群节点配置
创建集群配置模板
# 创建集群配置生成脚本
cat > ~/redis-practice/cluster/create-cluster-configs.sh << 'EOF'
#!/bin/bash
BASE_DIR=~/redis-practice/cluster
PORTS=(7000 7001 7002 7003 7004 7005)
for port in "${PORTS[@]}"; do
mkdir -p $BASE_DIR/data/node-$port
cat > $BASE_DIR/conf/redis-$port.conf << CONFIG
# 基本配置
port $port
bind 0.0.0.0
protected-mode no
# 集群配置
cluster-enabled yes
cluster-config-file $BASE_DIR/data/node-$port/nodes-$port.conf
cluster-node-timeout 15000
cluster-announce-ip 127.0.0.1
cluster-announce-port $port
# 数据持久化
dir $BASE_DIR/data/node-$port
dbfilename dump-$port.rdb
appendonly yes
appendfilename "appendonly-$port.aof"
# 日志配置
logfile $BASE_DIR/logs/redis-$port.log
loglevel notice
# 安全配置
requirepass redis123
masterauth redis123
# 性能配置
maxmemory 256mb
maxmemory-policy allkeys-lru
CONFIG
done
echo "集群配置文件生成完成!"
EOF
chmod +x ~/redis-practice/cluster/create-cluster-configs.sh
~/redis-practice/cluster/create-cluster-configs.sh
3.3 启动集群节点
# 启动所有集群节点
cd ~/redis-practice/cluster
for port in 7000 7001 7002 7003 7004 7005; do
echo "启动节点 $port"
redis-server conf/redis-$port.conf &
sleep 1
done
# 等待所有节点启动
sleep 5
echo "所有节点启动完成"
3.4 创建集群
# 创建集群 (Redis 5.0+ 使用 redis-cli)
redis-cli --cluster create \
127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 \
127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 \
--cluster-replicas 1 \
-a redis123
# 如果是 Redis 4.x,使用 redis-trib.rb
# redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 ...
3.5 验证集群状态
# 查看集群信息
redis-cli -c -p 7000 -a redis123 cluster info
redis-cli -c -p 7000 -a redis123 cluster nodes
# 测试集群数据分片
redis-cli -c -p 7000 -a redis123 << 'EOF'
set name "Redis集群测试"
set age 25
set city "北京"
get name
get age
get city
EOF
3.6 集群管理操作
# 创建集群管理脚本
cat > ~/redis-practice/cluster/cluster-manager.sh << 'EOF'
#!/bin/bash
REDIS_PASSWORD="redis123"
case $1 in
"status")
echo "=== 集群状态 ==="
redis-cli -c -p 7000 -a $REDIS_PASSWORD cluster info
echo ""
echo "=== 节点信息 ==="
redis-cli -c -p 7000 -a $REDIS_PASSWORD cluster nodes
;;
"test")
echo "=== 测试数据写入 ==="
for i in {1..10}; do
redis-cli -c -p 7000 -a $REDIS_PASSWORD set "test:$i" "value-$i"
done
echo "=== 测试数据读取 ==="
for i in {1..10}; do
redis-cli -c -p 7000 -a $REDIS_PASSWORD get "test:$i"
done
;;
"shutdown")
echo "=== 关闭集群 ==="
for port in 7000 7001 7002 7003 7004 7005; do
redis-cli -p $port -a $REDIS_PASSWORD shutdown
done
;;
*)
echo "用法: $0 {status|test|shutdown}"
;;
esac
EOF
chmod +x ~/redis-practice/cluster/cluster-manager.sh
# 测试集群
~/redis-practice/cluster/cluster-manager.sh status
~/redis-practice/cluster/cluster-manager.sh test
4 Redis Sentinel 哨兵架构
4.1 Redis Sentinel 核心命令详解
在使用 Sentinel 脚本之前,让我们先了解 Sentinel 的核心命令:
Sentinel 管理命令
# 1. 启动 Sentinel 服务
redis-sentinel sentinel.conf # 使用配置文件启动
redis-server sentinel.conf --sentinel # 更新的启动方式
# 2. Sentinel 监控命令
SENTINEL MASTERS # 查看所有被监控的主节点
SENTINEL MASTER mymaster # 查看指定主节点的详细信息
SENTINEL SLAVES mymaster # 查看主节点下的所有从节点
SENTINEL SENTINELS mymaster # 查看监控同一主节点的其他 Sentinel
SENTINEL GET-MASTER-ADDR-BY-NAME mymaster # 获取主节点地址
# 3. 故障转移命令
SENTINEL FAILOVER mymaster # 手动触发故障转移
SENTINEL CKQUORUM mymaster # 检查故障转移条件
SENTINEL FLUSHCONFIG # 刷新配置到磁盘
# 4. 动态配置修改
SENTINEL MONITOR mymaster 127.0.0.1 6379 2 # 动态添加监控
SENTINEL REMOVE mymaster # 移除监控
SENTINEL SET mymaster down-after-milliseconds 10000 # 修改参数
# 5. 信息查询
SENTINEL PENDING-SCRIPTS # 查看待执行的脚本
SENTINEL IS-MASTER-DOWN-BY-ADDR 127.0.0.1 6379 # 查询主节点是否下线
INFO sentinel # 查看 Sentinel 状态信息
# 6. Sentinel 配置文件关键参数
# sentinel monitor <master-name> <ip> <port> <quorum>
# sentinel auth-pass <master-name> <password>
# sentinel down-after-milliseconds <master-name> <milliseconds>
# sentinel parallel-syncs <master-name> <numreplicas>
# sentinel failover-timeout <master-name> <milliseconds>
# sentinel notification-script <master-name> <script-path>
# sentinel client-reconfig-script <master-name> <script-path>
手动配置 Sentinel 示例
# 1. 准备主从架构(先启动 Redis 主从节点)
redis-server --port 6379 --requirepass redis123 --masterauth redis123 --daemonize yes
redis-server --port 6380 --requirepass redis123 --masterauth redis123 --daemonize yes
redis-cli -p 6380 -a redis123 REPLICAOF 127.0.0.1 6379
# 2. 创建 Sentinel 配置文件
cat > /tmp/sentinel-26379.conf << EOF
port 26379
dir /tmp
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel auth-pass mymaster redis123
sentinel down-after-milliseconds mymaster 5000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 10000
requirepass sentinel123
EOF
# 3. 启动 Sentinel
redis-sentinel /tmp/sentinel-26379.conf &
# 4. 连接 Sentinel 并查看状态
redis-cli -p 26379 -a sentinel123
> SENTINEL MASTERS
> SENTINEL SLAVES mymaster
# 5. 模拟主节点故障(关闭主节点)
redis-cli -p 6379 -a redis123 DEBUG SEGFAULT # 模拟崩溃
# 或者
redis-cli -p 6379 -a redis123 SHUTDOWN # 正常关闭
# 6. 观察 Sentinel 日志,查看故障转移过程
tail -f /tmp/sentinel-26379.log
# 7. 查看新的主节点
redis-cli -p 26379 -a sentinel123 SENTINEL GET-MASTER-ADDR-BY-NAME mymaster
# 8. 测试新主节点是否可写入
NEW_MASTER_PORT=$(redis-cli -p 26379 -a sentinel123 SENTINEL GET-MASTER-ADDR-BY-NAME mymaster | tail -1)
redis-cli -p $NEW_MASTER_PORT -a redis123 SET failover-test "success"
Sentinel 客户端连接示例
# Python 使用 Sentinel 的示例代码
cat > sentinel_client_example.py << 'EOF'
from redis.sentinel import Sentinel
# 连接 Sentinel
sentinel = Sentinel([('127.0.0.1', 26379), ('127.0.0.1', 26380)],
socket_timeout=0.1,
password='sentinel123')
# 发现主节点
master = sentinel.master_for('mymaster', socket_timeout=0.1, password='redis123')
# 发现从节点
slave = sentinel.slave_for('mymaster', socket_timeout=0.1, password='redis123')
# 使用
master.set('foo', 'bar')
print(slave.get('foo'))
EOF
# Java 使用 Sentinel 的示例代码
cat > SentinelExample.java << 'EOF'
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisSentinelPool;
import java.util.HashSet;
import java.util.Set;
public class SentinelExample {
public static void main(String[] args) {
Set<String> sentinels = new HashSet<>();
sentinels.add("127.0.0.1:26379");
sentinels.add("127.0.0.1:26380");
JedisSentinelPool pool = new JedisSentinelPool("mymaster", sentinels, "redis123");
try (Jedis jedis = pool.getResource()) {
jedis.set("test", "value");
System.out.println(jedis.get("test"));
}
pool.close();
}
}
EOF
4.2 架构说明
- 1个主节点 + 2个从节点
- 3个 Sentinel 哨兵节点监控主从节点
- 自动故障发现和主从切换
准备 Redis 主从节点
# 复用主从架构的配置,但需要修改一些参数
cp ~/redis-practice/master-slave/conf/* ~/redis-practice/sentinel/conf/
# 修改主节点配置以适配 Sentinel
cat > ~/redis-practice/sentinel/conf/redis-master.conf << 'EOF'
port 6379
bind 0.0.0.0
protected-mode no
dir /home/$(whoami)/redis-practice/sentinel/data/master
dbfilename dump-master.rdb
appendonly yes
appendfilename "appendonly-master.aof"
logfile /home/$(whoami)/redis-practice/sentinel/logs/redis-master.log
loglevel notice
# Sentinel 需要的配置
slave-serve-stale-data yes
slave-read-only yes
slave-priority 100
requirepass redis123
masterauth redis123
maxmemory 256mb
maxmemory-policy allkeys-lru
EOF
# 修改从节点配置
sed 's|master-slave|sentinel|g' ~/redis-practice/master-slave/conf/redis-slave1.conf > ~/redis-practice/sentinel/conf/redis-slave1.conf
sed 's|master-slave|sentinel|g' ~/redis-practice/master-slave/conf/redis-slave2.conf > ~/redis-practice/sentinel/conf/redis-slave2.conf
配置 Sentinel 哨兵
# 创建 Sentinel 配置
for i in 1 2 3; do
port=$((26378 + i))
cat > ~/redis-practice/sentinel/conf/sentinel-$i.conf << EOF
# Sentinel 基本配置
port $port
bind 0.0.0.0
protected-mode no
# 工作目录
dir /home/$(whoami)/redis-practice/sentinel/data/sentinel-$i
# 日志配置
logfile /home/$(whoami)/redis-practice/sentinel/logs/sentinel-$i.log
loglevel notice
# 监控主节点配置
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel auth-pass mymaster redis123
# 故障检测配置
sentinel down-after-milliseconds mymaster 5000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 10000
# Sentinel 认证
requirepass sentinel123
# 通知脚本 (可选)
# sentinel notification-script mymaster /path/to/notify.sh
# sentinel client-reconfig-script mymaster /path/to/reconfig.sh
EOF
mkdir -p ~/redis-practice/sentinel/data/sentinel-$i
done
4.3 启动 Sentinel 架构
# 创建修复版本的启动脚本
cat > ~/redis-practice/sentinel/start-sentinel-cluster.sh << 'EOF'
#!/bin/bash
BASE_DIR=~/redis-practice/sentinel
echo '=== 检查Redis安装状态 ==='
# 检查Redis是否安装
if ! command -v redis-server >/dev/null 2>&1; then
echo '错误: redis-server 命令未找到!'
echo '请先安装Redis:'
echo ' Ubuntu/Debian: sudo apt install redis-server -y'
echo ' CentOS/RHEL: sudo yum install redis -y'
echo ' macOS: brew install redis'
exit 1
fi
# 检查sentinel启动方式
SENTINEL_CMD=""
if command -v redis-sentinel >/dev/null 2>&1; then
SENTINEL_CMD='redis-sentinel'
echo '✅ 使用 redis-sentinel 命令启动哨兵'
else
SENTINEL_CMD='redis-server --sentinel'
echo '⚠️ redis-sentinel 命令不存在,使用 redis-server --sentinel 模式'
fi
echo "=== 创建数据目录 ==="
mkdir -p $BASE_DIR/data/{master,slave1,slave2}
echo "=== 启动 Redis 主从节点 ==="
redis-server $BASE_DIR/conf/redis-master.conf &
sleep 2
redis-server $BASE_DIR/conf/redis-slave1.conf &
redis-server $BASE_DIR/conf/redis-slave2.conf &
echo "=== 等待主从同步 ==="
sleep 5
# 验证主从节点启动状态
echo "=== 验证主从节点状态 ==="
for port in 6379 6380 6381; do
if redis-cli -p $port -a redis123 ping >/dev/null 2>&1; then
echo "✅ Redis节点 $port 启动成功"
else
echo "❌ Redis节点 $port 启动失败"
exit 1
fi
done
echo "=== 启动 Sentinel 哨兵 ==="
for i in 1 2 3; do
port=$((26378 + i))
echo "启动 Sentinel-$i (端口$port)"
# 首先检查命令是否存在,然后启动
if command -v redis-sentinel >/dev/null 2>&1; then
echo " 使用 redis-sentinel 命令启动"
redis-sentinel $BASE_DIR/conf/sentinel-$i.conf &
elif command -v redis-server >/dev/null 2>&1; then
echo " 使用 redis-server --sentinel 模式启动"
redis-server $BASE_DIR/conf/sentinel-$i.conf --sentinel &
else
echo " 错误: 未找到 redis-sentinel 或 redis-server 命令"
echo " 请检查 Redis 是否正确安装"
exit 1
fi
sleep 2
# 验证启动状态
if redis-cli -p $port -a sentinel123 ping >/dev/null 2>&1; then
echo " ✅ Sentinel-$i 启动成功"
else
echo " ⚠️ Sentinel-$i 可能未完全启动,请稍后检查"
fi
done
echo "=== Sentinel 集群启动完成 ==="
sleep 3
# 验证Sentinel状态
echo "=== 验证 Sentinel 状态 ==="
for port in 26379 26380 26381; do
if redis-cli -p $port -a sentinel123 ping >/dev/null 2>&1; then
echo "✅ Sentinel $port 启动成功"
else
echo "⚠️ Sentinel $port 可能未完全启动,请稍等"
fi
done
sleep 2
echo "=== 查看 Sentinel 状态 ==="
redis-cli -p 26379 -a sentinel123 sentinel masters 2>/dev/null || echo "Sentinel还在初始化中,请稍后手动检查"
EOF
chmod +x ~/redis-practice/sentinel/start-sentinel-cluster.sh
手动启动方案:
# 手动启动方案
cat > ~/redis-practice/sentinel/manual-start-sentinel.sh << 'EOF'
#!/bin/bash
BASE_DIR=~/redis-practice/sentinel
echo "=== 手动启动 Sentinel 架构 ==="
# 步骤1: 启动Redis主从节点
echo "1. 启动Redis主从节点..."
redis-server $BASE_DIR/conf/redis-master.conf &
sleep 2
redis-server $BASE_DIR/conf/redis-slave1.conf &
sleep 2
redis-server $BASE_DIR/conf/redis-slave2.conf &
sleep 3
# 步骤2: 验证主从节点
echo "2. 验证主从节点状态..."
for port in 6379 6380 6381; do
if redis-cli -p $port -a redis123 ping >/dev/null 2>&1; then
echo " ✅ Redis $port: OK"
else
echo " ❌ Redis $port: 失败"
fi
done
# 步骤3: 尝试不同的Sentinel启动方式
echo "3. 启动Sentinel哨兵..."
for i in 1 2 3; do
port=$((26378 + i))
echo " 启动 Sentinel-$i (端口$port)"
# 方式1: 检查并使用redis-sentinel
if command -v redis-sentinel >/dev/null 2>&1; then
echo " 📍 检测到 redis-sentinel 命令,正在启动..."
redis-sentinel $BASE_DIR/conf/sentinel-$i.conf &
sleep 1
# 验证启动是否成功
if redis-cli -p $port -a sentinel123 ping >/dev/null 2>&1; then
echo " ✅ 使用 redis-sentinel 启动成功"
else
echo " ❌ redis-sentinel 启动失败"
fi
else
# 方式2: 使用redis-server --sentinel
echo " ⚠️ redis-sentinel 命令不存在,尝试 redis-server --sentinel"
if command -v redis-server >/dev/null 2>&1; then
redis-server $BASE_DIR/conf/sentinel-$i.conf --sentinel &
sleep 1
# 验证启动是否成功
if redis-cli -p $port -a sentinel123 ping >/dev/null 2>&1; then
echo " ✅ 使用 redis-server --sentinel 启动成功"
else
echo " ❌ redis-server --sentinel 启动失败"
fi
else
echo " ❌ redis-server 命令也不存在,无法启动 Sentinel"
fi
fi
sleep 2
done
sleep 5
# 步骤4: 验证Sentinel状态
echo "4. 验证Sentinel状态..."
for port in 26379 26380 26381; do
if redis-cli -p $port -a sentinel123 ping >/dev/null 2>&1; then
echo " ✅ Sentinel $port: OK"
else
echo " ❌ Sentinel $port: 失败"
fi
done
echo "=== 启动完成,运行以下命令检查状态 ==="
echo "redis-cli -p 26379 -a sentinel123 sentinel masters"
EOF
chmod +x ~/redis-practice/sentinel/manual-start-sentinel.sh
4.4 验证 Sentinel 功能
# 创建 Sentinel 测试脚本
cat > ~/redis-practice/sentinel/test-sentinel.sh << 'EOF'
#!/bin/bash
SENTINEL_PASSWORD="sentinel123"
REDIS_PASSWORD="redis123"
echo "=== 1. 查看当前主节点 ==="
redis-cli -p 26379 -a $SENTINEL_PASSWORD sentinel get-master-addr-by-name mymaster
echo -e "\n=== 2. 查看所有监控的主节点 ==="
redis-cli -p 26379 -a $SENTINEL_PASSWORD sentinel masters
echo -e "\n=== 3. 查看从节点信息 ==="
redis-cli -p 26379 -a $SENTINEL_PASSWORD sentinel slaves mymaster
echo -e "\n=== 4. 查看其他 Sentinel 节点 ==="
redis-cli -p 26379 -a $SENTINEL_PASSWORD sentinel sentinels mymaster
echo -e "\n=== 5. 测试数据写入主节点 ==="
redis-cli -p 6379 -a $REDIS_PASSWORD set sentinel-test "Hello Sentinel"
echo -e "\n=== 6. 从从节点读取数据 ==="
redis-cli -p 6380 -a $REDIS_PASSWORD get sentinel-test
redis-cli -p 6381 -a $REDIS_PASSWORD get sentinel-test
echo -e "\n=== 7. 模拟主节点故障 ==="
echo "将要关闭主节点 (端口 6379),观察 Sentinel 的故障转移..."
read -p "按 Enter 继续..."
redis-cli -p 6379 -a $REDIS_PASSWORD debug segfault || redis-cli -p 6379 -a $REDIS_PASSWORD shutdown
echo -e "\n=== 8. 等待故障转移完成 ==="
sleep 10
echo -e "\n=== 9. 查看新的主节点 ==="
redis-cli -p 26379 -a $SENTINEL_PASSWORD sentinel get-master-addr-by-name mymaster
echo -e "\n=== 10. 验证新主节点可写入 ==="
NEW_MASTER=$(redis-cli -p 26379 -a $SENTINEL_PASSWORD sentinel get-master-addr-by-name mymaster | head -1)
NEW_PORT=$(redis-cli -p 26379 -a $SENTINEL_PASSWORD sentinel get-master-addr-by-name mymaster | tail -1)
redis-cli -h $NEW_MASTER -p $NEW_PORT -a $REDIS_PASSWORD set failover-test "Master switched successfully"
redis-cli -h $NEW_MASTER -p $NEW_PORT -a $REDIS_PASSWORD get failover-test
EOF
chmod +x ~/redis-practice/sentinel/test-sentinel.sh
~/redis-practice/sentinel/test-sentinel.sh
5 监控和管理工具
5.1 Redis 核心监控命令详解
在编写监控脚本之前,让我们先了解 Redis 的核心监控命令:
系统信息查询命令
# 1. 基本信息查询
INFO # 获取所有服务器信息
INFO server # 服务器基本信息
INFO memory # 内存使用信息
INFO replication # 复制相关信息
INFO persistence # 持久化信息
INFO stats # 统计信息
INFO clients # 客户端连接信息
INFO cpu # CPU 使用信息
INFO cluster # 集群信息
INFO keyspace # 键空间信息
# 2. 性能监控命令
MONITOR # 实时监控所有命令
SLOWLOG GET [count] # 获取慢查询日志
SLOWLOG LEN # 获取慢查询日志长度
SLOWLOG RESET # 清空慢查询日志
CLIENT LIST # 列出所有客户端连接
CLIENT KILL [ip:port] # 杀死指定客户端连接
# 3. 内存分析命令
MEMORY USAGE <key> # 查看键的内存使用量
MEMORY STATS # 内存统计信息
MEMORY DOCTOR # 内存诊断建议
DBSIZE # 当前数据库键的数量
LASTSAVE # 最后一次保存到磁盘的时间
# 4. 配置管理命令
CONFIG GET <parameter> # 获取配置参数
CONFIG SET <parameter> <value> # 设置配置参数
CONFIG REWRITE # 将配置写入配置文件
CONFIG RESETSTAT # 重置统计信息
# 5. 数据库操作命令
SELECT <db> # 选择数据库
FLUSHDB # 清空当前数据库
FLUSHALL # 清空所有数据库
SAVE # 同步保存数据到磁盘
BGSAVE # 异步保存数据到磁盘
BGREWRITEAOF # 异步重写AOF文件
实用监控脚本示例
# 创建综合监控脚本
cat > ~/redis-practice/redis-health-check.sh << 'EOF'
#!/bin/bash
# 单个Redis实例健康检查函数
check_redis_health() {
local host=$1
local port=$2
local password=$3
local name=$4
echo "=== $name 健康检查 ==="
# 连接测试
if ! redis-cli -h $host -p $port -a $password ping >/dev/null 2>&1; then
echo "❌ 连接失败"
return 1
fi
# 获取详细信息
local info=$(redis-cli -h $host -p $port -a $password info 2>/dev/null)
# 基本信息
echo "Redis版本: $(echo "$info" | grep redis_version | cut -d: -f2 | tr -d '\r')"
echo "运行模式: $(echo "$info" | grep redis_mode | cut -d: -f2 | tr -d '\r')"
echo "进程ID: $(echo "$info" | grep process_id | cut -d: -f2 | tr -d '\r')"
# 运行时间
local uptime=$(echo "$info" | grep uptime_in_seconds | cut -d: -f2 | tr -d '\r')
echo "运行时间: $((uptime/3600))小时 $(((uptime%3600)/60))分钟"
# 内存使用
echo "内存使用: $(echo "$info" | grep used_memory_human | cut -d: -f2 | tr -d '\r')"
echo "内存峰值: $(echo "$info" | grep used_memory_peak_human | cut -d: -f2 | tr -d '\r')"
# 连接数
echo "连接客户端: $(echo "$info" | grep connected_clients | cut -d: -f2 | tr -d '\r')"
# 命令统计
echo "总命令数: $(echo "$info" | grep total_commands_processed | cut -d: -f2 | tr -d '\r')"
# 键空间信息
local keyspace=$(echo "$info" | grep "^db0:" | cut -d: -f2 | tr -d '\r')
if [ ! -z "$keyspace" ]; then
echo "数据库0: $keyspace"
fi
# 持久化状态
echo "上次保存: $(date -d @$(echo "$info" | grep rdb_last_save_time | cut -d: -f2 | tr -d '\r'))"
# 复制状态(如果是主从架构)
local role=$(echo "$info" | grep "role:" | cut -d: -f2 | tr -d '\r')
echo "节点角色: $role"
if [ "$role" = "master" ]; then
local slaves=$(echo "$info" | grep connected_slaves | cut -d: -f2 | tr -d '\r')
echo "连接从节点: $slaves"
elif [ "$role" = "slave" ]; then
local master_link=$(echo "$info" | grep master_link_status | cut -d: -f2 | tr -d '\r')
echo "主节点连接: $master_link"
fi
# 慢查询检查
local slow_queries=$(redis-cli -h $host -p $port -a $password slowlog len 2>/dev/null)
if [ "$slow_queries" -gt 0 ]; then
echo "⚠️ 慢查询: $slow_queries 条"
fi
echo "✅ 健康检查完成"
echo ""
EOF
chmod +x ~/redis-practice/redis-health-check.sh
5.2 Redis 监控脚本
cat > ~/redis-practice/redis-monitor.sh << 'EOF'
#!/bin/bash
monitor_redis() {
local host=$1
local port=$2
local password=$3
local name=$4
echo "=== $name ($host:$port) ==="
# 检查连接
if redis-cli -h $host -p $port -a $password ping >/dev/null 2>&1; then
echo "✅ 连接状态: 正常"
# 获取基本信息
info=$(redis-cli -h $host -p $port -a $password info server,memory,clients 2>/dev/null)
echo "Redis 版本: $(echo "$info" | grep redis_version | cut -d: -f2 | tr -d '\r')"
echo "运行时间: $(echo "$info" | grep uptime_in_seconds | cut -d: -f2 | tr -d '\r') 秒"
echo "内存使用: $(echo "$info" | grep used_memory_human | cut -d: -f2 | tr -d '\r')"
echo "连接客户端: $(echo "$info" | grep connected_clients | cut -d: -f2 | tr -d '\r')"
# 检查角色
role=$(redis-cli -h $host -p $port -a $password info replication 2>/dev/null | grep "role:" | cut -d: -f2 | tr -d '\r')
echo "节点角色: $role"
else
echo "❌ 连接状态: 失败"
fi
echo ""
}
echo "Redis 架构监控报告"
echo "===================="
echo "生成时间: $(date)"
echo ""
echo "1. 主从架构监控"
echo "----------------"
monitor_redis 127.0.0.1 6379 redis123 "主节点"
monitor_redis 127.0.0.1 6380 redis123 "从节点1"
monitor_redis 127.0.0.1 6381 redis123 "从节点2"
echo "2. 集群架构监控"
echo "----------------"
for port in 7000 7001 7002 7003 7004 7005; do
monitor_redis 127.0.0.1 $port redis123 "集群节点-$port"
done
echo "3. Sentinel 监控"
echo "----------------"
for port in 26379 26380 26381; do
if redis-cli -p $port -a sentinel123 ping >/dev/null 2>&1; then
echo "✅ Sentinel-$port: 正常运行"
masters=$(redis-cli -p $port -a sentinel123 sentinel masters 2>/dev/null | grep -c "name")
echo " 监控主节点数: $masters"
else
echo "❌ Sentinel-$port: 连接失败"
fi
done
EOF
chmod +x ~/redis-practice/redis-monitor.sh
5.3 清理脚本
cat > ~/redis-practice/cleanup.sh << 'EOF'
#!/bin/bash
echo "=== Redis 架构练习清理脚本 ==="
echo "正在停止所有 Redis 进程..."
# 停止 Redis 实例
for port in 6379 6380 6381 7000 7001 7002 7003 7004 7005; do
redis-cli -p $port -a redis123 shutdown 2>/dev/null || true
done
# 停止 Sentinel 实例
for port in 26379 26380 26381; do
redis-cli -p $port -a sentinel123 shutdown 2>/dev/null || true
done
# 强制杀死可能残留的进程
pkill -f redis-server 2>/dev/null || true
pkill -f redis-sentinel 2>/dev/null || true
echo "正在清理数据文件..."
rm -rf ~/redis-practice/*/data/*
rm -rf ~/redis-practice/*/logs/*
echo "清理完成!"
echo "如需重新开始,请重新运行相应的启动脚本。"
EOF
chmod +x ~/redis-practice/cleanup.sh
6 性能测试
6.1 Redis 性能测试核心命令
在使用性能测试脚本之前,让我们先了解 redis-benchmark 的核心参数:
redis-benchmark 命令详解
# 1. 基本用法
redis-benchmark [options] # 基本命令格式
# 2. 连接相关参数
-h <hostname> # Redis服务器地址(默认127.0.0.1)
-p <port> # Redis服务器端口(默认6379)
-a <password> # Redis密码
-s <socket> # Unix socket连接
# 3. 测试参数
-c <clients> # 并发客户端数量(默认50)
-n <requests> # 总请求数(默认10000)
-d <size> # 数据大小(字节,默认3)
-t <tests> # 指定要测试的命令(用逗号分隔)
-r <keyspacelen> # 使用随机键,指定键空间大小
# 4. 输出格式
--csv # CSV格式输出
-q # 简化输出
--latency # 延迟相关统计
--latency-history # 延迟历史记录
--latency-dist # 延迟分布统计
# 5. 特殊选项
-i <interval> # 间隔时间(秒)
-l # 循环测试
-P <pipeline> # 使用管道模式
--cluster # 集群模式
-e # 在错误时显示错误信息
# 6. 常用测试命令
SET # 设置键值
GET # 获取键值
INCR # 递增
LPUSH # 列表推入
RPUSH # 列表推入
LPOP # 列表弹出
RPOP # 列表弹出
SADD # 集合添加
HSET # 哈希设置
SPOP # 集合弹出
ZADD # 有序集合添加
ZREVRANGE # 有序集合范围查询
MSET # 批量设置
实用性能测试示例
# 1. 基本性能测试
redis-benchmark -h 127.0.0.1 -p 6379 -a redis123 -c 50 -n 10000
# 2. 指定命令测试
redis-benchmark -h 127.0.0.1 -p 6379 -a redis123 -t set,get -n 100000 -c 100
# 3. 不同数据大小测试
redis-benchmark -h 127.0.0.1 -p 6379 -a redis123 -t set,get -n 10000 -d 1024 -c 50
# 4. 管道模式测试
redis-benchmark -h 127.0.0.1 -p 6379 -a redis123 -t set,get -n 10000 -P 10
# 5. 随机键测试
redis-benchmark -h 127.0.0.1 -p 6379 -a redis123 -t set,get -n 10000 -r 1000
# 6. 集群模式测试
redis-benchmark -h 127.0.0.1 -p 7000 -a redis123 -t set,get -n 10000 --cluster
# 7. 延迟测试
redis-cli -h 127.0.0.1 -p 6379 -a redis123 --latency
redis-cli -h 127.0.0.1 -p 6379 -a redis123 --latency-history -i 1
redis-cli -h 127.0.0.1 -p 6379 -a redis123 --latency-dist
# 8. 内存使用分析
redis-cli -h 127.0.0.1 -p 6379 -a redis123 --bigkeys
redis-cli -h 127.0.0.1 -p 6379 -a redis123 --hotkeys # 需要开启 maxmemory-policy
# 9. 综合性能分析
redis-benchmark -h 127.0.0.1 -p 6379 -a redis123 -t set,get,incr,lpush,rpush,lpop,rpop,sadd,hset,spop,zadd,zrevrange,mset -n 100000 -c 50 --csv
# 10. 对比测试脚本
cat > ~/redis-practice/performance-compare.sh << 'EOF'
#!/bin/bash
echo "Redis 性能对比测试"
echo "===================="
# 测试参数
TEST_COUNT=50000
CONCURRENCY=50
DATA_SIZE=100
PASSWORD="redis123"
# 测试单机Redis
echo "1. 单机 Redis 性能测试 (6379)"
echo "--------------------------------"
redis-benchmark -h 127.0.0.1 -p 6379 -a $PASSWORD -t set,get -n $TEST_COUNT -c $CONCURRENCY -d $DATA_SIZE -q
# 测试从节点读性能
echo -e "\n2. 从节点读性能测试 (6380)"
echo "--------------------------------"
redis-benchmark -h 127.0.0.1 -p 6380 -a $PASSWORD -t get -n $TEST_COUNT -c $CONCURRENCY -d $DATA_SIZE -q
# 测试集群性能
echo -e "\n3. 集群模式性能测试 (7000)"
echo "--------------------------------"
redis-benchmark -h 127.0.0.1 -p 7000 -a $PASSWORD -t set,get -n $TEST_COUNT -c $CONCURRENCY -d $DATA_SIZE --cluster -q 2>/dev/null
# 管道模式测试
echo -e "\n4. 管道模式性能测试"
echo "--------------------------------"
redis-benchmark -h 127.0.0.1 -p 6379 -a $PASSWORD -t set,get -n $TEST_COUNT -c $CONCURRENCY -d $DATA_SIZE -P 10 -q
echo -e "\n测试完成!"
EOF
chmod +x ~/redis-practice/performance-compare.sh
6.2 基准测试脚本
cat > ~/redis-practice/benchmark.sh << 'EOF'
#!/bin/bash
echo "=== Redis 性能测试 ==="
test_single() {
local host=$1
local port=$2
local password=$3
local name=$4
echo "测试 $name ($host:$port)"
echo "------------------------"
redis-benchmark -h $host -p $port -a $password -t set,get -n 10000 -c 50 -d 100 --csv | \
while IFS=, read test ops_per_sec; do
echo "$test: $ops_per_sec 操作/秒"
done
echo ""
}
test_cluster() {
echo "测试 Redis 集群"
echo "----------------"
redis-benchmark -h 127.0.0.1 -p 7000 -a redis123 -t set,get -n 10000 -c 50 -d 100 --cluster --csv | \
while IFS=, read test ops_per_sec; do
echo "$test: $ops_per_sec 操作/秒"
done
echo ""
}
echo "1. 单实例性能测试"
test_single 127.0.0.1 6379 redis123 "主节点"
echo "2. 集群性能测试"
test_cluster
echo "3. 延迟测试"
echo "------------"
redis-cli -h 127.0.0.1 -p 6379 -a redis123 --latency -i 1 &
LATENCY_PID=$!
sleep 5
kill $LATENCY_PID
EOF
chmod +x ~/redis-practice/benchmark.sh
7 快速操作命令总结
7.1 核心命令速查表
Redis 基础管理命令
# 启动和连接
redis-server [config_file] # 启动Redis服务器
redis-cli -h host -p port -a password # 连接Redis
redis-cli --cluster create ... # 创建集群
redis-sentinel sentinel.conf # 启动Sentinel
# 信息查询
INFO [section] # 获取服务器信息
PING # 测试连接
DBSIZE # 获取键数量
CONFIG GET parameter # 获取配置
SLOWLOG GET [count] # 获取慢查询日志
# 主从复制
REPLICAOF host port # 设置主从关系(Redis 5.0+)
SLAVEOF host port # 设置主从关系(Redis 4.x)
SLAVEOF NO ONE # 取消主从关系
# 集群管理
CLUSTER NODES # 查看集群节点
CLUSTER INFO # 查看集群状态
CLUSTER MEET ip port # 加入节点到集群
CLUSTER ADDSLOTS slot... # 分配槽位
# Sentinel 管理
SENTINEL MASTERS # 查看监控的主节点
SENTINEL GET-MASTER-ADDR-BY-NAME name # 获取主节点地址
SENTINEL FAILOVER name # 手动故障转移
# 性能测试
redis-benchmark -h host -p port -a password -t tests -n requests -c clients
7.2 实用命令速查手册
日常运维命令
# 1. 服务状态检查
ps aux | grep redis # 查看Redis进程
netstat -tlnp | grep redis # 查看Redis端口
redis-cli -p 6379 -a password ping # 测试连接
# 2. 数据备份和恢复
redis-cli -p 6379 -a password SAVE # 同步备份
redis-cli -p 6379 -a password BGSAVE # 异步备份
redis-cli -p 6379 -a password BGREWRITEAOF # 重写AOF
cp /path/to/dump.rdb /backup/location # 备份数据文件
# 3. 内存管理
redis-cli -p 6379 -a password MEMORY USAGE key # 查看键内存使用
redis-cli -p 6379 -a password --bigkeys # 查找大键
redis-cli -p 6379 -a password FLUSHDB # 清空当前数据库
redis-cli -p 6379 -a password FLUSHALL # 清空所有数据库
# 4. 客户端管理
redis-cli -p 6379 -a password CLIENT LIST # 列出所有客户端
redis-cli -p 6379 -a password CLIENT KILL ip:port # 关闭指定客户端
redis-cli -p 6379 -a password MONITOR # 监控所有命令
# 5. 配置管理
redis-cli -p 6379 -a password CONFIG GET '*' # 获取所有配置
redis-cli -p 6379 -a password CONFIG SET parameter value # 设置配置
redis-cli -p 6379 -a password CONFIG REWRITE # 保存配置到文件
# 6. 性能监控
redis-cli -p 6379 -a password --latency # 延迟监控
redis-cli -p 6379 -a password --stat # 实时统计
redis-cli -p 6379 -a password --scan --pattern 'user:*' # 扫描匹配键
故障排查命令
# 1. 日志分析
tail -f /path/to/redis.log # 实时查看日志
grep ERROR /path/to/redis.log # 查找错误日志
grep WARNING /path/to/redis.log # 查找警告日志
# 2. 连接问题排查
telnet 127.0.0.1 6379 # 测试TCP连接
redis-cli -h host -p port ping # 测试Redis连接
nmap -p 6379 host # 测试端口开放
# 3. 内存问题排查
redis-cli -p 6379 -a password INFO memory # 内存使用情况
redis-cli -p 6379 -a password MEMORY DOCTOR # 内存诊断
redis-cli -p 6379 -a password --bigkeys # 查找大键
# 4. 性能问题排查
redis-cli -p 6379 -a password SLOWLOG GET 10 # 查看慢查询
redis-cli -p 6379 -a password --latency-history # 延迟历史
redis-cli -p 6379 -a password INFO stats # 统计信息
# 5. 主从同步问题
redis-cli -p 6379 -a password INFO replication # 主节点复制信息
redis-cli -p 6380 -a password INFO replication # 从节点复制信息
redis-cli -p 6380 -a password REPLICAOF 127.0.0.1 6379 # 重新建立主从关系
# 6. 集群问题排查
redis-cli -c -p 7000 -a password CLUSTER NODES # 集群节点状态
redis-cli -c -p 7000 -a password CLUSTER INFO # 集群整体状态
redis-cli --cluster check 127.0.0.1:7000 -a password # 集群健康检查
8 学习要点和最佳实践
8.1 主从复制架构
- 优势: 读写分离,提高读性能
- 劣势: 主节点单点故障,需手动切换
- 适用场景: 读多写少的应用
8.2 Cluster 集群架构
- 优势: 水平扩展,自动分片,高可用
- 劣势: 复杂性高,某些命令限制
- 适用场景: 大数据量,高并发应用
8.3 Sentinel 哨兵架构
- 优势: 自动故障转移,监控报警
- 劣势: 额外的运维复杂性
- 适用场景: 对可用性要求高的应用
8.4 配置要点
- 密码认证:生产环境必须配置
- 持久化:根据业务需求选择 RDB 或 AOF
- 内存管理:设置合适的最大内存和淘汰策略
- 网络安全:绑定合适的网络接口
8.5 常见问题解决方案
问题: "Connection refused"
# 检查端口占用
netstat -tlnp | grep :6379
# 检查防火墙
sudo ufw status # Ubuntu
sudo firewall-cmd --list-ports # CentOS
# 检查Redis进程
ps aux | grep redis
问题: "NOAUTH Authentication required"
# 检查密码配置
redis-cli -p 6379 -a redis123 ping
redis-cli -p 26379 -a sentinel123 ping
问题: "集群节点无法通信"
# 检查集群端口
for port in 7000 7001 7002 7003 7004 7005; do
redis-cli -p $port -a redis123 ping
done
# 检查集群状态
redis-cli -c -p 7000 -a redis123 cluster nodes
8.6 监控指标
- 内存使用率
- 连接数
- 命令执行延迟
- 主从同步延迟
- 集群槽位分布