redis的sentinel和cluster简介
1、redis哨兵(Sentinel)
1.1、原理
类似于mysql的MHA,实现故障转移,当主节点出现故障则将从节点提升为主节点,并将其他从节点指向新提升的主节点
可多次使用,不像MHA的一次性
可以将哨兵sentinel当成DNS,客户端不是直接连接的redis主从,而是先连接的哨兵,哨兵在根据请求进行指引,哨兵安装多个
故障转移:
- 多个sentinel哨兵发现并确认主节点有问题
- 选举出一个sentinel哨兵作为领导来进行后续操作
- 选择一个从节点提升为主节点
- 将其他从节点指向新的主节点
- 通知客户端主从变化
- 将修复好后的损坏的主节点作为新主的从节点
节约成本可将sentinel和redis安装在同一个主机,sentinel有专门的进程来监控redis集群的工作状态;sentinel进程通过流言协议来沟通接收主节点是否下线状态,并使用投票协议来决定是否进行故障转移;每个sentinel进程都会向其他sentinel、master、slave定时发送消息来确认对方是否健康存活
各自,单个的sentinel进程认为主节点宕机称为主观宕机SDOWN
多数的sentinel进程认为主节点宕机称为客观宕机ODOWN,接下来利用投票算法来选举出一个sentinel哨兵作为领导来执行故障转移操作
redis集群中的sentinel节点个数应该大于等于3且为奇数
1.2、具体实现
1.2.1、环境准备
redis集群:三台主机,一主10.0.0.8两从10.0.0.9、10.0.0.10,在集群的每台主机上都配置sentinel
#在所有主机上
[root@rocky2 ~]#yum -y install redis
[root@rocky2 ~]#vim /etc/redis.conf
bind 0.0.0.0
masterauth "123456" #确保集群内的切换密码均一致,便于管理
requirepass "123456"
#在所有从节点上10.0.0.9、10.0.0.10
[root@rocky2 ~]#echo "REPLICAOF 10.0.0.8 6379" >> /etc/redis.conf
#在所有主机上
[root@rocky2 ~]#systemctl restart redis
1.2.2、配置sentinel
[root@10.0.0.8 ~]#vim /etc/redis-sentinel.conf
bind 0.0.0.0
daemonize yes
logfile "/var/log/redis/sentinel.log"
sentinel monitor mymaster 10.0.0.8 6379 2
sentinel auth-pass mymaster 123456
sentinel down-after-milliseconds mymaster 3000
#在其他主机上进行相同更改步骤,也可rsync拷贝
#更改配置文件完成保存后,配置文件中自动生成sentinel myid选项,跟启动相关,集群内的myid值需各不相同,如相同需手动更改为不同值
1.2.3、sentinel配置文件格式
#如果是编译安装,将源码目录下的sentinel.conf文件拷贝到redis安装路径下更改文件属性即可
[root@rocky2 ~]#vim /etc/redis-sentinel.conf
bind 0.0.0.0 #连接地址
port 26379 #默认端口
daemonize yes #后台执行sentinel
pidfile "redis-sentinel.pid"
logfile "sentinel_26379.log"
dir "/tmp" #工作目录
sentinel monitor mymaster 10.0.0.8 6379 2
#告诉sentinel当前redis主从复制中的主节点,mymaster是当前监控的集群的名称,可自定义,可监控多组集群
#2是认为客观宕机的sentinel决定人数,全部sentinel数量/2,向后取整值
sentinel auth-pass mymaster 123456
#redis集群中的主节点的密码,注意这行要放在上面行的下面
sentinel down-after-milliseconds mymaster 30000
#sentinel主观判断集群mymaster中所有节点下线的时间,单位毫秒,建议减小
sentinel parallel-syncs mymaster 1
#发生故障转移后,可以同时向新主节点同步数据的从节点数量,数字越小总同步时间越长,但可以减轻新主节点的负载压力
sentinel failover-timeout mymaster 180000
#所有从节点指向新主节点所需的超时时间,超过时间还未连接则判断该从节点损坏,单位毫秒
sentinel deny-scripts-reconfig yes #禁止修改脚本,不用动它
logfile /var/log/redis/sentinel.log #日志文件
1.2.4、启动sentinel
在所有主机上
#yum安装使用systemctl控制即可
systemctl start redis-sentinel.service
#如编译安装
#方法1,用安装路径下的文件来启动,启动程序后面跟配置文件
/apps/redis/bin/redis-sentinel /apps/redis/etc/sentinel.conf
#方法2,写service文件
vim /lib/systemd/system/redis-sentinel.service
[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
1.2.5、检查sentinel状态
[root@10.0.0.8 ~]#redis-cli -p 26379
127.0.0.1:26379> info Sentinel #查看sentinel状态
# Senti nel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok, address=10.0.0.8:6379,slaves=2,sentinels=3
#两个slave,三个sentinel服务器,如果sentinels值不符合,检查myid可能冲突
2、redis cluster
将数据分区、分块,再分别存放在不同节点上,解决单机性能的瓶颈,支持多个主节点并行写入和故障转移
类似于年级,将一个学校里的学生根据年级分别安排在不同的教室里
cluster模式下的数据库为单一数据库
2.1、redis cluster架构
- Redis dluster需要至少3个master节点财能实现,slave节点数量不限,当然一般每 个master都至少对应的有一个slave节点
- 如果有三个主节点采用哈希槽hash slot的方式来分配16384个槽位slot,类似于仓库,类别
- 此三个节点分别承担的slot区间可以是如以下方式分配,对key使用CRC16计算对16384取余数,再分配
- 内部自带sentinel功能,且互相配套
#不是绝对值
节点M1 0-5460
节点M2 5461-10922
节点M3 10923-16383
2.1.1、虚拟槽分区
寻找槽的过程并不是一次就命中的,客户端访问redis时会先随机连接其中一个节点,
当将key进行CRC运算后该节点会返回key所在槽位的相对应节点信息,然后客户端才访问相对应的节点;集群redis中节点之间的通信,保证了最多两次就能访问到槽位相对应所在的节点,
集群中的所有节点通过meet操作来建立联系,A对B,A对C,B通过A认识C,所有节点都能建立联系,互相知道对方负责哪些槽位
2.1.2、数据分区
分布方式 | 顺序分布,均匀性 | 哈希分布 |
---|---|---|
数据分散度 | 分布倾斜 | 分布散列 |
顺序访问 | 支持 | 不支持 |
- 顺序分布保障了数据的有序性,但是离散性低,可能导致某个分区的数据热度高,其他分区数据的热度低,分区访问不均衡。
- 哈希分布也分为多种分布方式,比如区域哈希分区,一致性哈希分区等。 而redis cluster采用的是虚拟槽分区的方式。
2.2、redis cluster管理
2.2.1、扩容
建议节点数为奇数
10.0.0.68
10.0.0.78
在需要添加的主节点上:
[root@rocky2 ~]#yum -y install redis
[root@rocky2 ~]#sed -i.bak -e 's/bind 127.0.0.1/bind 0.0.0.0/' -e '/masterauth/a masterauth 123456'-e '/requirepass/a requirepass 123456' -e '/# cluster-enabled yes/a cluster-enabled yes' -e '/# cluster-config-file nodes-6379.conf/a cluster-config-file nodes-6379.conf' -e '/cluster-require-full-coverage yes/c cluster-require-full-coverage no' /etc/redis.conf
[root@rocky2 ~]#systemctl restart redis
#--cluster add-node添加新节点10.0.0.68:6379,指定添加到哪个集群中10.0.0.8:6379,集群内任意ip即可
[root@rocky2 ~]#redis-cli -a 123456 --cluster add-node 10.0.0.68:6379 10.0.0.8:6379
#--cluster reshard重新分配槽位,指定集群内任意节点10.0.0.8:6379即可
[root@rocky2 ~]#redis-cli -a 123456 --cluster reshard 10.0.0.8:6379
#执行后会出现交互式问答
#1:需分配多少槽位给新节点,16384/集群主节点数
#2:新节点的id,一长串的数字字母结合那段复制粘贴即可,71be23364ff74a979bb3e63950245e4c8eef1fe4
#3:分配的槽位从哪来?一个是all每个节点均分,另一个是从单一节点分配,所有槽位都从那一个节点分,写节点id,一般用all即可
#4:确认该分配方案吗?yes
在所需添加的从节点上:
[root@rocky2 ~]#yum -y install redis
[root@rocky2 ~]#sed -i.bak -e 's/bind 127.0.0.1/bind 0.0.0.0/' -e '/masterauth/a masterauth 123456'-e '/requirepass/a requirepass 123456' -e '/# cluster-enabled yes/a cluster-enabled yes' -e '/# cluster-config-file nodes-6379.conf/a cluster-config-file nodes-6379.conf' -e '/cluster-require-full-coverage yes/c cluster-require-full-coverage no' /etc/redis.conf
[root@rocky2 ~]#systemctl restart redis
#一步到位,可在集群内任一主机执行均可
#指定新添加节点--cluster add-node 10.0.0.78:6379到集群(任一节点即可)10.0.0.8:6379中,--cluster-slave设置为从节点,--cluster-master-id指定新添加从节点的主节点的id,即绑定主节点
[root@rocky2 ~]#redis-cli -a 123456 --cluster add-node 10.0.0.78:6379 10.0.0.8:6379 --cluster-slave --cluster-master-id 71be23364ff74a979bb3e63950245e4c8eef1fe4
查看集群状态
[root@rocky2 ~]#redis-cli -a 123456 cluster nodes
2.2.2、缩容
跟扩容所需面临情况相反,槽位,数据等等
在需缩容主节点上
#缩容后集群内还有多少节点就迁移几次,且需计算迁移槽位数,缩容节点槽位数/缩容后集群内节点数
[root@rocky2 ~]#redis-cli -a 123456 --cluster reshard 10.0.0.8:6379
#1:需分配多少槽位给新节点,缩容节点槽位数/缩容后集群内节点数
#2:节点的id,指定迁移槽位到哪个节点,71be23364ff74a979bb3e63950245e4c8eef1fe4
#3:分配的槽位从哪来?指定需要缩容的节点id,71be23364ff74a979bb3e63950245e4c8eef1fe4,done
#4:确认该分配方案吗?yes
#执行多次
#查看迁移情况
[root@rocky2 ~]#redis-cli -a 123456 cluster nodes
#注意需先下线从节点,如先下线主节点会有故障转移操作
#从集群中删除节点,指定集群(任一节点都可)10.0.0.68:6379,后面跟上需要删除的节点id
[root@rocky2 ~]#redis-cli -a 123456 --cluster del-node 10.0.0.68:6379 71be23364ff74a979bb3e63950245e4c8eef1fe4
#删除从节点,直接执行删除即可
[root@rocky2 ~]#redis-cli -a 123456 --cluster del-node 10.0.0.68:6379 71be23364ff74a979bb3e63950245e4c8eef1fe4