redis进阶---redis集群(二):(哨兵、集群)

2020-06-22

置顶.png

一、引入:

顶上的图好看不,我觉得挺好看的,好了废话不多说,开搞💩 :

之前在的服务器一直一单机的形式呈现,然后就会出现中断啊、宕机等等其他问题,然后用主从复制进行弥补、在主从复制中我们说到,slave哪怕1-2台宕机了,依旧还能够正常工作(slave数量大于3).但是我们在主从复制的时候并没有说到master宕机的情况,那master宕机了怎么办呢?那我们一起来看看接下来的内容:



二、哨兵

1.定义

哨兵是一个分布式系统,用于对蛀虫结构中的每台服务器进行 监控 ,当出现故障时通过投票机制选择新的master并将所有的slave连接到master上

2.作用

  • 监控:
    不断检查master与slave是否能够正常运行
    master存活检测,master与slave运行情况检测
  • 通知(提醒):当被监控的服务器出现问题时,向其他(哨兵间、客户端)发送消息
  • 自动故障转移:断开master与slave连接,选取一个slave作为master,将其他slave连接到新的master,并告知客户端新的服务器地址
  • PS:哨兵也是一台redis服务器,但是它不提供任何的数据服务,哨兵通常配置数量为单数(eg:3个、5个、7个)。

3.配置哨兵

采用一拖二的主从结构、配置三个哨兵(配置相同、端口不同)

conf文件说明:

port 26379  #端口号
daemonize no   #是否要用守护线程的方式启动
pidfile /var/run/redis-sentinel.pid #进程pid文件
logfile "" #日志文件
dir /tmp   #存储哨兵信息目录
sentinel monitor mymaster 127.0.0.1 6379 2  #哨兵监控的主 2代表要至少2个表决挂了
sentinel down-after-milliseconds mymaster 30000  #主多久没响应认为挂了
sentinel parallel-syncs mymaster 1 #一个开始同步,值越小性能压力越小速度越慢
sentinel failover-timeout mymaster 180000  #超时同步设定
sentinel deny-scripts-reconfig yes

4.启动哨兵命令

redis-sentinel sentinel-端口号.conf

哨兵启动图.png

图解 :

  1. 启动命令:redis-sentinel sentinel26379.conf。sentinelxx为配置文件
  2. 当前哨兵的ID
  3. 添加了master,名称mymaster,ip、slave数量
  4. slave相关得到信息
  5. 启动第一个哨兵时不会出现,我这里启动了三个哨兵,启动后他们之间会进行一个信息的互通之后才会显示

当我们启动哨兵后,对应的conf文件也会被自动修改,会增加相关哨兵等的信息

  • 修改前:

conf文件变化前.png

  • 修改后:

conf文件改变后.png

5.哨兵工作原理

过程:监控、通知、故障转移

我们先来看一个redis运行的图:

master宕机.png

**图解:**从图中我们可以看到。在方框外的部分是哨兵正常启动后的界面,它上面有相关的哨兵id(sentinel ID is ...)之后声明了主机master相关信息(moniter master mymaster 127.0.0.1 6379 quarum 2)。接着还有slave相关信息(不介绍了)。

然后我们来看框内部分:+sdown 主机停止工作设置主机127.0.0.1 6379为sdown,然后接着确定后标志位改为+odown。这时候他们开始进行重新挑选master工作。看最后倒数三行,最后确定端口6381作为master,6380、6379作为slave....

我们看一下详细的一个过程:


阶段一:监控阶段

作用:

  • 用于同步各个节点的状态信息
  • 获取各个sentinel的状态(是否在线)
  • 获取master的状态与属性(runid、role:master、各个节点的信息)
  • 获取所有的slave状态(根据master中的slave信息)其中包括(slave属性:runid、role:slave、master_host、master_port、offset等)

哨兵监控阶段.png

上图中:sentinel需要先连接master,之后发送info指令获取master的信息。但是后期sentinel还需要与master进行信息交换啊。那要怎么办呢?

我们来看看下面这个图(只看红色部分,可能看的有点头疼)

image.png

图解:

sentinel通过cmd连接(专门发命令的)与master通信。在这个过程中sentinel还保存了哨兵的状态(SentinelState)同时在master端同时也记录redis实例信息(SentinelRedisInstance)。接着sentinel接着去连接每一个slave,全部结束后下一个sentinel重复上述的连接过程。之后为了保证多个sentinel的信息同步。于是他们建立一个通道进行发布订阅,然后做到互相之间能够信息同步。同时他们为了能够长期信息对称,他们会定时ping对方。


阶段二:通知阶段

信息的长期维护的阶段,上图中三个sentinel组成一个小的群体,它们之间信息相互互通,redis服务器在工作的过程中,sentinel通过他们建立的cmd连接,进行获取其工作状态,之后进行信息回传。获取到信息在sentinel构成的群体中进行信息互通。

通知阶段.png


阶段三:故障转移阶段

我们在进行阶段二通知的时候大家有想过这样一个问题吗?万一出现故障怎么办?我们来设想一下这样一个场景。

过程一image.png图解:其中一个sentinel给master发指令,然后发现master一直没回应,他就一直发指令,直到达到范围内回应,sentinel认为msater凉了,然后他就给它一个SRI_S_DOWN的标志位,之后回去跟其他的sentinel说:“master凉了,你们去看看(发送:sentinel is-master-down-by...)”。然后其他的sentinel发送hello没有回应。这时候大家认为master确定凉凉了,然后其他的sentinel说:“它确实凉了”(sentinel is-master-down-by...),然后就把master的标志位从SRI_S_DOWN改为SRI_O_DOWN。

过程二

然后因为master宕机了,三个哨兵就需要重新选出一个master来,那怎么选呢?

三个哨兵呢,在收到sentinel is-master-down-by-...\ip\port等信息后进行一个投票机制,超过半数了,通过以后,被选出得到sentinel去挑选新的master。

image.png

过程三:

sentinel去挑选master。具体过程与规则见下:

sentinel挑选master的规则:

  • 挑选在线的
  • 响应快的
  • 与原master断开的时间短的
  • 优先原则:优先级、offset、runid(小)

确定以后发指令:

  • 向新的master发送slaveof no one
  • 向其他的slave发送slaveof新的master ip+port

image.png


故事总结:

可能上面的没有基础的看的云里雾里的,接下来用故事来理解吧😅 。

假设一所学校有三个高度近视的:语文老师(sentinel)、数学老师(sentinel)、英语老师(sentinel)、然后每个班都有一个班长(master)还有许多的学生(slave)。有一天,语文老师去上课,发现没人喊起立了。语文老师就喊:“班长人呢~ ~班长~~”结果没人回应。然后语文老师就去和数学老师、英语老师说:“班长丢了”。这时候数学老师与英语老师去到教师喊道:“班长人呢~班长~~”,结果没人回。之后回来后三个老师就聚在一起讨论,我们要不要挑选一个班长出来。谁去挑选一个班长出来。最后决定语文老师去,语文老师来到教室里说:“我们现在来挑选一个班长,但是有以下条件。。。。有。。。可以优先考虑。。。”。最后从所有学生中挑选出来一个同学作为班长。然后语文老师宣布:“现在得到班长就是它,你们现在要听他的话”然后继续开始上课。。。😇

嗯,虽然有些地方有点不当,例如班长不在1/2节课就换个班长这个不现实,但是凑活着点理解把。你就想这个只是一个故事假设,只要班长一不再,一个班总要有班长吧。那咱就换一个就是了😅



三、集群

大家有想过吗?redis提供的服务OPS(即operation per second 每秒操作次数)可以达到10万次每秒,但如果需要20万次每秒怎么办?或者是假设单机内存为256G,可是当前的业务需求最低为1G又要怎么办?我们来看看接下来的内容:

1.定义:

使用网络将若干台计算机联通起来,并提供统一的管理方式,使其呈现单机的服务效果。

image.png

2.作用:

  • 分散单台服务器的访问压力,实现负载均衡
  • 分散单台服务器的存储压力,实现可扩展性
  • 降低单台服务器宕机带来的业务灾难
  • ...

3.redis集群架构设计

  • 数据存储设计:
    在单机中key,直接放在redis存储空间中 ,但是在集群中,要怎么办呢?
    key经过CRC16方法计算出一个值,之后对16384取模,之后获取的值就是保存的位置。而16384就是将所有的存储空间切割成为18384份(被划分后存储空间官方叫: 槽),每台主机保存一部分存储空间(槽)(需要注意这并不是key的存储空间)。将计算出的key放到对应的存储空间中。image.png
    这时候你有没有想过这样一个问题:一台计算机宕机了怎么办呢或者是新增了怎么办呢?
    如果有新加节点,他会经过计算后将原来的全部进行优化,每个redis服务器拿出一部分存储空间(槽)给新的节点。
    数据存储设计.png

    所谓的增节点、宕机其实就是改变槽所存储的位置不同。但是槽的位置改变了,我们要怎么才能直到槽的位置在哪呢?接着看集群内部通信设计:
    image.png
    图解: 假设我们存在服务器ABC,他们相互互联、相互通信,保存各个库中槽的编号数据,当key去寻找的时候,一次命中则直接返回,如果未命中告知具体的位置,然后查找返回。这样就可以做到顶多2次就能命中。

4.redis集群的搭建

  • 配置文件

废话不多说,直接改配置文件:

cluster-enabled yes|no #设置加入cluster,成为其中的节点
cluster-config-file nodes-6379.conf #cluster配置文件名,该文件属于自动生成,仅用于快速查找文件并查询文件内容 #区分不同的配置文件当在不同文件夹下就不会出现冲突,可以不配置。
cluster-node-timeout 10000 #10s判断节点是否下线或者切换为从节点
cluster-migration-barrier <count> #master连接的slave最小数量
  • 常用命令
ps -ef |grep redis #查看是否启动
cluster replicate <master-id> #进入第一个节点redis,切换其主节点
cluster meet ip:port  #发现新节点,新增节点
cluster forget <id> #忽略一个没有solt的节点
cluster failover  #手动故障移除
  reids-cli redis6379.conf   #redis6379.conf为我的的启动配置文件 

启动之后查看启动的redis服务器,对比起以前多了cluster标致:
PS启动后截图.png

我在启动过程中提示了不能够使用redis-trib进行启动提示使用redis-cli。因为我用了redis5版本:

redis-cli create 127.0.0.1:6379 127.0.0.1:6380...   --cluster-replicas 1
  #之后输入yes

成狗构建的命令.png
在启动成功之后可以看见下图的一个master与slave同步信息以及绑定:
master成功后截图.png


标题:redis进阶---redis集群(二):(哨兵、集群)
作者:sirwsl
地址:https://www.wslhome.top/articles/2020/06/22/1592827882457.html