Redis高可用之哨兵模式、集群
一、Redis哨兵模式
1.简介
主从模式,当主节点宕机之后,从节点是可以作为主节点顶上来,继续提供服务的。
但是有一个问题,主节点的IP已经变动了,此时应用服务还是拿着原主节点的地址去访问,这…
于是,在Redis 2.8版本开始引入,就有了哨兵这个概念。
哨兵模式的核心功能是在主从复制的基础上,引入了主节点的自动故障转移。
端口号:26379
2.哨兵模式的作用
1)监控:哨兵会不断地检查主节点和从节点是否运作正常。
2)自动故障转移:当主节点不能正常工作时,哨兵会开始自动故障转移操作,它会将失效主节点的其中一个从节点升级为新的主节点,并让其它从节点改为复制新的主节点。
3)通知(提醒):哨兵可以将故障转移的结果发送给客户端。
3.哨兵结构
哨兵结构由两部分组成,哨兵节点和数据节点
哨兵节点:哨兵系统由一个或多个哨兵节点组成,哨兵节点是特殊的redis节点,不存储数据。
数据节点:主节点和从节点都是数据节点。
4.故障转移机制(重要)
1.由哨兵节点定期监控发现主节点是否出现了故障。
每个哨兵节点每隔1秒会向主节点、从节点及其它哨兵节点发送一次ping命令做一次心跳检测。
如果主节点在一定时间范围内不回复或者是回复一个错误消息,那么这个哨兵就会认为这个主节点主观下线了(单方面的)。
当超过半数哨兵节点认为该主节点主观下线了,这样就客观下线了。
2.当主节点出现故障,此时哨兵节点会通过Raft算法(选举算法)实现选举机制共同选举出一个哨兵节点为leader,来负责处理主节点的故障转移和通知。
所以整个运行哨兵的集群的数量不得少于3个节点。
3.由leader哨兵节点执行故障转移。
##故障转移过程##
将某一个从节点升级为新的主节点,让其它从节点指向新的主节点;
若原主节点恢复也变成从节点,并指向新的主节点;
通知客户端主节点已经更换。
客观下线是主节点才有的概念;
如果从节点和哨兵节点发生故障,被哨兵主观下线后,不会再有后续的客观下线和故障转移操作。
5.主节点选举机制
1)过滤掉不健康的(已下线的),没有回复哨兵 ping 响应的从节点。
2)选择配置文件中从节点优先级配置最高的。(replica-priority,默认值为100)
3)选择复制偏移量最大,也就是复制最完整的从节点。
二、部署Redis哨兵模式
节点服务器 | IP地址 |
---|---|
Master | 192.168.100.146 |
Slave1 | 192.168.100.150 |
Slave2 | 192.168.100.155 |
sentinel配置
Sentinel实际上是一个特殊的redis服务器,有些redis指令支持,但很多指令并不支持.默认监听在26379/tcp端口.
哨兵可以不和Redis服务器部署在一起,但一般部署在一起以节约成本
所有redis节点使用相同的以下示例的配置文件
#如果是编译安装,在源码目录有sentinel.conf,复制到安装目录即可, cp /data/redis-5.0.7/sentinel.conf /apps/redis/etc/ [root@centos7 ~]#vim /apps/redis/etc/sentinel.conf bind 0.0.0.0 #修改监听端口 port 26379 #不用修改默认 daemonize yes # 不用修改如果是systemd 启动模式, 修改后启动不了 pidfile "/apps/resdis/run/redis-sentinel.pid" #指定pid文件 logfile "/apps/redis/log/sentinel.log" # 指定日志文件 dir "/tmp" #工作目录不用修改 sentinel monitor mymaster 10.0.0.8 6379 2 #mymaster是集群的名称,此行指定当前mymaster集群中master服务器的地址和端口 #2为法定人数限制(quorum),即有几个sentinel认为master down了就进行故障转移,一般此值是所有sentinel节点(一般总数是>=3的 奇数,如:3,5,7等)的一半以上的整数值,比如,总数是3,即3/2=1.5,取整为2,是master的ODOWN客观下线的依据 sentinel auth-pass mymaster 123456 #mymaster集群中master的密码,注意此行要在上面行的下面 sentinel down-after-milliseconds mymaster 30000 #(SDOWN)判断mymaster集群中所有节点的主观下线的时间, 单位:毫秒,建议3000(3秒) 否则等待时间过长 sentinel parallel-syncs mymaster 1 #发生故障转移后,可以同时向新master同步数据的slave的数量,数字越小总同步时间越长,但可以减轻新master的负载压力 sentinel failover-timeout mymaster 180000 #所有slaves指向新的master所需的超时时间,单位:毫秒 sentinel deny-scripts-reconfig yes #禁止修改脚本
修改文件内容
[root@localhost etc]#grep -vE "^#|^$" sentinel.conf bind 0.0.0.0 port 26379 daemonize yes pidfile /apps/redis/run/redis-sentinel.pid logfile "/apps/redis/log/sentinel.log" dir /tmp sentinel monitor mymaster 192.168.100.146 6379 2 sentinel auth-pass mymaster 123456 sentinel down-after-milliseconds mymaster 3000 sentinel parallel-syncs mymaster 1 sentinel failover-timeout mymaster 18000 sentinel deny-scripts-reconfig yes
[root@localhost etc]#cat >> /lib/systemd/system/redis-sentinel.service <<eof [Unit] Description=Redis Sentinel After=network.target [Service] ExecStart=/apps/redis/bin/redis-sentinel /apps/redis/etc/sentinel.conf --supervised systemd ExecStop=/bin/kill -s QUIT $MAINPID User=redis Group=redis RuntimeDirectory=redis RuntimeDirectoryMode=0755 [Install] WantedBy=multi-user.target eof [root@localhost etc]# systemctl daemon-reload [root@localhost etc]# systemctl start redis-sentinel.service
#或绝对路径启动
/apps/redis/bin/redis-sentinel /apps/redis/etc/sentinel.conf
关掉 主服务器验证
在主上观察日志
从上观察master变化
在sentinel状态中尤其是最后一行,涉及到masterIP是多少,有几个slave,有几个sentinels,必须是符合全部服务器数量
[root@slave1 ~]# redis-cli -p 26379 127.0.0.1:26379> INFO sentinel
#两个slave,三个sentinel服务器,如果sentinels值不符合,检查myid可能冲突
### 去看 配置文件中的 id 要所有节点不一样 [root@slave1 ~]# tail -f /apps/redis/etc/sentinel.conf
主再恢复后会变成从
三、Redis集群
假如三个主节点分别是:A, B, C 三个节点,采用哈希槽 (hash slot)的方式来分配16384个slot 的话它们三个节点分别承担的slot 区间可以是:
节点A覆盖 0-5460 节点B覆盖 5461-10922 节点C覆盖 10923-16383
3.部署Redis集群
启多实例 来实现redis
redis的集群一般需要6个节点,3主3从。方便起见,这里所有节点在同一台服务器上模拟: 以端口号进行区分:3个主节点端口号:6001/6002/6003,对应的从节点端口号:6004/6005/6006
cd /apps/redis/ mkdir -p redis-cluster/redis600{1..6}
chown redis.redis /apps/redis/redis-cluster/ -R
准备可执行文件到每个文件夹
for i in {1..6} do cp /data/redis-5.0.7/redis.conf /apps/redis/redis-cluster/redis600$i cp /data/redis-5.0.7/src/redis-cli /data/redis-5.0.7/src/redis-server /apps/redis/redis-cluster/redis600$i done
#其他5个文件夹的配置文件以此类推修改,注意6个端口都要不一样。 vim /apps/redis/redis-cluster/redis6001/redis.conf #bind 127.0.0.1 #69行,注释掉bind 项,默认监听所有网卡 protected-mode no #88行,修改,关闭保护模式 port 6001 #92行,修改,redis监听端口, daemonize yes #136行,开启守护进程,以独立进程启动 如果是 systemd 启动不需要修改 cluster-enabled yes #832行,取消注释,开启群集功能 cluster-config-file nodes-6001.conf #840行,取消注释,群集名称文件设置 cluster-node-timeout 15000 #846行,取消注释群集超时时间设置 appendonly yes #699行,修改,开启AOF持久化
#修改6001 sed -i.bak 's/bind 127.0.0.1/bind 0.0.0.0/' redis.conf sed -i.bak 's/protected-mode yes/protected-mode no/' redis.conf sed -i.bak 's/^port .*/port 6001/' redis.conf sed -i.bak 's/^daemonize .*/daemonize yes/' redis.conf sed -i.bak 's/^# cluster-enabled .*/cluster-enabled yes/' redis.conf sed -i.bak 's/^# cluster-config-file .*/cluster-config-file nodes-6001.conf/' redis.conf sed -i.bak 's/^# cluster-node-timeout .*/cluster-node-timeout 15000/' redis.conf sed -i.bak 's/appendonly no/appendonly yes/' redis.conf
cd /apps/redis/redis-cluster/redis6001 #先切换目录 #复制配置文件 for i in {2..6} do \cp -f ./redis.conf /apps/redis/redis-cluster/redis600${i} done
sed -i 's/6001/6002/' /apps/redis/redis-cluster/redis6002/redis.conf sed -i 's/6001/6003/' /apps/redis/redis-cluster/redis6003/redis.conf sed -i 's/6001/6004/' /apps/redis/redis-cluster/redis6004/redis.conf sed -i 's/6001/6005/' /apps/redis/redis-cluster/redis6005/redis.conf sed -i 's/6001/6006/' /apps/redis/redis-cluster/redis6006/redis.conf
分别进入那六个文件夹,执行命令:redis-server redis.conf ,来启动redis节点
systemctl stop redis # 先停止之前的服务 ss -natp |grep 6379
cd /etc/redis/redis-cluster/redis6001 # 切换目录 redis-server redis.conf # 启动 #脚本去启动 for d in {1..6} do cd /apps/redis/redis-cluster/redis600$d redis-server redis.conf done
ps -ef | grep redis
ss -natp |grep "\b600[1-6]\b"
redis-cli --cluster create 127.0.0.1:6001 127.0.0.1:6002 127.0.0.1:6003 127.0.0.1:6004 127.0.0.1:6005 127.0.0.1:6006 --cluster-replicas 1 #六个实例分为三组,每组一主一从,前面的做主节点,后面的做从节点。下面交互的时候 需要输入 yes 才可以创建。 --replicas 1 表示每个主节点有1个从节点。
redis-cli -p 6001 -c #加-c参数,节点之间就可以互相跳转
set name hx # 对name 键进行算法 得出 值 为 5789 跳到对应的节点存储
cluster keyslot name #查看name键的槽编号
cluster nodes