[Redis][集群][下]详细讲解

目录

  • 1.集群搭建(基于 Docker)
  • 2.主节点宕机
    • 1.宕机后会发生什么?
    • 2.处理流程
      • 1.故障判定
      • 2.故障迁移
  • 3.集群扩容
    • 0.前言
    • 1.把新的主节点加入到集群
    • 2.重新分配slots
    • 3.给新的主节点添加从节点


1.集群搭建(基于 Docker)

  • 拓扑结构如下
    请添加图片描述

  • 创建目录和配置:创建redis-cluster⽬录,内部创建两个⽂件

    redis-cluster/
    ├── docker-compose.yml 
    └── generate.sh
    
  • generate.sh

    for port in $(seq 1 9); \
    do \mkdir -p redis${port}/touch redis${port}/redis.confcat << EOF > redis${port}/redis.confport 6379bind 0.0.0.0protected-mode noappendonly yescluster-enabled yescluster-config-file nodes.confcluster-node-timeout 5000cluster-announce-ip 172.30.0.10${port}cluster-announce-port 6379cluster-announce-bus-port 16379EOF
    done# 注意cluster-announce-ip的值有变化
    for port in $(seq 10 11); \
    do \mkdir -p redis${port}/touch redis${port}/redis.confcat << EOF > redis${port}/redis.confport 6379bind 0.0.0.0protected-mode noappendonly yescluster-enabled yescluster-config-file nodes.confcluster-node-timeout 5000cluster-announce-ip 172.30.0.1${port}cluster-announce-port 6379cluster-announce-bus-port 16379EOF
    done
    
    • 配置说明
      • cluster-enabled yes:开启集群
      • cluster-config-file nodes.conf:集群节点⽣成的配置
      • cluster-node-timeout 5000:节点失联的超时时间
      • cluster-announce-ip 172.30.0.101:节点⾃⾝ip
      • cluster-announce-port 6379:节点⾃⾝的业务端⼝
      • cluster-announce-bus-port 16379节点⾃⾝的总线端⼝(管理端口),集群管理的信息交互是通过这个端⼝进⾏的
  • docker-compose.yml

    • 先创建networks,并分配网段172.30.0.0/24
    • 配置每个节点,注意配置⽂件映射,端⼝映射,以及容器的ip地址,设定成固定ip⽅便后续的观察和操作
      version: '3.7'
      networks:mynet:ipam:config:- subnet: 172.30.0.0/24services:redis1:image: 'redis:5.0.9'container_name: redis1restart: alwaysvolumes:- ./redis1/:/etc/redis/ports:- 6371:6379- 16371:16379command:redis-server /etc/redis/redis.confnetworks:mynet:ipv4_address: 172.30.0.101redis2:image: 'redis:5.0.9'container_name: redis2restart: alwaysvolumes:- ./redis1/:/etc/redis/ports:- 6372:6379- 16372:16379command:redis-server /etc/redis/redis.confnetworks:mynet:ipv4_address: 172.30.0.102# redis3 ~ redis11
      
  • 启动容器docker-compose up -d

  • 构建集群:此处把前9个主机构成集群,3主6从,后两个主机暂时不用

    • --cluster create:表⽰建⽴集群.后⾯填写每个节点的ip和地址
    • --cluster-replicas 2:表⽰每个主节点需要两个从节点备份
      redis-cli --cluster create 172.30.0.101:6379 172.30.0.102:6379 172.30.0.103:6379 172.30.0.104:6379 172.30.0.105:6379 172.30.0.106:6379 172.30.0.107:6379 172.30.0.108:6379 172.30.0.109:6379 --cluster-replicas 2
      
    • 日志中会描述哪些是主节点,哪些从节点跟随哪个主节点
      >>> Performing hash slots allocation on 9 nodes...
      Master[0] -> Slots 0 - 5460
      Master[1] -> Slots 5461 - 10922
      Master[2] -> Slots 10923 - 16383
      Adding replica 172.30.0.105:6379 to 172.30.0.101:6379
      Adding replica 172.30.0.106:6379 to 172.30.0.101:6379
      Adding replica 172.30.0.107:6379 to 172.30.0.102:6379
      Adding replica 172.30.0.108:6379 to 172.30.0.102:6379
      Adding replica 172.30.0.109:6379 to 172.30.0.103:6379
      Adding replica 172.30.0.104:6379 to 172.30.0.103:6379
      M: e4f37f8f0ea0dafc584349999795716613910e51 172.30.0.101:6379slots:[0-5460] (5461 slots) master
      M: 5f71983ad52cc7077ce8874ae1c4f9c23d9f502c 172.30.0.102:6379slots:[5461-10922] (5462 slots) master
      M: b3c0a96f6a206088ecea639147b6fcf903afe872 172.30.0.103:6379slots:[10923-16383] (5461 slots) master
      S: 85025819223f12615046c54d89f510e9cd0444a1 172.30.0.104:6379replicates b3c0a96f6a206088ecea639147b6fcf903afe872
      S: 2e5dc211288784ba55d554a377b87bfe2b5398db 172.30.0.105:6379replicates e4f37f8f0ea0dafc584349999795716613910e51
      S: 29f05d98982bd3df05d0222091e4b8ef9569f424 172.30.0.106:6379replicates e4f37f8f0ea0dafc584349999795716613910e51
      S: 3584840ac704c3ee016f3bdcca3f7ebe6f6e8e80 172.30.0.107:6379replicates 5f71983ad52cc7077ce8874ae1c4f9c23d9f502c
      S: 0a889103b35db2a6e82e8c09904bbef310cff3b1 172.30.0.108:6379replicates 5f71983ad52cc7077ce8874ae1c4f9c23d9f502c
      S: 00ba82bed6abeb015116d51d1af7fcb1609d03ad 172.30.0.109:6379replicates b3c0a96f6a206088ecea639147b6fcf903afe872
      Can I set the above configuration? (type 'yes' to accept): yes
      
    • Redis在构建集群时,谁是主节点,谁是从节点,谁和谁是一个分片,都是不固定的
      • 理论上说,从集群角度看,提供的所有节点本就应该是等价的
  • 此时,使用客户端连上集群中的任何一个节点,都相当于连上了整个集群

    • 客⼾端后⾯要加上-c选项,否则如果key没有落到当前节点上,是不能操作的
      • -c会自动把请求重定向到对应节点
    • 使⽤cluster nodes可以查看到整个集群的情况
  • 使用集群之后,之前的那些Redis命令,基本都能使用,除了一些操作多个key,如mget
    ![[Pasted image 20240911210424.png]]


2.主节点宕机

1.宕机后会发生什么?

  • 此处集群做的工作,和之前哨兵做的类似,会主动从该主节点旗下从节点中挑一个出来,提拔为主节点
    • master提示fail后,原本的slave会变成新的master
    • 如果重新启动原master,该节点会作为slave存在
  • 可以使⽤cluster failover进⾏集群恢复,也就是把原master重新设定成·master
    • 需要登录到原master机器上执行

2.处理流程

1.故障判定

  • 集群中的所有节点,都会周期性的使⽤⼼跳包进⾏通信
    • 节点A给节点B发送ping包,B就会给A返回⼀个pong
      • pingpong除了message type属性之外,其他部分都是⼀样的
      • 这⾥包含了集群的配置信息(该节点的id,该节点从属于哪个分⽚,是主节点还是从节点,从属于谁,持有哪些slots的位图…)
    • 每个节点,每秒钟,都会给⼀些随机的节点发起ping,⽽不是全发⼀遍
      • 这样设定是为了避免在节点很多的时候,⼼跳包也⾮常多
      • ⽐如有9个节点,如果全发,就是 9 ∗ 8 9*8 98有72组⼼跳了,⽽且这是按照 N 2 N^2 N2这样的级别增⻓的
    • 当节点A给节点B发起ping包,B不能如期回应的时候,此时A就会尝试重置和B的TCP连接,看能否连接成功,如果仍然连接失败,A就会把B设为PFAIL状态(相当于主观下线).
    • A判定B为PFAIL之后,会通过Redis内置的Gossip协议,和其他节点进⾏沟通,向其他节点确认B的状态
      • 每个节点都会维护⼀个⾃⼰的"下线列表",由于视⻆不同,每个节点的下线列表也不⼀定相同
    • 此时A发现其他很多节点,也认为B为PFAIL,并且数⽬超过总集群个数的⼀半,那么A就会把B标记成FALL(相当于客观下线),并且把这个消息同步给其他节点(其他节点收到之后,也会把B标记成FAIL)
    • 至此,B是否下线,就已经明确了
  • 某个或者某些节点宕机,有的时候会引起整个集群都宕机,称为fail状态
    • 某个分⽚,所有的主节点和从节点都挂了
      • 此时,该分片就无法提供数据服务了,相当于数据缺失
    • 某个分⽚,主节点挂了,但是没有从节点
    • 超过半数的master节点都挂了
      • 如果突然一系列的master都挂了,说明集群遇到了非常严重的问题,此时就需要赶紧停下来,检查检查是不是有什么问题
    • 核心原则:保证每个slots都能正常工作(存取数据)

2.故障迁移

  • 上述例⼦中,B故障,并且A把BFAIL的消息告知集群中的其他节点
    • 如果B是从节点,那么不需要进行故障迁移
    • 如果B是主节点,那么就会由B的从节点(比如C和D)触发故障转移了
  • 所谓故障转移,就是指把从节点提拔成主节点,继续给整个Redis集群提供支持
  • 具体流程
    • 从节点判定⾃⼰是否具有参选资格,如果从节点和主节点已经太久没通信(此时认为从节点的数据和主节点差异太⼤了),时间超过阈值,就失去竞选资格
    • 具有资格的节点,⽐如C和D,就会先休眠⼀定时间休眠时间 = 500ms基础时间 + [0, 500ms]随机时间 + 排名 * 1000msoffset的值越⼤,则排名越靠前(越⼩)
      • 排名越靠前,休眠时间就越短,谁休眠时间短,大概率就是新的主节点了
    • 比如C的休眠时间到了,C就会给其他所有集群中的节点,进行拉票操作
      • 但是只有主节点才有投票资格
    • 主节点就会把⾃⼰的票投给C(每个主节点只有1票),当C收到的票数超过主节点数⽬的⼀半,C就会晋升成主节点
      • C⾃⼰负责执⾏slaveof no one,并且让D执⾏slaveof C
    • 同时,C还会把⾃⼰成为主节点的消息,同步给其他集群的节点,⼤家也都会更新⾃⼰保存的集群结构信息
  • 上述选举的过程,成为Raft算法,是一种在分布式系统中广泛使用的算法
    • 在随即休眠时间的加持下,基本上就是谁先醒,谁就能竞选成功
    • 更多的时候,是为了选一个节点出来,至于是谁,并不重要
  • 哨兵是先选出leaderleader负责找一个从节点升级成主节点这里是直接投票选出新的主节点

3.集群扩容

0.前言

  • 扩容是⼀个在开发中⽐较常遇到的场景
  • 随着业务的发展,现有集群很可能⽆法容纳⽇益增⻓的数据,此时给集群中加⼊更多新的机器。就可以使存储的空间更⼤了
  • 分布式的本质就是使⽤更多的机器,引⼊更多的硬件资源
  • 明确集群扩容操作,是一件风险较高,成本较大的操作,操作时,需要抱着一个敬畏的心!!!

1.把新的主节点加入到集群

  • 上⾯已经把redis1-redis9重新构成了集群,接下来把redis10和redis11也加⼊集群
    • 此处把redis10作为主机,redis11作为从机
      redis-cli --cluster add-node 172.30.0.110:6379 172.30.0.101:6379
      
  • 说明
    • add-node后的第⼀组地址是新节点的地址
    • 第⼆组地址是集群中的任意节点地址,表示要把新节点加到哪个集群中
  • 执行结果
    >>> Adding node 172.30.0.110:6379 to cluster 172.30.0.101:6379
    >>> Performing Cluster Check (using node 172.30.0.101:6379)
    M: 00d319e23ef76a4d51e74600c42ee2a371ae81f6 172.30.0.101:6379slots:[0-5460] (5461 slots) master2 additional replica(s)
    S: e34911c57d7605903de84ec05b3deac611aaef7e 172.30.0.105:6379slots: (0 slots) slavereplicates 00d319e23ef76a4d51e74600c42ee2a371ae81f6
    S: 6cf48cc11d0171b6ab1b418808473167acd7986e 172.30.0.106:6379slots: (0 slots) slavereplicates 00d319e23ef76a4d51e74600c42ee2a371ae81f6
    S: fd18c7f164b09ec563f4573ec9d6466e6769221e 172.30.0.108:6379slots: (0 slots) slavereplicates b3f2ba758318f4bd54031c98c01d7a6155ff43d3
    M: 579282abe81b3f20ffd17d5a1956cdca3b0e71b0 172.30.0.103:6379slots:[10923-16383] (5461 slots) master2 additional replica(s)
    S: e9ea79b1326ea5a75a1701d5c12a0f6081c1d043 172.30.0.109:6379slots: (0 slots) slavereplicates 579282abe81b3f20ffd17d5a1956cdca3b0e71b0
    S: 628d1ec9ceef6760b9038c4fbc83ee92430062ac 172.30.0.107:6379slots: (0 slots) slavereplicates b3f2ba758318f4bd54031c98c01d7a6155ff43d3
    M: b3f2ba758318f4bd54031c98c01d7a6155ff43d3 172.30.0.102:6379slots:[5461-10922] (5462 slots) master2 additional replica(s)
    S: 2a248acb47f0036655397897f9800c70ea22514f 172.30.0.104:6379slots: (0 slots) slavereplicates 579282abe81b3f20ffd17d5a1956cdca3b0e71b0
    [OK] All nodes agree about slots configuration.
    >>> Check for open slots...
    >>> Check slots coverage...
    [OK] All 16384 slots covered.
    >>> Send CLUSTER MEET to node 172.30.0.110:6379 to make it join the cluster.
    [OK] New node added correctly.
    
  • 此时的集群状态172.30.0.110这个节点已经成为了集群中的主节点,但没有任何slots
    • 需要重新分配slots

2.重新分配slots

  • 示例命令
    redis-cli --cluster reshard 172.30.0.101:6379
    
  • 说明reshard后的地址是集群中的任意节点地址
  • 执行之后,会进入交互式操作,Redis会提示用户输入以下内容
    • 多少个slots要进⾏reshard?
    • 哪个节点来接收这些slots?
    • 这些slots从哪些节点搬运过来?
      • all:从其他每个持有slotsmaster都拿过来点
      • done:从某一个或某几个节点来移动slots,以done为结尾
    How many slots do you want to move (from 1 to 16384)? 4096
    What is the receiving node ID? 522a1bd88a1a9084e6919fa88f4bf1c3655ad837
    Please enter all the source node IDs.Type 'all' to use all the nodes as source nodes for the hash slots.Type 'done' once you entered all the source nodes IDs.
    Source node #1: all
    
  • 如果在搬运slots/key的过程中,此时客户端能否访问Redis集群呢
    • 对于那些不需要搬运的key,访问的时候是没有任何问题的
    • 但是对于需要搬运的key,进⾏访问可能会出现短暂的访问错误(key的位置出现了变化)
    • 随着搬运完成,这样的错误⾃然就恢复了

3.给新的主节点添加从节点

  • 光有主节点了,此时扩容的⽬标已经初步达成,但是为了保证集群可⽤性,还需要给这个新的主节点添加从节点,保证该主节点宕机之后,有从节点能够顶上
  • 示例命令
    redis-cli --cluster add-node 172.30.0.111:6379 172.30.0.101:6379 --cluster-slave --cluster-master-id [172.30.1.110 节点的 nodeId]
    

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【Python】FeinCMS:轻量级且可扩展的Django内容管理系统

在互联网飞速发展的今天&#xff0c;内容管理系统&#xff08;CMS&#xff09;成为了网站开发中的核心工具&#xff0c;尤其对于需要频繁更新内容的企业和个人站点而言&#xff0c;CMS 提供了极大的便利。市场上有许多不同的 CMS 工具可供选择&#xff0c;其中基于 Django 框架…

在IDEA中构建Jar包,安装Jar包到Maven仓库并在Maven项目中使用

文章目录 0. 关于本文1. IDEA构建Jar包1.1 准备一份Java代码&#xff08;就是你要构建工件的代码&#xff09;1.2 进行如下步骤构建工件 2. 关于Maven3. 将Jar包安装到Maven仓库4. 使用安装的Jar包依赖 0. 关于本文 本文内容&#xff1a; 借助IDEA构建Jar包将Jar包安装到Mave…

甄选范文“论网络安全体系设计”,软考高级论文,系统架构设计师论文

论文真题 随着社会信息化的普及,计算机网络已经在各行各业得到了广泛的应用。目前,绝大多数业务处理几乎完全依赖计算机和网络执行,各种重要数据如政府文件、工资档案、财务账目和人事档案等均依赖计算机和网络进行存储与传输。另一方面,针对计算机和网络的攻击活动日益猖…

STM32-HAL库驱动DHT11温湿度传感器 --2024.9.28

目录 一、教程简介 二、驱动原理讲解 &#xff08;一&#xff09;通信4步骤 &#xff08;二&#xff09;传感器数据解析 三、CubeMX生成底层代码 &#xff08;一&#xff09;基础配置 &#xff08;二&#xff09;配置DHT11的驱动引脚 &#xff08;三&#xff09;配置串口 四…

uni-app在线预览pdf

这里推荐下载pdf.js 插件 PDF.js - Browse Files at SourceForge.net 特此注意 如果报 Promise.withResolvers is not a function 请去查看版本兼容问题 降低pdf.js版本提高node版本 下载完成后 在 static 文件夹下新建 pdf 文件夹&#xff0c;将解压文件放进 pdf 文件…

【Python】Django Grappelli:打造优雅且现代化的 Django 管理后台

在 Django 开发中&#xff0c;默认的 Django Admin 界面尽管功能强大且能满足大多数管理需求&#xff0c;但其界面设计相对基础&#xff0c;尤其在用户体验和视觉呈现上显得较为简约。在一些项目中&#xff0c;开发者可能需要更加现代化且美观的后台界面。这时&#xff0c;Djan…

[Linux#58][HTTP] 自己构建服务器 | 实现网页分离 | 设计思路

目录 一. 最简单的HTTP服务器 二.服务器 2.0 Protocol.hpp httpServer.hpp 子进程的创建和退出 子进程退出的意义 父进程关闭连接套接字 httpServer.cc argc (argument count) argv (argument vector) 三.服务器和网页分离 思考与补充&#xff1a; 一. 最简单的HTT…

Tomcat搭建zrlog

1.基础环境准备&#xff1a; 在开始进行软件安装和服务配置之前&#xff0c;必须对系统进行基础设置&#xff0c;以确保服务器的正常运行。这个任务要求你进行一些基础的系统配置操作&#xff0c;包括修改主机名、关闭防火墙以及临时关闭 SELinux等。通过这些步骤&#xff0c;…

实验2 网络测试命令的使用及对等网组建

实验2 网络测试命令的使用及对等网组建 一、实验目的 1. 熟悉常用网络测试命令的语法及其功能&#xff1b; 2. 掌握常用的网络故障分析及排除的方法&#xff1b; 3. 熟悉Windows中的网络组建及各参数的设置和基本意义。 4.如何在对等网中建立共享及访问对方的共享资源。 二、…

国庆假节高速免费通行全攻略

关注▲洋洋科创星球▲一起成长&#xff01; 国庆节假期全国收费公路继续对7座以下&#xff08;含7座&#xff09;小型客车免收车辆通行费。 具体免费时段从 10月1日00&#xff1a;00开始 10月7日24&#xff1a;00结束 01 提前出发&#xff0c;免费离开&#xff1a; 如果你在…

FastAPI前置知识及快速入门

FastAPI fastapi&#xff0c;一个用于构建 API 的现代、快速&#xff08;高性能&#xff09;的web框架。 fastapi是建立在Starlette和Pydantic基础上的&#xff0c;Pydantic是一个基于Python类型提示来定义数据验证、序列化和文档的库。Starlette是一种轻量级的ASGI框架/工具包…

JNI实现Java调用C++函数

1. 测试环境 操作系统&#xff1a;win10JDK版本&#xff1a;JDK11 安装教程gcc版本&#xff1a;8.1.0 2. 声明native方法 // HelloJNI.java public class HelloJNI {// 输出Hello JNI from CPP. private native static void sayHello();// 实现两个整数相加private native s…

Java基础扫盲(二)

想看Java基础扫盲&#xff08;一&#xff09;的可以观看我的上篇文章Java基础扫盲 目录 String为什么设计为不可变的 String有长度限制吗 为什么JDK9将String的char[]改为byte[] 泛型中K,T,V,E,Object,?等都代表什么含义 怎么修改一个类中使用了private修饰的String类型…

Java基于相似算法实现以图搜图

一、简述 本文主要讲如何利用图片相似性算法&#xff0c;基于LIRE来实现图片搜索。 二、依赖 <dependencies><!-- https://mvnrepository.com/artifact/org.apache.lucene/lucene-core --><dependency><groupId>org.apache.lucene</groupId><…

7.MySQL内置函数

目录 日期函数时间函数字符串函数数学函数其他函数 日期函数 函数名称描述current_date()当前日期current_time()当前时间current_timesamp()当前时间戳date(datetime)返回datetime参数的日期部分date_add(date, interval d_value_tyep)在date中添加日期函数或时间。interval后…

项目计划软件如何助力企业策略规划和执行监控

项目管理软件助力任务、时间和协作管理&#xff0c;如ZohoProjects集成了任务管理、时间跟踪、协作工具等功能&#xff0c;提高性价比&#xff0c;适合不同规模团队。其简化流程、专业度高&#xff0c;成为企业提升效率的重要工具。 一、项目计划软件的由来 项目计划软件的历史…

在线代码编辑器

在线代码编辑器 文章说明前台核心代码后台核心代码效果展示源码下载 文章说明 采用Java结合vue3设计实现的在线代码编辑功能&#xff0c;支持在线编辑代码、运行代码&#xff0c;同时支持导入文件&#xff0c;支持图片识别&#xff0c;支持复制代码&#xff0c;可将代码导出为图…

Cookie、Session、Token(JWT)还不懂?

Cookie、Session、Token&#xff08;JWT&#xff09; 三者的区别与用途&#xff01;如何进行身份认证&#xff0c;保持用户登录状态&#xff1f; Cookie、Session 和 Token 都是在 Web 开发中用于管理用户状态和进行身份认证的技术&#xff0c;它们之间有以下区别和用途&#…

一步步带你Linux内核编译与安装

Linux内核编译与安装 安装流程 #mermaid-svg-0PfY2uowOUJaN2Ov {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-0PfY2uowOUJaN2Ov .error-icon{fill:#552222;}#mermaid-svg-0PfY2uowOUJaN2Ov .error-text{fill:#5522…