中间件(redis,rabbitmq,zookeeper,kafka)集群讨论及搭建

2023-11-18

一,前言

大家好,我是小墨。

这一篇文章我们来一个中间件的集群的搭建的大团圆章节,将围绕我们使用的主流几个中间件(我使用过的)的集群构建方式进行原理讨论和实际搭建方案探讨,包括zookeeper,redis,rabbitmq,zookeeper,然后我们对这些中间件集群进行总结,尽量提炼出一些知识出来一起分享,注意本文不涉及实际搭建过程。后面一期专门讲讲mysql集群,然后我们再尽量联系起来一起思考。

二,中间件集群搭建

 

1,zookeeper集群

1)集群搭建

我们简单讲述下zookeeper集群搭建方式:

  1. 准备zookeeper机器,我们举例机器A,B,C,配置zoo.cfg:这里多了一个server.id=host:port1:port2 配置,这个id为server ID 用于标记机器在集群中的机器序号
    tickTime=2000
    dataDir=/var/lib/zookeeper
    dataLogDir=/var/lib/log
    clientPort=2181
    initLimit=5
    syncLimit=2
    server.1=A:2888:3888
    server.2=B:2888:3888
    server.3=C:2888:3888

     

  2. 创建 myid 文件,在 dataDir 目录下创建名为 myid 的文件,在文件第一行写上对应的 Server ID。

  3. 启动机器

2)集群分析

对于zookeeper而言,作为一种为分布式而设计的协调服务,集群中的机器自动会协调之间的关系,对于zookeeper集群而言,有三种角色:

  • leader:负责更新系统状态,在协调集群过程时起投票的发起和决议,负责写入信息,并同步到各个节点
  • follower:参与选举leader的投票,然后用于接收客户请求并向客户端返回结果
  • observer:除了不参与投票外,其他与follower一样,只干活无权力者

zookeeper集群基于ZAB协议进行启动,leader宕机,运行时的选举过程,我们这里不细讲整个选举过程,就以如果有leader宕机情况下如何选出leader恢复集群工作    (举例A,B,C三台机器构成的集群,A 为leader):

  1. 变更状态。leader挂掉后,剩余的follower机器把状态有following改为looking。开始选举
  2. 每个server发起一个投票。B和C会将自身作为leader来投票,这里投票信息包括自身myid,ZXID(写成功的消息,都有一个全局唯一的标识,叫zxid,每写一次都会递增,防止不同轮次的选举互相干扰),然后广播给集群中的其他机器
  3. 接收各机器投票:各机器收到投票后判断该投票的有效性,如检查是否是本轮投票、是否来自LOOKING状态的服务器。
  4. 处理投票。比较规则如下: 1)优先检查ZXID,ZXID最大的优先为leader   2)ZXID相同就比较myid,myid最大获胜为leader。
  5. 统计投票。每次投票后,服务器都会统计投票信息,判断是否已经有过半机器接受到相同的投票信息,如果有的话那么表示过半机器都有相同观点认为某机器为leader
  6. 修改服务器状态,当确认leader后,该follower升级leader,修改状态为leading,其他follower修改为following

我们简单讨论下为什么这么设计,我们先关注一个zookeeper集群读写数据流程

1)写请求

  • 有写操作时,如果是follower接收,会转到leader,
  • leader收到写请求后,写入本地,为该操作生成zxid,然后发zxid和数据一起给所有follower节点
  • 当follower收到后时,写入本地,成功后返回给leader。
  • leader收到过半反馈(包括自己),返回给client说已经成功

2)读数据:Client向zookeeper发出读请求时,无论是Leader还是Follower,都直接返回查询结果,并不保证数据最新。

好了看完后我们是不是想到了分布式中的难言之隐----数据一致性问题,但是我们这里按下不表,就谈谈我们当时选举过程的设计:我们使用如此规则1)优先检查ZXID,ZXID最大的优先为leader   2)ZXID相同就比较myid,myid最大获胜为leader。

明显就可以发现我们是选举一个数据最新的follower!!希望尽量保证leader宕机后数据的最新和一致性。

 

 

2,redis集群

对于redis集群的更加完整的请查看redis之---redis集群方案,我不详细叙述了,主要举redis的cluster集群方案。

cluster集群的键空间被分割为16384个slots(即hash槽),slot是数据映射的基本单位,即集群的最大节点数量是16384(官方推荐最大节点数量为1000个左右)。集群中的每个Master节点负责处理16384个hash槽其中的一部分,当集群处于“stable”状态时(无slots在节点间迁移),任意一个hash slot只会被单个node所服务。

在这里插入图片描述

作为一种去中心化的设计,我们谈谈这种设计下如何保证集群稳定运行:

  1. 集群分为主从节点两种角色,主节点负责写与读,从节点只做备份,数据副本
  2. 当主节点发生宕机,进行从节点选举,我们概括下:

当挂掉的master有多个slave时,存在多个slave竞争为master节点过程,过程如下:

  •   1)过半主节点发现该主节点下线了才标记为客观下线 ,集群广播fail消息   
  •   2)检查从节点与主节点最后断线时间,发现超过了cluster-node-time*cluster-slave-validity-factor的不具有资格
  •   3)准备选举,复制偏移量越大的节点说明从节点延迟越低,优先选举
  •   4)从节点收到集群内超过一半的主节点的投票后成为主节点
  •   5)替换主节点,获取槽,广播自己的pong消息,让其他从节点成为他的小弟
     

 

3,消息队列集群

对于消息队列的集群,我们举了rabbitmq和kafka来进行比较,我们可以思考对比出这两种消息队列的吞吐性能和功能区分。

1)rabbitmq集群

rabbitmq不是很熟悉的同学可以看下我之前文章的科普知识

rabbitmq之一---消息队列基础

对于rabbitmq是基于erlang这种天生具有分布式特性的语言写的,所以天然的rabbitmq支持 集群化,意思是集群的元数据不需要通过zk来存储,rabbitmq集群的exchange信息会同步到所有节点上,但是Queue的完整信息注意只存在所创建的那个节点上,其他节点只知道指向queue的owner node的指针

那对于这种情况我们思考几个问题:

   1,rabbitmq如何实现集群?

rabbitmq集群方式比较简单,
1)修改所有机器的cookie文件为同一个值
2)配置各个节点hosts文件,写入各集群节点hosts

xxx.xxx.xxx.xxx rmq-broker-test-1
xxx.xxx.xxx.xxx rmq-broker-test-2
xxx.xxx.xxx.xxx rmq-broker-test-3
......
xxx.xxx.xxx.xxx rmq-broker-test-10

3)启动各节点,以一个为主节点,其他逐一加入

rabbitmqctl stop_app 
rabbitmqctl reset 
rabbitmqctl join_cluster rabbit@rmq-broker-test-2 
rabbitmqctl start_app 

   2,rabbitmq各节点角色?

rabbitmq节点有两种角色:内存节点,磁盘节点。为了持久化和高可用,必须保证两个以上的磁盘节点,防止一个崩溃导致数据丢失。

  3,如何实现负载均衡?

我们刚才讲到每个队列只有自己的完整信息,通过集群中的其他节点来访问另一个节点的队列时,会被转发到原来的队列进行消费,所以原来的集群方式无法实现负载均衡。那这样要提高吞吐量的需要通过第三方负载均衡器来帮助,我们可以使用HAProxy来辅助实现负载均衡

listen rabbitmq_cluster
        bind 0.0.0.0:5672
        #配置TCP模式
        mode tcp
        #加权轮询
        balance roundrobin
        #RabbitMQ集群节点配置,其中ip1~ip4为RabbitMQ集群节点ip地址
        server rmq_node1 ip1:5672 check inter 5000 rise 2 fall 3 weight 1
        server rmq_node2 ip2:5672 check inter 5000 rise 2 fall 3 weight 1
        server rmq_node3 ip3:5672 check inter 5000 rise 2 fall 3 weight 1
        server rmq_node4 ip4:5672 check inter 5000 rise 2 fall 3 weight 1
        ......

通过这种加权轮询各个rabbitmq节点实现负载均衡提高单位时间吞吐量。

 

2)kafka集群

对于kafka而言因为它的设计目标就是高吞吐量,所以我们来看看kafka的集群方式如何配置:

1,配置zookeeper。kafka集群的元数据都得通过zookeeper来进行保存,通过zk来调配之间节点的状态,节点是无状态的。

2,kafka节点启动,注意配置连接zk端口。

接下来我们来看看kafka为了实现高吞吐量,高可用使用了什么架构

如图所示,生产者会按照主题(topic)投递到kafka集群。然后消费者按照指定的topic去消费。

那么这种方式就非常方便我们实现

1,高吞吐量:将一个主题划分到多个broker,在每个broker存放一个partition(分区),那么通过多节点可以顺利实现吞吐量的提高

2,高可用:指定partition(分区)的备份个数,即副本数,实现数据的冗余备份。

 

三,分布式理论

通过科普了两种分布式理论后我们思考下不同中间件的设计出发点,从而更能明白其分布式集群设计。

   1) CAP理论

CAP理论告诉我们:一个分布式系统不可能同时满足一致性(C:Consistency)、可用性(A:Availability)和分区容错性(P:Partition tolerance)这三个基本需求,最多只能同时满足其中两项

     由于这三者无法全部实现,可以实现为:

选择                                                                                                        说    明
CA 放弃分区容错性,加强一致性和可用性,其实就是传统的单机数据库的选择
AP 放弃一致性(这里说的一致性是强一致性),追求分区容错性和可用性,这是很多分布式系统设计时的选择,例如很多NoSQL系统就是如此
CP 放弃可用性,追求一致性和分区容错性,基本不会选择,网络问题会直接让整个系统不可用

 2)BASE理论

BASE是Basically Available(基本可用)、Soft state(软状态)和Eventually consistent(最终一致性)

BASE理论的核心思想是:即使无法做到强一致性,但每个应用都可以根据自身业务特点,采用适当的方式来使系统达到最终一致性

  1. 基本可用:指分布式系统在出现不可预知故障的时候,允许损失部分可用性
  2. 软状态:允许系统中的数据存在中间状态,并认为该中间状态的存在不会影响系统的整体可用性
  3. 最终一致性:最终一致性强调的是所有的数据副本,在经过一段时间的同步之后,最终都能够达到一个一致的状态

四,分布式集群分析及总结

      我简单介绍了zookeeper集群,redis集群,rabbitmq集群,kafka集群的构建等内容,那我们思考下对于集群化设计注意事项和思考点,为我们去分析和了解各种集群应用做个知识铺垫。

  • 1,zookeeper出身就是作为分布式协调系统,系统着重于维护分布式集群的各种情形:集群间节点主从关系,新增节点,节点宕机等分布式常见情况,数据量请求不大。
  • 2,redis作为一个nosql,由于redis强调内存读写性能,讲究一个字:快。而cluster集群模式是redis3.0才推出的,所以其实前期有各种公司出proxy方案用于配合redis,如推特的twenty,豌豆荚的codis方案。
  • 3,rabbitmq出身于金融领域,所以更加强调消息可靠性,有各种实现可靠性方案,所以我们注意到如果需要加强吞吐量得使用负载均衡器来辅助实现,使用erlang也使其自带分布式。
  • 4,kakfa而言,目标是一个高吞吐量的分布式发布订阅消息系统,为日志而生,所以天生就带有各种分区,多副本。但是需要zk来辅助管理集群化。

然后我们其实可以看了CAP理论,BASE理论后我们思考,因为不能将一个分布式系统做到完全的满足CAP,必然选择性放弃一部分,我们看看这几种分布式中间件集群方案如何考虑:

  1. zookeeper,高度强调可用性,你能想象一个负责动物园管理员倒下的日子么?其他动物岂不是得无法无天了。所以他有一套基于ZAB的分布式协调方案,他就不强调中心化,允许动物园的动物们去跟“从管理员”打交道,读数据不强调需要跟动物管理员老大打报告,虽然带来一定的数据不一致性(存在写数据需要传播到整个集群的过程),但是保证了高可用,当然也是因为zk的写请求不大,所以一定的数据延迟带来的不一致是允许的。
  2. redis,强调数据的读写速率,所以他的cluster集群方案用了一种去中心化方案。先分槽,让多个主节点去分散的承担读写任务,然后从节点只作为数据备份(读写分离一般少设计),因为它认为通过内存的随机读写速度已经足够快满足用户需求,也保证数据的一致性,当然对于异常情况如主节点倒下时,也模拟了选举方式,然后尽量选择数据和主节点最接近的从节点来保证数据的相对一致性。
  3. rabbitmq,强调可靠性1)数据可靠。所以集群化设计时,如果你设置消息要落盘持久化时,他会等磁盘节点写入成功才返回OK,即使内存节点已经可以进行操作,为了提高吞吐量的话需要通过HAProxy负载均衡,但是也会受限于磁盘写入速度。2)系统可靠,假如存在异常情况,主节点挂掉,由于rabbitmq是天然支持分布式的,自然会从 从节点来代替主节点工作,不需要经过什么选举过程,系统恢复工作速率更快。
  4. kafka,强调高吞吐量。kafka集群系统通过zk来进行集群管理,使用分区来实现一个topic在多个broker中入队,然后也可以通过多副本在多broker中存储备份,所以你会注意到多副本下的几个broker是基本镜像一样,那么如果发生一个节点异常,那么直接通过ZK来选举出一个来代替即可。

欢迎观看,可以点赞支持哈。

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

中间件(redis,rabbitmq,zookeeper,kafka)集群讨论及搭建 的相关文章

  • Dagger2的使用以及原理分析

    使用 Dagger2的使用说起来并不难 关键在于要掌握Dagger2的提供的几个注解及其意思 环境搭建 在模块级的build gradle文件中加入如下依赖 plugins id com android application id org

随机推荐

  • C++:基于浅拷贝/深拷贝对模拟string类的一些优化

    文章目录 string类和日期类 浅拷贝 深拷贝 对于上述代码的深拷贝写法 正常版本和优化版本 写时拷贝 string类和日期类 前面我们已经实现了string类和日期类 这两个类有没有想过它们有什么不同 其实答案很明显 不同的地方在于st
  • vue history模式刷新页面进入404解决方案

    前言 vue 的路由模式严格意义上来讲有三种 但是常见的hash模式和history模式 1 默认的路由模式 2 hash模式 就是连接后边会跟 号 3 history模式 history模式的详细配置请移步官方文档vue路由history
  • PLL时钟约束

    方法 1 自动创建基时钟和 PLL 输出时钟 例 derive pll clocks 这一方法使您能够自动地约束 PLL 的输入和输出时钟 ALTPLL megafunction 中指定的 所有 PLL 参数都用于约束 PLL 的输入和输出
  • 安恒10月夺旗赛

    概述 昨天参加的比赛 这个比赛是信安之路微信公众号和安恒合作的一个比赛 是个人赛 作为一个大一的嫩鸡 还是搞web的 对于re和pwn毫无办法 所以昨天最终的结果是这样的 过程 这一次部分题需要用VPN内网访问 但是不知道为什么刚开始的时候
  • Verilog HDL 语言笔记

    目录 一 基本语法 1 模块的结构 1 模块声明 2 端口定义 3 数据类型说明 4 逻辑功能描述 2 语言要素及数据类型 2 1语言要素 2 2 常量 2 3 变量和数据类型 2 4 参数 2 5 向量 2 6 存储器 2 7 运算符 3
  • phpstorm定位错误代码

    phpstorm可以智能的帮你发现错误 例如你在文件中有一处语法错误 它会自动帮你标红 但当你打开这个文件 想找到具体错误代码在哪一行 你需要一行一行的浏览 而且错误标记不是很明显 这样太痛苦了 解决方法 点击Next Highlighte
  • ios抓包工具stream抓包教程

    ios抓包工具stream抓包教程 1 首先在应用商店搜索并下载stream 2 安装后打开app 3 准备安装证书 4 选择安装证书 允许应用添加vpn配置 5 这时app会自动跳转至浏览器下载证书文件 允许即可 6 下载完成后在描述与文
  • 为不同的调制方案设计一个单载波系统(映射器-信道-去映射器)(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码实现 1 概述 本代码为不同的调制方案 BPSK QPSK
  • cadence allegro 学习记录(一)

    1 主题颜色设置 Options Preference Applications Theme 在Schematic Theme 原理图的主题颜色中修改 2 原理图格点设置 Options Preference Grid Display 左侧
  • java入门基础知识(第一课)初识Java!!!

    硬件 硬盘 计算机永久存储数据的载体 所有计算机所要使用的信息都存储在这里 内存 计算机暂时存储数据的载体 主要负责将数据从硬盘中传输到CPU中 平衡速率差 CPU 计算机的核心 大脑 主要处理单元 所有的信息都由CPU进行运算得出结果 软
  • MySQL常见报错

    1 授权错误 更改root密码 ALTER USER root IDENTIFIED WITH mysql native password BY 123456 2 Can t open file xxx forums MYI errno 1
  • 大页内存原理及使用设置

    内存分页大小对性能的提升原理 首先 我们需要回顾一小部分计算机组成原理 这对理解大内存分页至于JVM性能的提升是有好处的 什么是内存分页 我们知道 CPU是通过寻址来访问内存的 32位CPU的寻址宽度是 0 0xFFFFFFFF 计算后得到
  • Android牛人启航博客地址

    http blog csdn net harvic880925 article category 1707319
  • (2023)Linux安装pytorch并使用pycharm远程编译运行

    2023 Linux安装pytorch并使用pycharm远程编译运行 安装miniconda 这部分参考我这篇博客的前半部分Linux服务器上通过miniconda安装R 2022 miniconda 安装r Dream of Grass
  • 服务器硬盘sas速度多少,服务器硬盘SAS接口和SATA接口哪个速度快,它们分别有什么优缺点?...

    SATA 串行ATA总线 SAS 希捷研究出来的取代SCSI技术的接口 目前SCSI是最高级的硬盘 SAS没有大量上市 同ATA一样 SCSI是一种能够通过各自的数据信道连接多种设备的并行技术 和ATA一样 SCSI也向串行技术方向有所发展
  • Anaconda3安装PyEcharts包后无法正常调用

    最近在研究数据可视化问题 然后得知了Python的PyEcharts包库 使用pip install pyecharts 命令安装显示成功 但是在Spyder中输入from pyecharts import Bar 显示无法import b
  • [机器学习与scikit-learn-35]:算法-分类-支持向量机-线性分类代码示例

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 https blog csdn net HiWangWenBing article details 123800789 目录 前言 第1步骤
  • python - 数据分析之matplotlib绘图模块一览总表

    Matplotlib 入门 https deepinout com matplotlib matplotlib tutorials matplotlib easy to start html Matplotlib 教程 https geek
  • GitHub私活利器【开源版】前后端分离的Java 商城系统(已上线)

    项目介绍 Smart Shop 是一款基于 Spring Cloud MybatisPlus XXL JOB redis Vue 的前后端分离 分布式 微服务架构的 Java 商城系统 添加图片注释 不超过 140 字 可选 技术架构 运行
  • 中间件(redis,rabbitmq,zookeeper,kafka)集群讨论及搭建

    一 前言 大家好 我是小墨 这一篇文章我们来一个中间件的集群的搭建的大团圆章节 将围绕我们使用的主流几个中间件 我使用过的 的集群构建方式进行原理讨论和实际搭建方案探讨 包括zookeeper redis rabbitmq zookeepe