手把手教你搭建一个redis集群
脚本部署
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| #!/bin/bash # auto start redis program mkdir /usr/local/redis cd /usr/local/redis tar -zxvf /redis-5.0.4.tar.gz cd redis-5.0.4/src # 编译 make make MALLOC=libc # 让端口可用 firewall-cmd --add-port=16379/tcp --permanent firewall-cmd --add-port=6379/tcp --permanent mkdir /usr/local/redis/data # 把redis。conf配置文件复制到src文件夹下 cp /usr/local/redis/redis-5.0.4/redis.conf /usr/local/redis/redis-5.0.4/src mkdir /usr/local/redis/log # 修改日志文档 sed -i 's/logfile ""/logfile \/usr\/local\/redis\/log\/redis.log/g' redis.conf # redis在后台运行 sed -i 's/daemonize no/daemonize yes/g' redis.conf # 修改bind的ip地址 sed -i 's/bind 127.0.0.1/bind 0.0.0.0/g' redis.conf # 设定开始故障转移的时间 sed -i 's/# cluster-node-timeout 15000/cluster-node-timeout 15000/g' redis.conf # 判断是否有故障转移的资格 sed -i 's/# cluster-replica-validity-factor 10/cluster-replica-validity-factor 10/g' redis.conf # 确定故障转移需要几个节点 sed -i 's/# cluster-migration-barrier 1/cluster-migration-barrier 1/g' redis.conf # 修改dir文件目录 sed -i 's/dir .\//dir \/usr\/local\/redis\/data/g' redis.conf # 开启集群模式 sed -i 's/# cluster-enabled yes/cluster-enabled yes/g' redis.conf # 启动redis服务 /usr/local/redis/redis-5.0.4/src/redis-server /usr/local/redis/redis-5.0.4/src/redis.conf #集群搭建 /usr/local/redis/redis-5.0.4/src/redis-cli --cluster create 192.100.3.90:6379 192.100.3.91:6379 192.100.3.92:6379 --cluster-replicas 0
|
docker部署
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| #拉取镜像 docker pull redis:5.0.2 #创建容器 docker create --name redis-node01 --net host -v /data/redis-data/node01:/data redis:5.0.2 --cluster-enabled yes --cluster-config-file nodes-node-01.conf --port 6379 docker create --name redis-node02 --net host -v /data/redis-data/node02:/data redis:5.0.2 --cluster-enabled yes --cluster-config-file nodes-node-02.conf --port 6380 docker create --name redis-node03 --net host -v /data/redis-data/node03:/data redis:5.0.2 --cluster-enabled yes --cluster-config-file nodes-node-03.conf --port 6381 #启动容器 docker start redis-node01 redis-node02 redis-node03 #进入redis-node01容器进行操作 docker exec -it redis-node01 /bin/bash #172.16.55.185是主机的ip地址 redis-cli --cluster create 172.16.55.185:6379 172.16.55.185:6380 172.16.55.185:6381 --cluster-replicas 0
|
Redis5 高可用集群
概述
HA(High Available,高可用性群集)机集群系统简称,是保证业务连续性的有效解决方案,一般有两个或两个以上的节点,且分为活动节点及备用节点。通常把正在执 行业务的称为活动节点,而作为活动节点的一个备份的则称为备用节点。当活动节点出现问题,导致正在运行的业务(任务)不能正常运行时,备用节点此时就会侦测到,并立即接续活动节点来执行业务。从而实现业务的不中断或短暂中断。
Redis 一般以主/从方式部署(这里讨论的应用从实例主要用于备份,主实例提供读写)该方式要实现 HA 主要有如下几种方案:
- keepalived: 通过 keepalived 的虚拟 IP,提供主从的统一访问,在主出现问题时, 通过 keepalived 运行脚本将从提升为主,待主恢复后先同步后自动变为主,该方案的好处是主从切换后,应用程序不需要知道(因为访问的虚拟 IP 不变),坏处是引入 keepalived 增加部署复杂性,在有些情况下会导致数据丢失
- zookeeper: 通过 zookeeper 来监控主从实例, 维护最新有效的 IP, 应用通过 zookeeper 取得 IP,对 Redis 进行访问,该方案需要编写大量的监控代码
- sentinel: 通过 Sentinel 监控主从实例,自动进行故障恢复,该方案有个缺陷:因为主从实例地址( IP & PORT )是不同的,当故障发生进行主从切换后,应用程序无法知道新地址,故在 Jedis2.2.2 中新增了对 Sentinel 的支持,应用通过
redis.clients.jedis.JedisSentinelPool.getResource()
取得的 Jedis 实例会及时更新到新的主实例地址
![img]()
注意: sentinel 是解决 HA 问题的,cluster 是解决主从复制问题的,不重复,并且经常一起用
Redis Sentinel
Redis 集群可以在一组 redis 节点之间实现高可用性和 sharding。在集群中会有 1 个 master 和多个 slave 节点。当 master 节点失效时,应选举出一个 slave 节点作为新的 master。然而 Redis 本身 (包括它的很多客户端) 没有实现自动故障发现并进行主备切换的能力,需要外部的监控方案来实现自动故障恢复。
Redis Sentinel 是官方推荐的高可用性解决方案。它是 Redis 集群的监控管理工具,可以提供节点监控、通知、自动故障恢复和客户端配置发现服务。
![img]()
基于 Docker 安装 Redis 集群
2018 年 10 月 Redis 发布了稳定版本的 5.0 版本,推出了各种新特性,其中一点是放弃 Ruby 的集群方式,改为 使用 C 语言编写的 redis-cli
的方式,使集群的构建方式复杂度大大降低
下载所需镜像
- Redis (5.x 测试有效):
docker pull redis
- Redis Trib (用于创建集群):
docker pull zvelo/redis-trib
创建配置文件
官方配置文件地址:http://download.redis.io/redis-stable/redis.conf ,我们部署 3 个节点,需要分别创建 3 个配置文件,路径如下
- renode1:
cluster/node1/redis.conf
- renode2:
cluster/node2/redis.conf
- renode3:
cluster/node3/redis.conf
配置文件内容如下 (端口号不要重复)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| bind 0.0.0.0 # 关闭保护模式 protected-mode no # 绑定自定义端口 port 6379 # 禁止 Redis 后台运行 # daemonize yes pidfile /var/run/redis_6379.pid # 开启集群 cluster-enabled yes # 集群的配置,配置文件首次启动自动生成 cluster-config-file nodes_6379.conf # 开启 AOF # appendonly yes # 集群的 IP cluster-announce-ip 192.168.x.x # 集群的端口 cluster-announce-port 6379 # 集群的总线端口 cluster-announce-bus-port 16379
|
创建资源配置
docker-compose.yml
配置文件如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| version: '3.1' services: renode1: image: redis container_name: renode1 restart: always ports: - 6379:6379 - 16379:16379 volumes: - ./cluster/node1:/usr/local/etc/redis command: redis-server /usr/local/etc/redis/redis.conf renode2: image: redis container_name: renode2 restart: always ports: - 6380:6380 - 16380:16380 volumes: - ./cluster/node2:/usr/local/etc/redis command: redis-server /usr/local/etc/redis/redis.conf renode3: image: redis container_name: renode3 restart: always ports: - 6381:6381 - 16381:16381 volumes: - ./cluster/node3:/usr/local/etc/redis command: redis-server /usr/local/etc/redis/redis.conf
|
创建集群
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| docker run --rm -it zvelo/redis-trib create 192.168.141.220:6379 192.168.141.220:6380 192.168.141.220:6381 # 输出如下 >>> Creating cluster >>> Performing hash slots allocation on 3 nodes... Using 3 masters: 192.168.141.220:6379 192.168.141.220:6380 192.168.141.220:6381 M: 9250c85592b7bb8a19636b90e4cf22590bd3334f 192.168.141.220:6379 slots:0-5460 (5461 slots) master M: 7373de7b44ee50a1e4f653bfba1bb808138e7e3a 192.168.141.220:6380 slots:5461-10922 (5462 slots) master M: ec7e6e4cdd142249e3aa83541044932655d75b66 192.168.141.220:6381 slots:10923-16383 (5461 slots) master Can I set the above configuration? (type 'yes' to accept): yes >>> Nodes configuration updated >>> Assign a different config epoch to each node >>> Sending CLUSTER MEET messages to join the cluster Waiting for the cluster to join.. >>> Performing Cluster Check (using node 192.168.141.220:6379) M: 9250c85592b7bb8a19636b90e4cf22590bd3334f 192.168.141.220:6379 slots:0-5460 (5461 slots) master M: 7373de7b44ee50a1e4f653bfba1bb808138e7e3a 192.168.141.220:6380 slots:5461-10922 (5462 slots) master M: ec7e6e4cdd142249e3aa83541044932655d75b66 192.168.141.220:6381 slots:10923-16383 (5461 slots) master [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered.
|
验证集群是否成功
1
| docker exec -it renode1 /bin/bash
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| 127.0.0.1:6379> cluster info # 输出如下 cluster_state:ok cluster_slots_assigned:16384 cluster_slots_ok:16384 cluster_slots_pfail:0 cluster_slots_fail:0 cluster_known_nodes:3 cluster_size:3 cluster_current_epoch:3 cluster_my_epoch:1 cluster_stats_messages_ping_sent:860 cluster_stats_messages_pong_sent:870 cluster_stats_messages_sent:1730 cluster_stats_messages_ping_received:868 cluster_stats_messages_pong_received:860 cluster_stats_messages_meet_received:2 cluster_stats_messages_received:1730
|
1 2 3 4 5
| 127.0.0.1:6379> cluster nodes # 输出如下 ec7e6e4cdd142249e3aa83541044932655d75b66 192.168.141.220:6381@16381 master - 0 1569665070102 3 connected 10923-16383 7373de7b44ee50a1e4f653bfba1bb808138e7e3a 192.168.141.220:6380@16380 master - 0 1569665069094 2 connected 5461-10922 9250c85592b7bb8a19636b90e4cf22590bd3334f 192.168.141.220:6379@16379 myself,master - 0 1569665069000 1 connected 0-5460
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| 27.0.0.1:6379> cluster slots # 输出如下 1) 1) (integer) 10923 2) (integer) 16383 3) 1) "192.168.141.220" 2) (integer) 6381 3) "ec7e6e4cdd142249e3aa83541044932655d75b66" 2) 1) (integer) 5461 2) (integer) 10922 3) 1) "192.168.141.220" 2) (integer) 6380 3) "7373de7b44ee50a1e4f653bfba1bb808138e7e3a" 3) 1) (integer) 0 2) (integer) 5460 3) 1) "192.168.141.220" 2) (integer) 6379 3) "9250c85592b7bb8a19636b90e4cf22590bd3334f"
|
基于 Docker 安装 Redis Sentinel
创建配置文件
我们部署 3 个 Sentinel 节点,需要分别创建 3 个配置文件,路径如下
- resentinel1:
cluster/node1/sentinel.conf
- resentinel2:
cluster/node2/sentinel.conf
- resentinel3:
cluster/node3/sentinel.conf
配置文件内容如下 (端口号不要重复)
1 2 3 4 5 6 7 8 9
| bind 0.0.0.0 port 26379 dir /tmp # 自定义集群名,其中 192.168.141.220 为 Redis Master 的 IP,6379 为 Redis Master 的端口,2 为最小投票数(因为有 3 台 Sentinel 所以可以设置成 2) sentinel monitor rmaster 192.168.141.220 6379 2 sentinel down-after-milliseconds rmaster 30000 sentinel parallel-syncs rmaster 1 sentinel failover-timeout rmaster 180000 sentinel deny-scripts-reconfig yes
|
创建资源配置
docker-compose.yml
配置文件如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| version: '3.1' services: resentinel1: image: redis container_name: resentinel1 ports: - 26379:26379 command: redis-sentinel /usr/local/etc/redis/sentinel.conf volumes: - ./cluster/node1/sentinel.conf:/usr/local/etc/redis/sentinel.conf resentinel2: image: redis container_name: resentinel2 ports: - 26380:26380 command: redis-sentinel /usr/local/etc/redis/sentinel.conf volumes: - ./cluster/node2/sentinel.conf:/usr/local/etc/redis/sentinel.conf resentinel3: image: redis container_name: resentinel3 ports: - 26381:26381 command: redis-sentinel /usr/local/etc/redis/sentinel.conf volumes: - ./cluster/node3/sentinel.conf:/usr/local/etc/redis/sentinel.conf
|
验证集群是否成功
1
| docker exec -it resentinel1 /bin/bash
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| 127.0.0.1:26379> sentinel master rmaster # 输出如下 1) "name" 2) "rmaster" 3) "ip" 4) "192.168.141.220" 5) "port" 6) "6379" 7) "runid" 8) "30055483aeb9d75f35c0046aaec03440731e3e88" 9) "flags" 10) "master" 11) "link-pending-commands" 12) "0" 13) "link-refcount" 14) "1" 15) "last-ping-sent" 16) "0" 17) "last-ok-ping-reply" 18) "413" 19) "last-ping-reply" 20) "413" 21) "down-after-milliseconds" 22) "30000" 23) "info-refresh" 24) "2878" 25) "role-reported" 26) "master" 27) "role-reported-time" 28) "143537" 29) "config-epoch" 30) "0" 31) "num-slaves" 32) "0" 33) "num-other-sentinels" 34) "2" 35) "quorum" 36) "2" 37) "failover-timeout" 38) "180000" 39) "parallel-syncs" 40) "1"
|