Redis三主三从集群实战:三台服务器高效部署指南
1. Redis集群模式的选择与三主三从架构优势Redis作为高性能的内存数据库在实际生产环境中通常会面临单机性能瓶颈的问题。我遇到过不少团队刚开始使用Redis时都是单机部署等到用户量上来后才发现读写压力巨大。这时候就需要考虑Redis的集群方案了。Redis主要有三种集群模式主从复制、哨兵模式和集群模式。主从模式就像是一个老师带多个学生老师负责写学生负责读但老师请假了全班就停课。哨兵模式像是给班级配了班主任老师请假了会自动选个学生当新老师。而我们要重点讲的集群模式更像是把班级分成多个小组每个小组都有自己的老师和学生即使一个小组停课也不影响其他小组。三主三从架构最大的优势在于高可用性和数据分片。我去年给一个电商项目部署这套架构时正好遇到双十一大促期间有台服务器宕机但用户完全没感知因为系统自动完成了故障转移。具体来说三主三从有这些特点数据自动分片16384个槽位平均分配给三个主节点每个节点只负责部分数据故障自动转移当主节点不可用时对应的从节点会自动升级为主节点读写分离写操作走主节点读操作可以分散到从节点线性扩展需要扩容时只需要增加新的主从节点即可2. 三台服务器的环境准备与资源配置在实际部署前我们需要准备好三台服务器。我建议使用相同配置的机器避免出现性能瓶颈。去年我遇到一个坑三台机器内存配置不一致结果内存小的那台经常触发持久化导致集群性能不稳定。2.1 服务器基础配置每台服务器建议最低配置CPU4核以上内存8GB以上具体取决于数据量磁盘50GB以上用于持久化和日志操作系统CentOS 7.x或Ubuntu 18.04网络配置特别重要三台服务器最好在同一个局域网内我吃过跨机房的亏网络延迟导致集群经常报超时错误。确保关闭防火墙或开放Redis端口默认6379我们案例用16379/16380配置好hosts文件确保节点间能通过主机名互相访问设置SSH免密登录方便管理非必须但很实用2.2 系统参数优化这些优化项能显著提升Redis性能都是我踩过坑后总结的# 修改系统最大连接数 echo net.core.somaxconn 1024 /etc/sysctl.conf # 禁用透明大页THP否则会导致Redis延迟波动 echo never /sys/kernel/mm/transparent_hugepage/enabled # 增加TCP backlog echo net.ipv4.tcp_max_syn_backlog 1024 /etc/sysctl.conf sysctl -p3. Redis安装与多实例配置3.1 Redis安装与编译我推荐使用Redis 5.0版本因为从5.0开始官方用C重写了集群管理工具不再需要Ruby环境。下面是具体步骤# 安装依赖 yum -y install gcc-c tcl wget # 下载Redis这里以6.2.6为例 wget https://download.redis.io/releases/redis-6.2.6.tar.gz tar -zxvf redis-6.2.6.tar.gz -C /opt/ cd /opt/redis-6.2.6 # 编译安装 make make install编译时可能会遇到jemalloc报错这是内存分配器的兼容问题。我的经验是# 如果make报错尝试指定分配器 make MALLOClibc make install3.2 多实例目录准备三主三从需要每个服务器运行两个Redis实例一主一从。我习惯这样组织目录结构/opt/redis-6.2.6/ ├── 16379/ # 实例1目录 │ ├── redis.conf # 实例1配置 │ └── nodes.conf # 集群自动生成 ├── 16380/ # 实例2目录 │ ├── redis.conf │ └── nodes.conf ├── logs/ │ ├── redis-16379.log │ └── redis-16380.log └── redisdata/ ├── 16379/ # 实例1数据目录 └── 16380/ # 实例2数据目录创建这些目录的命令mkdir -p /opt/redis-6.2.6/{16379,16380,logs,redisdata/16379,redisdata/16380}4. 集群配置与优化技巧4.1 关键配置参数详解每个实例的redis.conf需要精心配置这是我优化过的配置模板# 基本配置 bind 192.168.100.21 # 改为本机IP port 16379 # 实例端口 daemonize yes # 后台运行 pidfile /var/run/redis_16379.pid # 持久化配置 dir /opt/redis-6.2.6/redisdata/16379 appendonly yes # 开启AOF appendfsync everysec # 折衷的持久化策略 # 集群配置 cluster-enabled yes cluster-config-file nodes-16379.conf cluster-node-timeout 15000 # 节点超时时间(毫秒) # 性能优化 tcp-backlog 1024 maxclients 10000 repl-backlog-size 128mb # 复制积压缓冲区大小特别注意这几个参数cluster-node-timeout设置太短会导致频繁主从切换太长则故障发现慢repl-backlog-size从节点断开重连后靠这个缓冲区做增量同步maxmemory-policy内存淘汰策略根据业务特点选择4.2 启动实例与检查在三台服务器上分别启动两个实例# 启动实例 redis-server /opt/redis-6.2.6/16379/redis.conf redis-server /opt/redis-6.2.6/16380/redis.conf # 检查是否启动成功 ps -ef | grep redis netstat -tnlp | grep redis常见问题排查端口冲突检查是否有其他Redis实例占用相同端口权限问题确保Redis用户有数据目录的写权限绑定IP错误如果无法远程连接检查bind配置5. 创建三主三从集群5.1 使用redis-cli创建集群Redis 5.0版本创建集群非常简单一条命令搞定redis-cli --cluster create \ 192.168.100.21:16379 192.168.100.22:16379 192.168.100.23:16379 \ 192.168.100.21:16380 192.168.100.22:16380 192.168.100.23:16380 \ --cluster-replicas 1--cluster-replicas 1表示每个主节点有1个从节点。执行后会显示槽位分配方案 Performing hash slots allocation on 6 nodes... Master[0] - Slots 0 - 5460 Master[1] - Slots 5461 - 10922 Master[2] - Slots 10923 - 16383 Adding replica 192.168.100.22:16380 to 192.168.100.21:16379 Adding replica 192.168.100.23:16380 to 192.168.100.22:16379 Adding replica 192.168.100.21:16380 to 192.168.100.23:16379输入yes确认配置后集群会自动完成节点握手和槽位分配。5.2 集群状态验证创建完成后务必检查集群状态# 连接任意节点 redis-cli -h 192.168.100.21 -p 16379 -c # 检查集群状态 cluster info # 正常应该看到cluster_state:ok # 查看节点信息 cluster nodes健康的集群应该显示3个master节点状态为master3个slave节点状态为slave所有16384个槽位都被分配cluster_slots_assigned:163845.3 设置集群密码为了提高安全性建议给集群设置密码# 依次连接每个节点执行 config set masterauth YourPassword123 config set requirepass YourPassword123 config rewrite注意所有节点必须使用相同的密码否则会导致节点间通信失败。6. 集群管理与维护技巧6.1 日常监控命令我习惯用这些命令监控集群健康状态# 查看集群信息 redis-cli --cluster info 192.168.100.21:16379 # 检查集群状态 redis-cli --cluster check 192.168.100.21:16379 # 查看节点内存使用情况 redis-cli -h 192.168.100.21 -p 16379 info memory | grep used_memory_human6.2 常见故障处理场景1主节点宕机自动恢复从节点会自动升级为主节点手动恢复原主节点恢复后执行cluster failover让其变为从节点场景2集群出现裂脑# 重置出问题的节点 redis-cli --cluster fix 192.168.100.21:16379场景3槽位分配不均# 重新平衡槽位 redis-cli --cluster rebalance --cluster-threshold 2 192.168.100.21:163796.3 性能优化建议合理设置超时时间cluster-node-timeout 15000 # 15秒太短会导致频繁主从切换太长则故障发现慢监控慢查询# 设置慢查询阈值(毫秒) config set slowlog-log-slower-than 10000 # 查看慢查询 slowlog get 10内存优化使用hash类型存储小对象设置合理的maxmemory和淘汰策略考虑使用redis-cli --cluster memkeys分析内存热点7. 客户端连接最佳实践7.1 连接池配置Java客户端示例LettuceRedisClusterConfiguration config new RedisClusterConfiguration( Arrays.asList( new RedisNode(192.168.100.21, 16379), new RedisNode(192.168.100.22, 16379), new RedisNode(192.168.100.23, 16379) ) ); config.setPassword(YourPassword123); LettuceConnectionFactory factory new LettuceConnectionFactory(config); factory.setShareNativeConnection(false); // 每个线程独立连接 factory.setPoolConfig(new GenericObjectPoolConfig() {{ setMaxTotal(100); // 最大连接数 setMaxIdle(20); // 最大空闲连接 }}); factory.afterPropertiesSet();7.2 读写分离实现Spring Boot配置示例spring: redis: cluster: nodes: 192.168.100.21:16379,192.168.100.22:16379,192.168.100.23:16379 max-redirects: 3 password: YourPassword123 lettuce: pool: max-active: 100 max-idle: 20 min-idle: 5 read-from: REPLICA_PREFERRED # 优先从从节点读取7.3 跨语言客户端注意事项Python (redis-py)from rediscluster import RedisCluster startup_nodes [{host: 192.168.100.21, port: 16379}] rc RedisCluster(startup_nodesstartup_nodes, passwordYourPassword123, decode_responsesTrue)Go (go-redis)rdb : redis.NewClusterClient(redis.ClusterOptions{ Addrs: []string{192.168.100.21:16379, 192.168.100.22:16379, 192.168.100.23:16379}, Password: YourPassword123, })所有客户端都需要支持集群重定向MOVED/ASK和自动连接故障转移。