zookeeper集群


zookeeper集群中,observer是不参与选举的,其主要作用是分担大量读的压力。follower参与选举,不处理事务请求,当事务请求落到follower或observer上时,这些节点会将事务请求转发到leader节点。leader节点挂了,所有的follower会重新进行选举。

zookeeper选举

选举要素

选举的三个要素:

  1. 每个zookeeper节点有三个状态:
  • LOOKING:游离态(没入党),节点的初始状态,不在集群中,等待参与选举。
  • FOLLOWER:已入党,参入过选举,知道leader是谁。
  • LEADER:党的领导人。
  1. 选举投票Vote信息:
  • id:选投为leader的id
  • zxid:机器的最大事务id
  • epoch:选举周期
  • state:投票机器的状态(LOOKING/FOLLOWER/LEADER)
  1. 机器节点间通信:
    每个机器都有一个专用于选举的端口。

选举流程

以上三个要素都有了,下面看是怎么选举的,以3个节点为例:

  • 服务启动都要与其它节点建立通信:

    后面发送选票和接收选票都用这个socket连接进行。socket连接是全双工通信,所以每两个节点间,只需要建立一条socket连接即可。
  1. 第一轮投票
    在服务启动参与选举时,每个节点先投自己一票:
  2. 第二轮投票
    因为第一轮投票,每个节点都是投自己一票,所以无法满足票数过半的要求,所以要进行第二轮投票,这时,每个节点会将第一轮pk获胜的选票投出。
  3. 选举结果
    根据第二轮投票,必定会出现票数过半的票。最终选举节点2为leader:

    后面加入的机器,如何选举leader呢?
    当leader已经选举完成后,集群中已经有leader节点了,所以再有机器加入也不用重新选举了。新加入的机器,会投自己一票给其它节点,票中有state表明自己为LOOKING状态。集群中的节点收到选票后,会判断选票是否为LOOKING机器投的。如果是则将已知的leader投出去,这样新加入的机器,就会获得leader节点选票,直接获得leader。

手写zookeeper选举流程

本工程只实现了选举功能,根据zookeeper选举流程实现,zookeeper用到了多级队列,此处只用到了一级,结构更加简单,便于深入理解zookeeper选举机制。
git代码地址:https://github.com/hiwei-zhang/zab
项目启动:
QuorumPeerMain.main方法启动。

建立三个启动项。zoo.cfg换为自己地址即可。在resources目录下已经建立三个zoo.cfg文件。这里只配置用于选举的端口地址。myid和zookeeper的myid用处一样。
依次启动三个应用,就可以在控制台看到选举信息。

整体流程图:


实现架构:

  1. 如何保证两个节点间只有一个socket连接?
        private void handleConnection(ZkSocket zkSocket) {Long sid = null, protocolVersion = null;try {Socket sock = zkSocket.getSocket();protocolVersion = zkSocket.getDin().readLong();if (protocolVersion >= 0) { // this is a server id and not a protocol versionsid = protocolVersion;}//判断对方id是否大于本机id,大于则保存连接。否则关闭连接,并重新主动去连接if(sid<myid){closeSocket(sock);if(!socketMap.containsKey(sid)){String address = serverMap.get(sid);String[] ap = address.split(":");ZkSocket socket = connectOn(ap[0], Integer.parseInt(ap[1]));if(socket!=null){putListener(sid,socket);}}}else{putListener(sid,zkSocket);}} catch (IOException e) {e.printStackTrace();}}
  1. leader挂掉,怎么触发选举?
    与leader保持心跳连接,当检测到失去连接后,重置本机状态,并发送选票,参与选举。
public void run(){//获取选票while(ServerInfo.isRunning){ZkSocket zkSocket = socketMap.get(sid);if(zkSocket!=null){try {DataInputStream din = zkSocket.getDin();int capacity = din.readInt();if(capacity>0){byte[] bytes = new byte[capacity];din.readFully(bytes,0,capacity);recvQueue.offer(parseMsg(bytes));}} catch (Exception e) {log.error("connect closed : {}",zkSocket.getSocket());socketMap.remove(sid);recvListenerMap.remove(sid);if(ServerInfo.status!=ServerStatusEnum.LOOKING&&ServerInfo.currentVote.getId()==sid){//发起选举log.info("leader {}失去连接,重新选举......",sid);ServerInfo.status = ServerStatusEnum.LOOKING;ServerInfo.currentVote = null;}break;}}}}

共同学习,如果有用,请点个赞。

攻破zookeeper选举流程(附带手写实现)相关推荐

  1. 手写webserver服务器

    手写webserver服务器 文章目录 手写webserver服务器 前言 一.web server执行流程 组件说明 项目地址 二.代码实现 三. 效果展示 四.总结 前言 webserver 服务 ...

  2. 浅谈 yso的 Commons-Collections1 (cc1)反序列化链 如何手写这条链子

    yso的cc1 ysoserial/src/main/java/ysoserial/payloads at master · frohoff/ysoserial (github.com) 这里面找 p ...

  3. 深度学习入门实践学习——手写数字识别(百度飞桨平台)——上篇

    一.项目平台 百度飞桨 二.项目框架 1.数据处理: 2.模型设计:网络结构,损失函数: 3.训练配置:优化器,资源配置: 4.训练过程: 5.保存加载. 三.手写数字识别任务 1.构建神经网络流程: ...

  4. 手写数字图片二值化转换为32*32数组。

    最近课设外加生病,本来打算在上一篇机器学习使用k-近邻算法改进约会网站的配对效果.就打算写的一直没有时间.按照<机器学习实战>的流程,手写数字识别是kNN中的最后一部分,也是一个比较经典的 ...

  5. ZooKeeper 集群:集群概念、选举流程、机器数量

    文章目录 集群 集群角色 选举 服务器启动时期的选举 服务器运行时期的选举 集群的机器数量 集群 集群角色 通常在分布式系统中,构成一个集群的每一台机器都有自己的角色,最常见的集群模式就是Master ...

  6. zookeeper专题:zookeeper集群模式下,leader选举流程分析

    文章目录 Zookeeper 集群模式一共有三种类型的角色 1. zookeeper启动时leader选举流程 1.1 加载配置文件,设置基本信息 1.2 指定快速选举算法,启动多级队列.线程 1.3 ...

  7. 使用Caffe进行手写数字识别执行流程解析

    之前在 http://blog.csdn.net/fengbingchun/article/details/50987185 中仿照Caffe中的examples实现对手写数字进行识别,这里详细介绍下 ...

  8. Zookeeper源码分析:选举流程

    参考资料 <<从PAXOS到ZOOKEEPER分布式一致性原理与实践>> zookeeper-3.0.0 Zookeeper选举模式 针对zookeeper-3.0.0版本,选 ...

  9. zookeeper springboot_摊牌了!我要手写一个“Spring Boot”

    ❝ 目前的话,已经把 Spring MVC 相关常用的注解比如@GetMapping .@PostMapping .@PathVariable 写完了.我也已经将项目开源出来了,地址:https:// ...

最新文章

  1. corners边框_安卓中设置(shape)圆角背景和边框(stroke)相关的问题
  2. 句柄 matlab_matlab 整车仿真
  3. 【Fanvas技术解密】HTML5 canvas实现脏区重绘
  4. 活久见啊,WPF工资已经这么高了!
  5. 前端学习(2143):webpack的config.js配置和package.json
  6. 用姓名字段统计人数_基于 Wide amp; Deep 网络和 TextCNN 的敏感字段识别
  7. K-Means算法和K-Means++算法的聚类
  8. Linux技术网站中文,Linux技术网站,putty工具,中文显示设置
  9. easyui 添加下拉框数据_电商教父:关于淘宝关键词点击率以及提升数据的方法...
  10. C#中的委托是什么?事件是不是一种委托?
  11. 10年老分析师:数据分析不只是一个岗位,更是一种职场必备能力
  12. [原创]FineUI秘密花园(二十六) — 选项卡控件概述
  13. span 超出部分换行
  14. Mac OS X10.11下CocoaPods的安装过程
  15. 2022年寒假ACM练习1
  16. 小米蓝牙音箱驱动_2020年度智能音箱拆解报告汇总,涵盖27个品牌72款产品
  17. 于仕琪libfacedetection WIN10 VS2015
  18. Delphi中使用ReportMachine 6.5中汇总行不进行汇总的设置问题
  19. 《电脑音乐制作实战指南:伴奏、录歌、MTV全攻略》——第1篇 获取伴奏篇 第1章 MIDI音乐伴奏的获取与制作 1.1 电脑MIDI音乐与设备的介绍...
  20. 整理:Github上最受欢迎的仓库(截至2021年12月26日)

热门文章

  1. Hive之grouping sets用法详解
  2. 封装axios网络请求 超好用的
  3. Linux 6.2 系列生命周期已结束
  4. Android 打开Facebook应用账号主页或网页主页代码
  5. 奔步前端面试(实习)
  6. 前端开发条形码生成、打印的2种方式总结(保姆级图文教程)
  7. MOSFET IGBT
  8. 我们一起去旅行-上海西塘苏杭篇
  9. linux命令---grep命令
  10. 第一款真正意义上的区块链游戏是?