深入Redis:哨兵的厉害

        之前的文章详细介绍了Redis的主从结构,可以有效保证了单个节点并发量过大导致的一系列问题。但是,如果某个节点出现问题了,还是需要人工处理,而人工并不是一种很及时、很靠谱的手段。要是处理的不好,很容易造成半小时一小时还没有恢复服务器的情况。而今天介绍的哨兵机制,就是通过自动化的手段来解决主节点挂了的问题。

        哨兵机制,是通过独立的进程来体现的,和redis-server是不同的进程。redis-sentinel不负责存储数据,只是对其他的redis-server进程起到监控的效果。通常哨兵节点也会搞一个集合,避免单哨兵节点挂掉~

        如果没有哨兵节点,就需要程序员自己来操作:

  • 看看主节点好不好抢救~
  • 定位是什么原因挂掉的,如果短时间无法解决,就需要挑选一个从节点,设置成新的主节点~

这就是本章讲解的重点:哨兵机制

目录

哨兵机制

docker

作用演示


哨兵机制

哨兵是单独的Redis sentinel进程,这几个哨兵进程会监视现有的redis master 和 slave,这些进程之间会建立tcp长连接,定时发送心跳包。借助这样的监控机制,就可以及时发现某个主机是否挂了:

  1. 如果主节点挂了,哨兵就会发挥作用。一个哨兵发现主节点有不对劲的地方,多个哨兵共同判断主节点是否真的挂了
  2. 如果主节点通过判断已经挂了,哨兵节点中就会推举出一个leader,这个leader负责从现有的节点中挑选一个作为新的节点
  3. 挑选出新的节点后,哨兵节点就会自动控制被选中的节点,执行 slaveof no one ,并且修改其他的节点,修改slaveof到新的主节点上
  4. 哨兵节点会自动通知客户端程序,告知新的主节点是谁,并且后续进行写操作,就会针对新的主节点进行操作了

这就引出了Redis哨兵的核心功能:监控、自动故障转移、通知。

但是,这可是有6个节点,理想情况应该部署在6个不同的服务器主机上。此处由于只有一个云服务器主机,我们用docker来避免一些端口号、配置文件等等的干扰和冲突。

docker

docker可以认为是一个轻量级的虚拟机,起到了虚拟机这样的隔离环境的效果,但是又没有吃很多的硬件资源。

docker中的关键概念:镜像  容器。类似于可执行程序和进程的关系。镜像可以自己构建,也可以直接拿别人构建好的(docker hub)。

  1. 安装docker 和docker-compose
    apt install docker-compose
  2. 停止之前的redis-server
    service redis-service stop
  3. 使用docker获取redis镜像
    docker pull redis:5.0.9

git pull 使用git从中央仓库拉取代码,docker pull 使用docker从中央仓库(默认就是docker hub)来拉取镜像。拉取到的镜像,里面包含一个精简的Linux系统,并且上面会安装好redis,只需要直接基于这个镜像创建一个容器跑起来,此时redis服务器就搭建好了。

但是,此处可是有6个节点,也就是我们会使用6个容器,此时就需要用到docker-compose来进行容器编排。通过一个具体的配置文件,把具体要创建哪一些容器,每个容器运行的各种参数描述清楚,后续通过一个简单的命令,就能够批量的启动、停止这些容器了。

  1. 创建三个容器,作为redis的数据节点,一个主节点两个从节点
  2. 创建三个容器,作为redis的哨兵节点

通过两个yml来配置。此处不用一个yml全部完成,是因为要避免6个容器同时启动,哨兵先启动判断主节点未启动造成的干扰。

配置文件

数据节点

version: '3.7'
services:
  master:
    image: 'redis:5.0.9'
    container_name: redis-master
    restart: always
    command: redis-server --appendonly yes
    ports:
      - "6379:6379"

  slave1:
    image: 'redis:5.0.9'
    container_name: redis-slave1
    restart: always
    command: redis-server --appendonly yes --slaveof redis-master 6379
    ports:
      - "6380:6379"

  slave2:
    image: 'redis:5.0.9'
    container_name: redis-slave2
    restart: always
    command: redis-server --appendonly yes --slaveof redis-master 6379
    ports:
      - "6381:6379"

在docker中,端口号和外面宿主机的端口号是两个体系,可以把容器内部的端口映射成宿主机的端口。

通过compose命令可以通过刚刚配置好的配置文件把docker启动起来

docker-compose up -d

再通过 docker ps -a就能查看到具体的节点了~已经可以查看到三个节点之间的关系

哨兵节点

配置yml

version: '3.7'
services:
  sentinel1:
    image: 'redis:5.0.9'
    container_name: redis-sentinel-1
    restart: always
    command: redis-sentinel /etc/redis/sentinel.conf
    volumes:
      - ./sentinel1.conf:/etc/redis/sentinel.conf
    ports:
      - "26379:26379"

  sentinel2:
    image: 'redis:5.0.9'
    container_name: redis-sentinel-2
    restart: always
    command: redis-sentinel /etc/redis/sentinel.conf
    volumes:
      - ./sentinel2.conf:/etc/redis/sentinel.conf
    ports:
      - "26380:26379"

  sentinel3:
    image: 'redis:5.0.9'
    container_name: redis-sentinel-3
    restart: always
    command: redis-sentinel /etc/redis/sentinel.conf
    volumes:
      - ./sentinel3.conf:/etc/redis/sentinel.conf
    ports:
      - "26381:26379"

此处yml文件配置好,还需要创建3个conf文件,让每一个哨兵节点都用自己的配置文件,以免出错。

但是当我们启动节点的时候,会提示没有找到master。这是因为:

我们之前启动数据节点的时候,一下子启动了几个容器,这时这几个容器处于同一个局域网中,在这个局域网中这几个容器可以相互访问。但是sentinel是另一个局域网,默认情况下这两个网络不是互通的。

解决办法:可以使用docker-compose把此处的两组服务放到同一个局域网中,先启动三个redis-server节点,再启动后面三个哨兵节点,直接让这三个哨兵节点加入到上面局域网中,而不是创建新的局域网。

最后,通过docker-compose up -d 启动节点。(注意,要切换到redis-sentinel文件夹才能启动)

作用演示

当我们启动了哨兵节点后,为了验证哨兵节点的作用,我们手动把主节点给干掉,当主节点挂了之后,哨兵节点就开始工作了。

手动停止节点

docker stop redis-master

在发现主节点挂了之后,会进行判断。

  • sdown 主观下线:此哨兵节点,认为该主节点挂了
  • odown 客观下线:好几个哨兵节点都认为该主节点挂了,达成了一致

此处会有一个法定票数这样的机制,当多少个哨兵节点都认为主节点挂了之后,此主节点才会真的被认为挂了

此时就需要从哨兵节点选出一个从节点,作为新的主节点,此处就需要提拔出一个新的主节点。

选取主节点

  1. 主观下线  哨兵通过心跳包,判定redis服务器是否正常工作,如果心跳包没有如约而至,就说明redis服务器挂了,但是此时还不能排除网络波动的影响,因此只能是当方面的认为这个reids节点挂了
  2. 客观下线  多个哨兵节点都认为主节点挂了,多个哨兵节点投票达到了法定票数,哨兵们就认为这个主节点是客观下线
  3. 让多个哨兵节点选出一个新的leader节点,由这个leader负责选出一个从节点作为新的主节点
  4. 上面选择leader的过程,也就是这个投票选择leader的过程,当哨兵1第一个发现某节点下线了,马上告诉哨兵2 和3,说我来负责这个事情。如果有多个拉票请求,就会投给最先到达的。简单地说,就是按照网络延迟来选择的。
  5. 此时leader选举完毕,leader就需要挑选一个从节点作为新的主节点、

要注意选举的过程,不是直接选出新的主节点,而是先选择leader,由leader负责后续的主节点指定。

挑选从节点作为新的主节点过程:

  1. 每个redis数据节点都会在配置文件中有一个优先级的设置,slave-priority,优先级高的从节点就会变成主节点
  2. offset最大的从节点就会变成主节点。
  3. 通过run id来随机选。

当把新的主节点指定好了之后,leader就会控制这个节点,执行slave no one,成为master,再控制其他的节点,执行slave of,让其他的节点成为这个新master的从节点。

至此,哨兵的真面目就浮出水面。哨兵+主从结构能够解决很多问题,但是不能够提高数据的存储容量,当我们需要存的数据接近或者超过机器的物理内存的时候,这样的就够就很难胜任了。

于是乎,Redis集群就出现了。下一章,Redis集群~~

  • 20
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值