一、Redis 连接相关问题详解
1.1 问题:无法连接 Redis 服务(Connection refused)
现象详解
当尝试连接 Redis 服务时,可能出现以下具体错误信息:
Error: Could not connect to Redis at 127.0.0.1:6379: Connection refused
Error: Target machine actively refused connection
可能原因深度分析
-
Redis 服务未启动:
- Redis 服务器进程未运行
- 服务启动失败(检查日志文件/var/log/redis/redis-server.log)
-
端口被占用:
- 6379 端口被其他应用程序(如另一个 Redis 实例)占用
- 可通过
lsof -i :6379查看具体占用进程
-
绑定 IP 限制:
- Redis 默认绑定 127.0.0.1(仅本地连接)
- 生产环境常见错误是未修改 bind 配置
-
防火墙拦截:
- 云服务器(如 AWS、阿里云)需要配置安全组规则
- 本地防火墙(Windows 防火墙、Linux iptables)
-
保护模式开启:
- Redis 3.2 后默认启用保护模式
- 当 bind 未指定且未设置密码时自动拒绝外部连接
解决方案详细步骤
1. 检查 Redis 服务状态
# 检查进程是否存在
ps aux | grep redis-server
# 检查服务状态(系统服务)
systemctl status redis
# 尝试手动启动
redis-server /etc/redis/redis.conf
2. 检查端口占用
# Linux 查看端口占用
netstat -tulnp | grep 6379
# 或
ss -tulnp | grep 6379
# 如果被占用,可终止进程
kill -9 [PID]
3. 配置绑定 IP
修改 redis.conf 文件:
# 允许所有IP连接(慎用)
bind 0.0.0.0
# 或指定多个IP
bind 127.0.0.1 192.168.1.100
4. 防火墙设置示例
CentOS/RHEL:
firewall-cmd --permanent --add-port=6379/tcp
firewall-cmd --reload
Ubuntu/Debian:
ufw allow 6379/tcp
ufw enable
云服务器注意事项:
- AWS: 配置安全组入站规则
- 阿里云: 配置安全组规则
5. 保护模式配置
# 临时关闭
redis-cli
127.0.0.1:6379> CONFIG SET protected-mode no
# 永久配置
vim /etc/redis/redis.conf
protected-mode no
requirepass yourstrongpassword
1.2 问题:连接频繁断开(Connection reset by peer)
现象扩展
- 连接建立后几分钟内自动断开
- 错误日志中出现 "Read timed out" 或 "Connection reset"
- 客户端出现 "SocketException: Broken pipe"
原因深入分析
-
Redis 服务器配置:
- timeout 参数设置过小(默认300秒)
- tcp-keepalive 配置不合理
-
中间件问题:
- 负载均衡器(如 AWS ELB)空闲超时设置
- NAT 网关会话超时
-
网络问题:
- 不稳定的WiFi或移动网络
- 路由表变化导致连接中断
详细解决方案
1. Redis 服务器配置优化
# 设置为0表示永不超时(生产环境慎用)
timeout 0
# 启用TCP keepalive(推荐配置)
tcp-keepalive 300
2. 客户端连接池优化示例
Java (Jedis) 高级配置:
JedisPoolConfig config = new JedisPoolConfig();
config.setTestOnBorrow(true); // 获取连接时验证
config.setTestOnReturn(true); // 归还连接时验证
config.setTestWhileIdle(true); // 空闲时验证
config.setNumTestsPerEvictionRun(10); // 每次检查的连接数
Python (redis-py) 配置:
import redis
# 启用健康检查
r = redis.Redis(
host='redis-host',
socket_keepalive=True,
socket_keepalive_options={
socket.TCP_KEEPIDLE: 60,
socket.TCP_KEEPINTVL: 30,
socket.TCP_KEEPCNT: 3
}
)
3. 网络问题排查工具
# 持续ping测试
ping -t redis-host
# MTR网络诊断
mtr redis-host
# TCP连接测试
telnet redis-host 6379
1.3 问题:连接池耗尽(Could not get a resource from the pool)
现象详细描述
- 高峰期出现大量获取连接超时
- 监控显示连接数达到上限
- 可能伴随 "Timeout waiting for idle object" 错误
根本原因分析
-
连接泄漏:
- 未正确释放连接(try-catch块中未关闭)
- 事务未正确结束
-
配置不当:
- maxTotal 小于实际并发量
- 连接获取超时时间设置过短
-
Redis 服务限制:
- maxclients 设置过小
- 系统文件描述符限制
全面解决方案
1. 连接池最佳实践配置
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(500); // 根据业务需求调整
config.setMaxIdle(100); // 建议小于maxTotal
config.setMinIdle(20); // 保持最小空闲连接
config.setMaxWaitMillis(5000); // 适当延长等待时间
config.setTestOnBorrow(true); // 确保连接有效
2. 连接泄漏排查方法
- 使用监控工具(如 JMX)查看连接池状态
- 在 finally 块中确保连接关闭
Jedis jedis = null;
try {
jedis = pool.getResource();
// 业务操作
} finally {
if (jedis != null) {
jedis.close();
}
}
3. Redis 服务端调整
# 查看当前连接数
127.0.0.1:6379> info clients
# 修改最大连接数
vim /etc/redis/redis.conf
maxclients 10000
# 调整系统限制
ulimit -n 65535
4. 高级监控方案
- 实现连接池监控接口
- 集成 Prometheus + Grafana 监控
- 设置连接池使用率告警
预防措施
- 实施连接获取超时熔断机制
- 定期检查连接泄漏
- 进行压力测试确定最优配置
- 实现连接池的动态调整
二、Redis 数据相关问题
2.1 问题:数据丢失(Key突然消失)
现象
- Redis中的Key未到过期时间却突然消失
- Redis重启后数据丢失
- 客户端查询时突然返回nil值
可能原因
-
内存淘汰策略触发:
- Redis内存达到maxmemory限制,触发配置的淘汰策略(如allkeys-lru)
- 特别是当业务数据量突增时更容易发生
-
数据未持久化:
- 未开启RDB或AOF持久化
- 持久化配置不合理(如RDB保存间隔过长)
- 服务器宕机导致内存数据丢失
-
手动删除或误操作:
- 执行了DEL key命令
- 执行了FLUSHDB、FLUSHALL等危险命令
- 运维人员误操作导致数据删除
-
Key过期时间设置错误:
- 通过EXPIRE设置了错误的过期时间
- 秒级和毫秒级单位混淆(EX vs PX)
- 业务逻辑错误导致提前删除
解决方案
排查内存淘汰策略
-
执行
info memory查看关键指标:used_memory:已使用内存maxmemory:最大内存限制evicted_keys:被淘汰的Key数量
-
如果
evicted_keys>0,说明触发了淘汰策略:- 调整maxmemory:建议设置为物理内存的70-80%(如16GB服务器可设置12GB)
- 选择合适的淘汰策略:
volatile-lru:仅淘汰带过期时间的Keyallkeys-lru:淘汰所有Keynoeviction:内存满时拒绝写入(默认策略)
开启并优化持久化
-
RDB持久化配置:
save 900 1 # 15分钟内至少1个变更 save 300 10 # 5分钟内至少10个变更 save 60 10000 # 1分钟内至少10000个变更 -
AOF持久化配置:
appendonly yes appendfsync everysec # 每秒刷盘 auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb -
推荐生产环境同时开启RDB和AOF:
- RDB用于定期全量备份
- AOF用于记录增量操作
防止误操作
-
禁用危险命令:
rename-command FLUSHDB "" rename-command FLUSHALL "" rename-command CONFIG "RANDOM_STRING_HERE" -
安全配置:
- 开启密码认证:
requirepass yourpassword - 使用Redis 6.0+的ACL功能:
ACL SETUSER alice on >password ~cache:* +get +set
- 开启密码认证:
验证过期时间设置
-
检查Key过期时间:
TTL user:100 # 返回剩余秒数 PTTL user:100 # 返回剩余毫秒数 -
正确设置过期时间:
SET user:100 "value" EX 3600 # 3600秒 SET user:100 "value" PX 3600000 # 3600000毫秒
2.2 问题:数据过期后未删除(Key过期但仍存在)
现象
- 通过
TTL key查看返回-2(已过期) - 但执行
GET key仍能获取到值 - 内存中仍有大量过期Key未被清理
可能原因
-
Redis过期删除策略特性:
- 惰性删除:访问Key时才检查过期
- 定期删除:默认每100ms随机检查部分Key
- 不会立即删除所有过期Key
-
内存淘汰策略未触发:
- Key未设置过期时间(TTL返回-1)
- 内存未满,淘汰策略不会执行
-
大量Key同时过期:
- 导致定期删除无法及时处理
解决方案
理解过期删除策略
-
Redis设计权衡:
- 不立即删除是为了避免性能损耗
- 一般业务场景可接受短暂延迟
-
特殊情况处理:
# 不推荐的方式 - 增加Redis负担 if redis.ttl(key) == -2: redis.delete(key)
确保Key设置过期时间
-
批量检查脚本示例:
# 使用SCAN安全遍历 redis-cli --scan --pattern "user:*" | while read key; do ttl=$(redis-cli ttl "$key") if [ "$ttl" -eq -1 ]; then echo "Warning: $key has no TTL" fi done -
设置合理的过期时间:
EXPIRE user:100 86400 # 1天过期
调整定期删除频率
-
修改redis.conf:
hz 50 # 默认10,提高至50 -
注意事项:
- hz过高会增加CPU使用率
- 建议在测试环境先验证
2.3 问题:数据类型使用错误
现象
- 使用String存储JSON格式的列表数据
- 每次修改需要全量读取和写入
- 查询效率低下
可能原因
- 开发者对Redis数据类型不熟悉
- 初期设计未考虑扩展性
- 简单模仿关系型数据库使用方式
解决方案
合理选择数据类型
| 数据类型 | 典型应用场景 | 优势 |
|---|---|---|
| String | 计数器、简单KV | INCR原子操作 |
| List | 消息队列、时间线 | LPUSH/RPOP操作 |
| Hash | 对象属性存储 | 部分字段更新 |
| Set | 标签、好友关系 | 集合运算 |
| ZSet | 排行榜、延迟队列 | 自动排序 |
迁移示例
-
错误方式:
SET user:100 '{"name":"张三","orders":["o1","o2"]}' -
优化方案:
# 使用Hash存储用户属性 HMSET user:100 name 张三 age 25 # 使用List存储订单 LPUSH user:100:orders o1 o2 # 使用Set存储标签 SADD user:100:tags vip active
性能对比
-
String+JSON方式:
- 读取:O(1)但需要解析JSON
- 修改:需要全量更新
- 空间:可能包含冗余数据
-
原生数据结构:
- 读取:直接获取所需部分
- 修改:可单独更新字段
- 空间:按需存储
最佳实践建议
- 设计阶段考虑数据访问模式
- 避免过度使用JSON序列化
- 必要时使用Lua脚本保证原子性
三、Redis 性能相关问题
3.1 Redis 响应延迟问题(命令执行耗时过长)
现象识别
- 基础命令响应异常:简单命令如
PING或GET key响应时间超过 10 毫秒(正常应低于 1 毫秒) - 监控指标异常:
- Prometheus + Grafana 显示
redis_command_duration_seconds指标显著升高 - Redis 内置监控显示
latency数据异常
- Prometheus + Grafana 显示
深入分析可能原因
-
Redis 进程阻塞
- 慢命令执行:
- 全量遍历命令:
KEYS *(时间复杂度O(n)) - 大数据量操作:
HGETALL large_hash(返回所有字段) - 复杂计算:
SORT large_set(大数据排序)
- 全量遍历命令:
- 持久化操作影响:
- RDB 快照生成(特别是大数据量时)
- AOF 重写(日志文件过大时)
- 慢命令执行:
-
服务器资源问题
- CPU 瓶颈:
- Redis 进程 CPU 使用率持续超过 80%
- 服务器整体 CPU 使用率饱和
- 内存问题:
- 物理内存不足触发 Swap
- 内存碎片率过高(可通过
INFO memory查看)
- 网络瓶颈:
- 高并发下网络带宽饱和
- 网络延迟增加(跨机房访问)
- CPU 瓶颈:
详细解决方案
慢命令优化方案
1.慢日志分析:
# 查看当前慢查询阈值(微秒)
config get slowlog-log-slower-than
# 获取最近的慢查询记录
slowlog get 10
2.具体优化措施:
- 替换
KEYS *:# 使用SCAN命令分批获取 SCAN 0 MATCH user:* COUNT 100 - 优化大Hash访问:
# 使用HSCAN分批获取字段 HSCAN large_user_info 0 COUNT 50 - 禁用危险命令:
# 在redis.conf中禁用 rename-command KEYS "" rename-command FLUSHDB ""
持久化优化方案
1.RDB优化配置:
# 减少保存频率
save 900 1
save 300 10
save 60 10000
# 禁用保存
save ""
2.AOF优化配置:
appendonly yes
appendfsync everysec
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-rewrite-incremental-fsync yes
服务器资源优化
1.CPU优化:
# 查看CPU使用情况
top -p $(pgrep redis-server)
# 绑定CPU核心(减少上下文切换)
taskset -cp 0,1,2,3 $(pgrep redis-server)
2.内存优化:
# 禁用Swap
sudo swapoff -a
# 设置内存策略
config set maxmemory 12gb
config set maxmemory-policy allkeys-lru
3.网络优化:
# 查看网络状况
iftop -n -P
# 优化内核参数
echo 'net.core.somaxconn=65535' >> /etc/sysctl.conf
sysctl -p
3.2 CPU 使用率过高问题
现象表现
top命令显示 Redis 进程持续占用高 CPU- Redis 响应时间波动明显
- 监控显示 CPU 使用率曲线长期高位运行
根本原因分析
-
计算密集型操作
- 频繁执行集合运算:
SINTER、SUNION、SDIFF - 大规模数据排序:
SORT命令 - 复杂Lua脚本执行
- 频繁执行集合运算:
-
Key设计问题
- 超长Key(超过100字节)
- 非结构化Key命名
- 大量小Key(导致内存碎片)
-
连接管理问题
- 连接数暴增(超过
maxclients限制) - 客户端异常未释放连接
- 连接数暴增(超过
优化实施方案
命令优化
1.替代复杂命令:
# 原命令
SINTER set1 set2 set3
# 优化方案
SSCAN set1 0 COUNT 100
SSCAN set2 0 COUNT 100
# 在应用层实现交集计算
2.启用多线程I/O(Redis 6.0+):
io-threads 4
io-threads-do-reads yes
Key设计规范
1.命名规范:
# 不推荐
user_information_for_id_12345_with_status_active
# 推荐
user:12345:status
2.数据结构优化:
# 大Hash拆分
HMSET user:1000 name "John" age 30
HMSET user:1001 name "Alice" age 28
连接管理
1.客户端优化:
// Java (Jedis) 连接池配置
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(200);
poolConfig.setMaxIdle(50);
poolConfig.setMinIdle(10);
JedisPool jedisPool = new JedisPool(poolConfig, "redis-host", 6379);
2.服务端配置:
maxclients 10000
timeout 300
tcp-keepalive 60
3.3 QPS 提升方案
性能瓶颈分析
-
硬件限制
- 单核CPU性能天花板
- 网络带宽限制
- 内存访问速度
-
架构限制
- 单实例处理所有请求
- 数据分布不均
-
使用模式问题
- 频繁短连接
- 未使用管道/批量操作
集群化部署方案
1.Redis Cluster 部署:
# 创建集群
redis-cli --cluster create \
192.168.1.101:6379 \
192.168.1.102:6379 \
192.168.1.103:6379 \
--cluster-replicas 1
2.分片策略:
- 预设16384个哈希槽
- 均匀分布在所有主节点
- 支持动态扩容
性能优化技巧
1.管道技术:
# Python示例
pipe = redis_client.pipeline()
for i in range(100):
pipe.get(f'key:{i}')
results = pipe.execute()
2.批量操作:
# 原生批量命令
MSET key1 val1 key2 val2 key3 val3
MGET key1 key2 key3
3.Lua脚本优化:
-- 原子性计数器
local current = redis.call('GET', KEYS[1])
if not current then
current = 0
end
local new = current + tonumber(ARGV[1])
redis.call('SET', KEYS[1], new)
return new
监控与调优
1.关键指标监控:
# 实时监控
redis-cli --stat
# 获取性能指标
INFO all
2.基准测试:
# 压力测试
redis-benchmark -h 127.0.0.1 -p 6379 -c 100 -n 100000
3.内核参数优化:
# 调整系统参数
vm.overcommit_memory = 1
net.ipv4.tcp_max_syn_backlog = 1024
net.core.somaxconn = 65535
四、Redis 持久化相关问题解析
4.1 RDB快照生成失败问题详解
详细背景
Redis的RDB持久化是通过fork子进程的方式实现的,这种机制在Linux系统上依赖操作系统的内存管理特性。当Redis实例内存使用量较大时,fork操作可能会遇到各种系统限制。
解决方案扩展
内存不足问题深入处理
-
内存监控:建议部署监控系统实时监控服务器内存使用情况,可使用以下命令:
# 监控Redis内存使用 redis-cli info memory | grep used_memory_human # 监控系统内存使用 free -h -
内存优化:
- 考虑使用Redis的内存优化功能,如:
redis-cli config set maxmemory-policy allkeys-lru - 对于大型数据集,可考虑分片(Sharding)方案,将数据分散到多个Redis实例
- 考虑使用Redis的内存优化功能,如:
-
系统级调优:
- 修改内核参数后,建议重启Redis服务:
sudo sysctl -p sudo systemctl restart redis
- 修改内核参数后,建议重启Redis服务:
磁盘空间问题补充方案
-
自动清理脚本示例:
#!/bin/bash RDB_DIR="/var/lib/redis" MAX_USAGE=90 CURRENT_USAGE=$(df -h $RDB_DIR | awk 'NR==2 {print $5}' | tr -d '%') if [ $CURRENT_USAGE -gt $MAX_USAGE ]; then find $RDB_DIR -name "dump*.rdb" -mtime +7 -exec rm {} \; fi可将此脚本加入crontab定时执行
-
磁盘扩展方案:
- 使用LVM逻辑卷管理,方便后续磁盘扩容
- 考虑云服务提供的自动扩展磁盘功能
权限问题完整处理流程
完整的权限修复流程:
# 确认Redis运行用户
REDIS_USER=$(ps -ef | grep redis-server | grep -v grep | awk '{print $1}')
# 设置正确权限
sudo mkdir -p /var/lib/redis
sudo chown $REDIS_USER:$REDIS_USER /var/lib/redis
sudo chmod 755 /var/lib/redis
# 检查SELinux状态
getenforce
# 如需可临时禁用
sudo setenforce 0
4.2 AOF文件损坏问题深度解析
修复流程详细说明
完整修复步骤
-
停止Redis服务:
sudo systemctl stop redis -
备份AOF文件:
TIMESTAMP=$(date +%Y%m%d%H%M%S) cp /var/lib/redis/appendonly.aof /var/lib/redis/appendonly.aof.bak.$TIMESTAMP -
修复AOF文件:
redis-check-aof --fix /var/lib/redis/appendonly.aof -
验证修复结果:
redis-check-aof /var/lib/redis/appendonly.aof -
测试启动:
redis-server /etc/redis.conf --test-memory 1024 -
正式启动:
sudo systemctl start redis
数据恢复进阶方案
-
混合持久化恢复:
- 在Redis 4.0+版本中可开启混合持久化:
config set aof-use-rdb-preamble yes - 这种模式下AOF文件前半段是RDB格式,后半段是AOF格式,恢复能力更强
- 在Redis 4.0+版本中可开启混合持久化:
-
从从节点恢复:
- 如果配置了主从复制,可以从健康的从节点获取数据
# 在从节点执行 redis-cli save scp /var/lib/redis/dump.rdb 主节点:/var/lib/redis/
预防措施增强
监控方案
-
设置AOF文件大小监控:
# 监控脚本示例 AOF_SIZE=$(ls -lh /var/lib/redis/appendonly.aof | awk '{print $5}') echo "AOF文件大小: $AOF_SIZE" -
定期验证AOF文件完整性:
# 加入crontab每周执行 0 3 * * 0 redis-check-aof /var/lib/redis/appendonly.aof
高级存储方案
-
使用ZFS文件系统:具有数据校验和自动修复功能
# 创建ZFS存储池 zpool create redispool /dev/sdb zfs create redispool/redisdata -
企业级解决方案:
- 考虑使用分布式存储系统如Ceph
- 云服务商提供的持久化存储方案
4.3 持久化性能问题全面优化
详细优化方案
操作系统级优化
-
透明大页(THP)禁用:
echo never > /sys/kernel/mm/transparent_hugepage/enabled加入/etc/rc.local实现开机自动禁用
-
内核参数调优:
# 提高内存分配成功率 echo "vm.overcommit_ratio=100" >> /etc/sysctl.conf echo "vm.swappiness=1" >> /etc/sysctl.conf sysctl -p
Redis配置优化
-
精细化的持久化配置:
# 在redis.conf中优化以下参数 rdbcompression yes rdbchecksum yes aof-rewrite-incremental-fsync yes aof-load-truncated yes -
内存优化配置:
# 限制子进程内存使用(Redis 6.2+) config set rdb-fork-child-memory-limit 2gb
硬件级优化
-
磁盘I/O调度器优化:
# 对于SSD建议使用noop或deadline调度器 echo noop > /sys/block/sda/queue/scheduler -
NUMA架构优化:
# 绑定Redis进程到特定NUMA节点 numactl --cpunodebind=0 --membind=0 redis-server /etc/redis.conf
监控与告警方案
-
关键指标监控:
- 持久化延迟监控:
redis-cli info persistence | grep -E "rdb_last_bgsave_time_sec|aof_last_bgrewrite_time_sec" - fork耗时监控:
redis-cli info stats | grep latest_fork_usec
- 持久化延迟监控:
-
告警阈值建议:
- fork时间 > 1秒告警
- bgsave耗时 > 5分钟告警
- AOF重写耗时 > 10分钟告警
企业级解决方案
- 使用Redis企业版:提供无fork持久化等高级功能
- 考虑Redis集群:分散持久化压力到多个节点
- 云服务解决方案:如AWS ElastiCache的持久化优化版本
五、Redis 集群相关问题详解
5.1 集群节点故障问题
详细现象分析
当主节点下线时,客户端会收到以下几种错误响应:
- MOVED错误:表示请求的key所在槽位已被迁移到其他节点
- ASK重定向:表示key正在迁移过程中
- CLUSTERDOWN错误:集群不可用状态
可能原因的深入分析
-
主从节点配置问题:
- 主节点无任何从节点,导致没有故障转移候选者
- 从节点配置不合理,如同步策略不当
-
同步延迟问题:
- 主节点写入压力大,从节点复制速度跟不上
- 网络带宽不足导致同步延迟
- 从节点配置的repl-backlog-size过小
-
心跳检测机制:
- 默认的cluster-node-timeout为15秒
- 在云环境或容器环境中,网络抖动可能导致误判
-
脑裂问题:
- 网络分区导致集群分裂
- 出现多个主节点,数据写入不同分区
全面的解决方案
1.主从节点配置最佳实践:
# 添加从节点详细示例
redis-cli --cluster add-node 192.168.1.2:6380 192.168.1.1:6379 \
--cluster-slave \
--cluster-master-id 3a3b6c7d8e9f0a1b2c3d4e5f6a7b8c9d
2.同步配置优化:
# redis.conf 配置示例
replica-read-only yes
repl-diskless-sync yes
repl-diskless-sync-delay 5
repl-backlog-size 128mb
min-replicas-to-write 1
min-replicas-max-lag 10
3.心跳参数调整:
cluster-node-timeout 20000
cluster-replica-validity-factor 10
cluster-migration-barrier 1
4.脑裂防护措施:
- 使用Redis Sentinel进行额外监控
- 配置合理的quorum值
- 考虑使用Redis的WAIT命令确保数据同步
5.2 数据分片不均衡问题
详细现象分析
- 使用
redis-cli --cluster check命令查看节点内存分布 - 通过
INFO memory命令检查各节点内存使用详情 - 某些节点频繁触发maxmemory策略
可能原因的深入分析
-
初始分片问题:
- 集群创建时未均匀分配slot
- 使用了错误的reshard命令参数
-
Key分布问题:
- 热点数据集中在某些slot
- 大Key占用过多内存
- 使用了不合理的hash tag
-
迁移问题:
- 迁移过程中断导致slot状态异常
- 节点故障导致迁移失败
全面的解决方案
1.重新分配slot的详细步骤:
# 自动平衡slot分布
redis-cli --cluster rebalance 192.168.1.1:6379 \
--cluster-threshold 5 \
--cluster-use-empty-masters \
--cluster-simulate
# 手动迁移slot示例
redis-cli --cluster reshard 192.168.1.1:6379
> How many slots do you want to move? 500
> What is the receiving node ID? 3a3b6c7d8e9f0a1b2c3d4e5f6a7b8c9d
> Please enter all the source node IDs.
Type 'all' to use all the nodes as source nodes for the hash slots.
Type 'done' once you entered all the source nodes IDs.
> all
> done
2.Key优化策略:
- 使用SCAN+DEL命令清理大Key
- 实现数据分页存储
- 合理使用hash tag,例如:
- 好的做法:
user:{12345}:profile,user:{12345}:orders - 坏的做法:
user:12345:profile,user:12345:orders
- 好的做法:
3.迁移状态检查:
# 检查slot状态
redis-cli cluster nodes | grep migrating
redis-cli cluster nodes | grep importing
# 修复迁移中断
redis-cli cluster setslot 1234 NODE 3a3b6c7d8e9f0a1b2c3d4e5f6a7b8c9d
5.3 集群扩容失败问题
详细现象分析
-
节点加入失败的各种错误信息:
ERR Invalid node addressERR The node already knows other nodesERR Node is not empty
-
扩容过程中的常见问题:
- 新节点无法与其他节点通信
- 槽位迁移卡住
- 集群状态不一致
可能原因的深入分析
-
节点配置问题:
- 新节点未开启cluster-enabled
- 存在残留的集群配置文件
-
网络问题:
- 防火墙未开放集群总线端口
- 安全组规则限制
- 节点间网络延迟过高
-
资源问题:
- 新节点内存不足
- 磁盘空间不足
全面的解决方案
1.准备新节点的详细步骤:
# 彻底清理新节点
redis-cli -h new-node shutdown nosave
rm -f /var/lib/redis/nodes.conf
rm -f /var/lib/redis/dump.rdb
2.网络配置检查:
# 检查集群端口连通性
telnet 192.168.1.1 6379
telnet 192.168.1.1 16379
# 防火墙配置示例
iptables -A INPUT -p tcp --dport 6379 -j ACCEPT
iptables -A INPUT -p tcp --dport 16379 -j ACCEPT
3.完整的扩容流程:
# 添加新节点
redis-cli --cluster add-node 192.168.1.10:6379 192.168.1.1:6379
# 等待节点加入集群
redis-cli --cluster check 192.168.1.1:6379
# 迁移槽位
redis-cli --cluster reshard 192.168.1.1:6379
# 添加从节点
redis-cli --cluster add-node 192.168.1.11:6379 192.168.1.10:6379 --cluster-slave
4.验证扩容结果:
redis-cli --cluster check 192.168.1.1:6379
redis-cli cluster info
redis-cli cluster nodes
1万+

被折叠的 条评论
为什么被折叠?



