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

本贴最后更新于 1402 天前,其中的信息可能已经沧海桑田

置顶.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 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。从 2010 年 3 月 15 日起,Redis 的开发工作由 VMware 主持。从 2013 年 5 月开始,Redis 的开发由 Pivotal 赞助。

    284 引用 • 247 回帖 • 176 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...