Redis哨兵模式搭建

Redis哨兵模式搭建

在Redis主从复制这篇文章中我们分析了主从复制的特点,其中一个问题就是主机宕机后需要手动调整,修改从机

为主机,不仅不利于迅速恢复生产场景,还会增加人力成本。哨兵模式的出现是就是为了解决我们主从复制模式中

需要我们人为操作的东西变为自动版,并且它比人为要更及时。这篇文章我们就来讲讲如何通过哨兵模式,迅

速实现自动故障转移。

一、哨兵主要功能

监控(Monitoring):哨兵会不断地检查主节点和从节点是否运作正常。

自动故障转移(Automatic Failover):当主节点不能正常工作时,哨兵会开始自动故障转移操作,它会将失效主

节点的其中一个从节点升级为新的主节点,并让其他从节点改为复制新的主节点。

配置提供者(Configuration Provider):客户端在初始化时,通过连接哨兵来获得当前Redis服务的主节点地址。

通知(Notification):哨兵可以将故障转移的结果发送给客户端。

其中,监控和自动故障转移功能,使得哨兵可以及时发现主节点故障并完成转移;而配置提供者和通知功能,则需

要在与客户端的交互中才能体现。

二、哨兵模式

哨兵模式下,可以将节点类型分为数据节点和哨兵节点:

数据节点:主从架构中的主节点和从节点都是数据节点。

哨兵节点:哨兵系统由一个或多个哨兵节点组成,哨兵节点是特殊的Redis节点,不存储数据。

在这里插入图片描述

在上图的架构中,除使用1主2从外,还额外使用了3个哨兵来监视集群状况。

三、搭建哨兵模式

1、部署主从节点

哨兵系统中的主从节点,与普通的主从节点配置是一样的,并不需要做任何额外配置,继续使用上篇文章的配置即

可。

bind 0.0.0.0
port 8000
pidfile /var/run/redis_8000.pid
logfile "redis8000.log"
dbfilename dump8000.rdb
dir /home/hydra/files/redis/slave/redis8000/
requirepass 123456
daemonize yes
masterauth 123456
bind 0.0.0.0
port 8001
pidfile /var/run/redis_8001.pid
logfile "redis8001.log"
dbfilename dump8001.rdb
dir /home/hydra/files/redis/slave/redis8001/
# replicaof 127.0.0.1 8000
slaveof 127.0.0.1 8000
requirepass 123456
masterauth 123456
# 从机开启aof持久化
appendonly yes
daemonize yes
bind 0.0.0.0
port 8002
pidfile /var/run/redis_8002.pid
logfile "redis8002.log"
dbfilename dump8002.rdb
dir /home/hydra/files/redis/slave/redis8002/
# replicaof 127.0.0.1 8000
slaveof 127.0.0.1 8000
requirepass 123456
masterauth 123456
# 从机开启aof持久化
appendonly yes
daemonize yes

注意使用哨兵模式下,一定要开启materauth配置密码:

masterauth 123456

2、部署哨兵节点

拷贝安装目录下的配置文件sentinel.conf到自己新建的sentinel目录下,并重命名为sentinel28000.conf

以便和之后的哨兵通过端口进行区分。

修改配置文件,首先修改通用配置:

bind 0.0.0.0
protected-mode no
port 28000
daemonize yes
pidfile /var/run/redis-sentinel28000.pid
logfile "sentinel28000.log"
dir /tmp

修改哨兵核心配置,如果只配置一台哨兵,只需要修改以下配置:

sentinel monitor mymaster 127.0.0.1 8000 2
# redis数据master节点设置了认证,则需要如下配置
sentinel auth-pass mymaster 123456
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000

看一下官方注释中的格式:

sentinel monitor <master-name> <ip> <redis-port> <quorum>  

master-name指定了主节点名称,ipredis-port指定了主节点地址,quorum是判断主节点客观下线的哨兵

数量阈值:当判定主节点下线的哨兵数量达到quorum时,对主节点进行客观下线。建议取值为哨兵数量的一半加

1。

sentinel auth-pass <master-name> <password>

当在Redis实例中开启了requirepass foobared 授权密码后,所有连接Redis实例的客户端都要提供密码。设置

哨兵sentinel 连接主从的密码,注意必须为主从设置一样的验证密码。

其他配置参数:

sentinel down-after-milliseconds mymaster 30000

该参数与主观下线的判断有关:哨兵使用ping命令对其他节点进行心跳检测,如果其他节点超过down-after-

milliseconds配置的时间没有回复,哨兵就会将其进行主观下线。该配置对主节点、从节点和哨兵节点的主观下线

判定都有效。

sentinel parallel-syncs mymaster 1

该参数与故障转移之后从节点的复制有关:它规定了每次向新的主节点发起复制操作的从节点个数。

例如,假设主节点切换完成之后,有3个从节点要向新的主节点发起复制:

如果parallel-syncs=1,则从节点会一个一个开始复制;

如果parallel-syncs=3,则3个从节点会一起开始复制。

parallel-syncs取值越大,从节点完成复制的时间越快,但是对主节点的网络负载、硬盘负载造成的压力也越大,

应根据实际情况设置。

这里我们使用3台哨兵,因此复制配置文件sentinel28001.confsentinel28002.conf,并批量替换其中的端

口号为28001和28002。

bind 0.0.0.0
protected-mode no
port 28000
daemonize yes
pidfile /var/run/redis-sentinel28000.pid
logfile "sentinel28000.log"
dir /tmp
sentinel monitor mymaster 127.0.0.1 8000 2
sentinel auth-pass mymaster 123456
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
bind 0.0.0.0
protected-mode no
port 28001
daemonize yes
pidfile /var/run/redis-sentinel28001.pid
logfile "sentinel28001.log"
dir /tmp
sentinel monitor mymaster 127.0.0.1 8000 2
sentinel auth-pass mymaster 123456
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
bind 0.0.0.0
protected-mode no
port 28002
daemonize yes
pidfile /var/run/redis-sentinel28002.pid
logfile "sentinel28002.log"
dir /tmp
sentinel monitor mymaster 127.0.0.1 8000 2
sentinel auth-pass mymaster 123456
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000

3、启动哨兵节点

../redis-5.0.4/src/redis-sentinel sentinel28000.conf
../redis-5.0.4/src/redis-sentinel sentinel28001.conf
../redis-5.0.4/src/redis-sentinel sentinel28002.conf

除此之外,也可以使用下面的命令启动,效果相同:

../redis-5.0.4/src/redis-server sentinel28002.conf --sentinel

查看运行进程:
在这里插入图片描述

可以看出,现在主从运行3台Redis实例,并配置了3台哨兵。

4、使用Jedis客户端进行测试

public class RedisSentinelTest {public static void main(String[] args)  {Set<String> set=new HashSet<>();set.add("127.0.0.1:28000");set.add("127.0.0.1:28001");set.add("127.0.0.1:28002");JedisSentinelPool jedisSentinelPool=new JedisSentinelPool("mymaster",set,"123456");while (true) {Jedis jedis=null;try {jedis = jedisSentinelPool.getResource();String s = UUID.randomUUID().toString();jedis.set("k" + s, "v" + s);System.out.println(jedis.get("k" + s));Thread.sleep(1000);}catch (Exception e){e.printStackTrace();}finally {if(jedis!=null){jedis.close();}}}}
}

在客户端写数据过程中,使用kill命令杀死主机,会存在短暂的写失败情况,抛出异常。这是因为在故障迁移的时

候,是不能写数据的,中间有服务不可用的过程,在迁移后会自动恢复。并且当原来的主机再启动后,会变成新主

机的从机使用,这是因为哨兵会动态的修改配置文件。

四、哨兵模式原理

1、关于哨兵的原理,关键是了解以下核心概念:

主观下线:在心跳检测的定时任务中,如果其他节点超过一定时间没有回复,哨兵节点就会将其进行主观下线。顾

名思义,主观下线的意思是一个哨兵节点“主观地”判断下线;与主观下线相对应的是客观下线。

客观下线:哨兵节点在对主节点进行主观下线后,会通过sentinel is-master-down-by-addr命令询问其他哨

兵节点该主节点的状态;如果判断主节点下线的哨兵数量达到一定数值,则对该主节点进行客观下线。

需要特别注意的是,客观下线是主节点才有的概念;如果从节点和哨兵节点发生故障,被哨兵主观下线后,不会再

有后续的客观下线和故障转移操作。

2、每个哨兵节点维护了3个定时任务。定时任务的功能分别如下:

  • 每10秒通过向主从节点发送info命令获取最新的主从结构:发现slave节点,并确定主从关系;

  • 每2秒通过发布订阅功能获取其他哨兵节点的信息,交互对节点的“看法”和自身情况;

  • 每1秒通过向其他节点发送ping命令进行心跳检测,判断是否下线。

3、领导者选举

选举领导者哨兵节点:当主节点被判断客观下线以后,各个哨兵节点会进行协商,选举出一个领导者哨兵节点,并

由该领导者节点对其进行故障转移操作。

监视该主节点的所有哨兵都有可能被选为领导者,选举使用的算法是Raft算法;Raft算法的基本思路是先到先得:

即在一轮选举中,哨兵A向B发送成为领导者的申请,如果B没有同意过其他哨兵,则会同意A成为领导者。

在从节点中选择新的主节点,选择的原则如下:

  • 首先过滤掉不健康的从节点

  • 然后选择优先级最高的从节点(由replica-priority指定)

  • 如果优先级无法区分,则选择复制偏移量最大的从节点

  • 如果仍无法区分,则选择runid最小的从节点

  • 更新主从状态:通过slaveof no one命令,让选出来的从节点成为主节点,并通过slaveof命令让其他节点成为其从节点

  • 将已经下线的主节点保持关注,当再次上线后设置为新的主节点的从节点

五、总结

在实际使用过程中,哨兵节点的数量应大于一个。一方面增加哨兵节点的冗余,避免哨兵本身成为高可用的瓶颈;

另一方面减少对下线的误判。此外,不同的哨兵节点应部署在不同的物理机上。并且哨兵节点的数量应该是奇数,

便于哨兵通过投票进行领导者选举的决策、客观下线的决策等。

在主从复制的基础上,哨兵引入了主节点的自动故障转移,进一步提高了Redis的高可用性;但是哨兵的缺陷同样

很明显:哨兵无法对从节点进行自动故障转移,在读写分离场景下,从节点故障会导致读服务不可用,需要我们对

从节点做额外的监控、切换操作。此外,哨兵仍然没有解决写操作无法负载均衡、及存储能力受到单机限制的问

题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/50653.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu18.04 交叉编译openssl-1.1.1

源码下载地址&#xff1a; openssl 此处使用的是openssl-1.1.1-pre5.tar.gz 解压: $tar -zxvf openssl-1.1.1-pre5.tar.gz $cd openssl-1.1.1-pre5/ 执行配置生成Makefile&#xff1a; $./config no-asm shared --prefix$PWD/__install 或者 $./config no-asm shared no-…

远控木马病毒分析

一、病毒简介 SHA256:880a402919ba4e896f6b4b2595ecb7c06c987b025af73494342584aaa84544a1 MD5:0902b9ff0eae8584921f70d12ae7b391 SHA1:f71b9183e035e7f0039961b0ac750010808ebb01 二、行为分析 同样在我们win7虚拟机中&#xff0c;使用火绒剑进行监控&#xff0c;分析行为…

C++ Day3

目录 一、类 【1】类 【2】应用实例 练习&#xff1a; 【3】封装 二、this指针 【1】this指针的格式 【2】必须使用this指针的场合 三、类中的特殊成员函数 【1】构造函数 i&#xff09;功能 ii&#xff09;格式 iii&#xff09;构造函数的调用时机 iv&#xff09;…

Golang使用消息队列(RabbitMQ)

最近在使用Golang做了一个网盘项目&#xff08;类似百度网盘&#xff09;&#xff0c;这个网盘项目有一个功能描述如下&#xff1a;用户会删除一个文件到垃圾回收站&#xff0c;回收站的文件有一个时间期限&#xff0c;比如24h&#xff0c;24h后数据库中记录和oss中文件会被删除…

C语言之扫雷游戏实现篇

目录 主函数test.c 菜单函数 选择循环 扫雷游戏实现分析 整体思路 问题1 问题2 问题3 问题4 游戏函数&#xff08;函数调用&#xff09; 创建游戏盘数组mine 创建游戏盘数组show 初始化游戏盘数组InitBoard 展示游戏盘DisplayBoard 游戏盘置雷SetMine 游戏…

设计模式之创建者模式

文章目录 一、介绍二、应用三、案例1. 麦当劳11随心配2. 代码演示3. 演示结果 四、优缺点五、送给读者 一、介绍 建造者模式(Builder Pattern)属于创建型设计模式&#xff0c;很多博客文章的对它的作用解释为用于将复杂对象的创建过程与其细节表示分离。但对于初学者来说&…

VS2022 C++ 批量追加hosts文件IP地址与域名脚本V1.0

这是自己使用VS2022 C++开发的批量追加"C:\Windows\System32\drivers\etc\hosts"文件IP地址与域名的脚本。它可以把cfg.txt文件中例如: 192.168.1.9 test.email 192.168.123.9 doutia.com批量追加到hosts文件 详细源代码如下: AddToHostHosts.cpp //#includ…

Pyqt5打开电脑摄像头进行拍照

目录 1、设计UI界面 2、设计逻辑代码&#xff0c;建立连接显示窗口 3、结果 1、设计UI界面 将ui界面转为py文件后获得的逻辑代码为&#xff1a;&#xff08;文件名为 Camera.py&#xff09; # -*- coding: utf-8 -*-# Form implementation generated from reading ui file …

【ES6】—【必备知识】—深拷贝与浅拷贝

一、如何把一个对象复制给另一个对象 1.Object.assign() let target {} let source {a: 1,b: 2 } Object.assign(target,source) console.log(target) // {a: 1, b: 2}2.Object.assign() 只能实现浅拷贝 let target {a: {b:1,c: 8} } let source {a: {b:2} } Object.ass…

无涯教程-PHP - File 函数

文件系统功能用于访问和操纵文件系统&#xff0c;PHP为您提供了操纵文件的所有功能。 运行时配置 这些功能的行为受php.ini中的设置影响。 NameDefaultChangeableChangelogallow_url_fopen"1"PHP_INI_ALLPHP_INI_ALL in PHP < 4.3.4. PHP_INI_SYSTEM in PHP &l…

Linux:如何创建用户

“useradd” 命令用于在 Linux 或类 Unix 系统上创建新用户账户。它是一个需要超级用户权限的命令&#xff0c;因此你需要以 root 或具有 sudo 权限的用户身份运行它。下面是使用 “useradd” 命令创建新用户的基本语法&#xff1a; useradd [选项] 用户名 下面是一些常用选项…

windows上ffmpeg如何录制双屏幕中的一个屏幕上的视频

首先&#xff0c;如何在window上安装ffmpeg自己查找scoop安装ffmpeg. 如题&#xff1a; 如果你有两个屏幕&#xff0c;如何让ffmpeg来录制其中的一个屏幕的视频呢。 很简单&#xff0c;首先你要查看另外一个屏幕的分辨率&#xff1a; 第一步&#xff1a;进入系统中 第二步&am…

硬件产品的量产问题------硬件工程师在产线关注什么

前言&#xff1a; 产品开发测试无误&#xff0c;但量产缺遇到很多不良甚至DOA问题。 硬件开发过程中如何确保产线的治具、生产及硬件工程师在产线需要关注一些什么。 坚信&#xff1a;好的产品是要可以做出来的。 1、禁忌&#xff1a; 禁忌热插拔&#xff1b;禁忌测试不防呆…

Python Opencv实践 - 图像直方图均衡化

import cv2 as cv import numpy as np import matplotlib.pyplot as pltimg cv.imread("../SampleImages/pomeranian.png", cv.IMREAD_COLOR) print(img.shape)#图像直方图计算 #cv.calcHist(images, channels, mask, histSize, ranges, hist, accumulate) #images&…

link 和 @import 有什么区别

页面导入样式时&#xff0c;使用 link 和 import 有什么区别 HTML中使用 link 标签 <link rel"stylesheet" href"style.css" />CSS 中 import import "style.css"; import url("style.css"); /* 两种方式无差别 */两者的区别…

数学建模知识之小白入门篇

数学建模知识--小白入门篇 一、数学模型的定义二、建立数学模型的方法和步骤1. 模型准备2. 模型假设3. 模型构成4. 模型求解5. 模型分析 三、数模竞赛出题的指导思想四、竞赛中的常见题型1. 实际问题背景2&#xff0e;若干假设条件3&#xff0e;要求回答的问题 五、提交一篇论文…

ModStartBlog v8.0.0 博客归档页面,部分组件升级

ModStart 是一个基于 Laravel 模块化极速开发框架。模块市场拥有丰富的功能应用&#xff0c;支持后台一键快速安装&#xff0c;让开发者能快的实现业务功能开发。 系统完全开源&#xff0c;基于 Apache 2.0 开源协议。 功能特性 丰富的模块市场&#xff0c;后台一键快速安装会…

C语言入门 Day_9 条件判断

目录 前言&#xff1a; 1.if判断 2.else判断 3.易错点 4.思维导图 前言&#xff1a; 我们知道比较运算和逻辑运算都会得到一个布尔型的数据&#xff0c;要么为真&#xff08;true&#xff09;&#xff0c;要么为假&#xff08;false&#xff09;。 今天我们来学习真和假在…

面试热题(复原ip地址)

有效 IP 地址 正好由四个整数&#xff08;每个整数位于 0 到 255 之间组成&#xff0c;且不能含有前导 0&#xff09;&#xff0c;整数之间用 . 分隔。 例如&#xff1a;"0.1.2.201" 和 "192.168.1.1" 是 有效 IP 地址&#xff0c;但是 "0.011.255.24…

pyqt5-自定义停靠栏头部

import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import *class CustomDock(QDockWidget):def __init__(self, title: str, parentNone):super().__init__(title, parent)"""停靠栏的头部"""h_layout Q…