01 ZooKeeper初探


传送门:


ZooKeeper初探

1. 为什么使用ZooKeeper?

  Nginx管理很多台服务器时,会碰到性能瓶颈。此时,就用到本章所学的ZooKeeper。

image-20211217154945169

如果某台提供订单的服务器不能提供,则Nginx 不给这台服务器转发清单列表。这样一种服务注册与服务发现的技术。订单相关的真实服务器会在zookeeper管理的属性结构中创建临时节点;一旦服务器出现故障,则这个连接就会断开,临时节点就会消失。Nginx可以做监听节点,一旦子节点发生改变,Nginx上的服务器列表与zookeeper上的节点做一个同步的操作。这是Nginx与zookeeper的典型应用。

从单机开发到分布式开发:

  • Nginx 作为负载均衡管理大量服务器时,管理起来比较麻烦,可以通过 zookeeper 实现注册服务与发现服务协作管理

  • 以前大部分应用需要开发私有的协调程序,缺乏一个通用的机制协调程序,反复编写浪费,且难以形成通用、伸缩性好的协调器

  • 使用分布式部署后,多线程并发安全的问题,以前学的同步代码块、重构锁、读写锁等通通失效,怎么办?

    使用zookeeper,在分布式集群外面实现分布式锁,这也是用zookeeper来实现分布式开发的协调程序的一个典型的应用场景

  • 大数据分布式集群中,集群的服务器如何管理?

2. zookeeper概述

2.1 zookeeper简介

  zookeeper:动物园管理员

  ZooKeeper 是分布式应用程序的协调服务框架,是 Hadoop 的重要组件。ZooKeeper 是 Google 的 Chubby 一个开源的实现,是 Hadoop 的分布式协调服务,包含一个简单的原语集,分布式应用程序可以基于它实现。

扩展:zookeeper是基于Google的一篇论文《The Chubby lock service for loosely coupled distributed systems》

2.2 具体应用场景

  1. Hadoop,使用 ZooKeeper 的事件处理确保整个集群只有一个 NameNode,存储配置信息等.

    image-20211217161813712

    ZooKeeper集群通常是奇数台的,便于选举

    如图,有两台NameNode,让这两台NameNode去ZooKeeper集群上注册节点(临时节点),不管是谁将临时节点注册下来,就是Active NameNode;另一台为Standby NameNode;当Active NameNode连接出现断开时,临时节点就会消失。另一台Standby NameNode立即注册临时节点,从Standby切换成Active。当运维人员将原来的Active NameNode修复好之后,则变成Standby NameNode。这是一个Hadoop里面比较典型的应用。

  2. HBase, 使 用 ZooKeeper 的 事 件 处 理 确 保 整 个 集 群 只 有 一 个 HMaster, 察 觉HRegionServer 联机和宕机,存储访问控制列表等。与Hadoop中原理非常相似。

3. 分布式编程容易出现的问题

  分布式的思想就是人多干活快,即用多台机器同时处理一个任务。分布式的编程和单机的编程 思想是不同的,随之也带来新的问题和挑战。

  1. 活锁

    活锁定义:在程序里,由于某些条件的发生碰撞,导致重新执行,再碰撞=》再执行,如此循环往复,就形成了活锁。活锁的危害:多个线程争用一个资源,但是没有任何一个线程能拿到这个资源。(死锁是有一个线程拿到资源,但相互等待互不释放造成死锁),活锁 是死锁的 变种。

    补充:活锁有更深层次的危害,耗尽 cpu 资源(在做无意义的调度)

  2. 需要考虑集群(几千台服务器)的管理问题,需要有一套机制来检测到集群里节点的状态变化

  3. .如果用一台机器做集群管理,存在单点故障问题,所以针对集群管理,也需要形成一个集群

  4. 管理集群里Leader的选举问题(要根据一定的算法和规则来选举),包括要考虑Leader挂掉 之后,如何从剩余的 follower 里选出 Leader

  5. 分布式锁的实现,用之前学的重入锁,同步代码块是做不了的

4. 拜占庭将军问题到信息安全(面试)

image-20211217170206188

拜占庭将军问题”是由著名计算机科学家莱斯利•兰伯特(LeslieLamport)提出的点对点通信中的基本问题,也可称为“两军问题”或者“拜占庭容错”,是分布式系统的经典问题。

  在5〜15世纪,拜占庭就是当时的东罗马帝国,也就是现在土耳其的伊斯坦布尔。可以想象,拜占庭军队有许多分支,驻守在敌人城外随时准备进攻,每一个分支都有各自的将军。当时的环境决定了骑马传递信息是将军之间通信和协调统计进攻时间的唯一途径。由于敌人的防御比较强大,任何一个军队分支的单独入侵行动都会失败,而且入侵的分支还会被歼灭。因此,只有一半以上的分支同时进攻才能成功占领敌人的城池。在观察了敌情以后,将军们需要制订出一个统一的进攻计划,即确定出在哪一天的哪一时刻进攻。然而将军中存在一个叛徒,他的任务就是破坏忠诚将军们的进攻计划,使他们的进攻不能达成一致。这样只要进攻时的军队分支少于一半,敌人就会胜利,叛徒的目的就达到了。这是一个由互不信任的各方构成的网络,但是他们需要完成一个共同使命(除叛徒以外)。由于各个将军之间互相不信任,认为只有在自己的城堡以及军队范围内才能保障自己的生命安全,所以将军们不会聚集到一起开会。在这种情况下,他们在任意时间以任意P率派出任意数量的信使到任意对方,内容如下:“我将在第X天的第X点进攻,你同意吗?”如果收到信息的将军同意该做法,他就会在原信上附上一份盖章验证的回信,然后把合并之后的信息拷贝再次发送给其余的将军们,要求他们也这样做。他们的目标就是通过原始信息的积累使最后的信息链盖上他们所有将军的图章,在时间上达成共识。问题出现在这里,假设有10个将军,每个将军向其他9个将军派出一名信使,那么就是10个将军每人派出了9名信使,而在任意时间内有总计90次的传输,并且每个将军分别收到9个信息,可能每一封信的进攻时间都不同。另外,叛变的将军还会同意超过一个以上将军的攻击时间,然后重新广播超过一条的信息链。于是,这个系统迅速演变成一个信息虚假和攻击时间相互矛盾的纠结体。

  ZooKeeper不会出现拜占庭将军问题,因为ZooKeeper集群通常是放在局域网当中,在局域网中,本身之间是相对安全的;信息在服务器与服务器的传输过程中,可以进行信息加密,只有有对应的解密算法才可以获取信息,极大提升信息在传输过程的安全问题。

5. Paxos小岛故事(Paxos分布式一致性算法)

  那么 ZooKeeper 最基础的东西是什么呢?不得不提 Paxos,它是一个基于消息传递的一致性算法,Leslie Lamport(莱斯利·兰伯特)在 1990 年提出,近几年被广泛应用于分布式计算中,Google 的 Chubby,Apache 的 ZooKeeper 都是基于它的理论来实现的, Paxos 还被认为是到目前为止唯一的分布式一致性算法,其它的算法都是 Paxos 的改进或 简化。有个问题要提一下,Paxos 有一个前提:没有拜占庭将军问题。就是说 Paxos 只有在一个可信的计算环境中才能成立,这个环境是不会被入侵所破坏的。

636193818180885077

  Paxos 描述了这样一个场景,有一个叫做 Paxos 的小岛(Island)上面住了一批居民,岛上面所有的事情由一些特殊的人决定,他们叫做议员(Senator)。议员的总数(Senator Count)是确定的,不能更改。岛上每次环境事务的变更都需要通过一个提议(Proposal), 每个提议都有一个编号(PID),这个编号是一直增长的,不能倒退。每个提议都需要超过半数((Senator Count)/2 +1)的议员同意才能生效。每个议员只会同意大于当前编号的提议,包括已生效的和未生效的。如果议员收到小于等于当前编号的提议,他会拒绝,并告知对方:你的提议已经有人提过了。这里的当前编号是每个议员在自己记事本上面记录的编号,他不断更新这个编号。整个议会不能保证所有议员记事本上的编号总是相同的。现在议会有一个目标:保证所有的议员对于提议都能达成一致的看法。

  好,现在议会开始运作,所有议员一开始记事本上面记录的编号都是 0。有一个议员发了一个提议:将电费设定为 1 元/度。他首先看了一下记事本,嗯,当前提议编号是 0,那么我的这个提议的编号就是 1,于是他给所有议员发消息:1 号提议,设定电费 1 元/度。其他议员收到消息以后查了一下记事本,哦,当前提议编号是 0,这个提议可接受,于是他记录下这个提议并回复:我接受你的 1 号提议,同时他在记事本上记录:当前提议编号为 1。发起提议的议员收到了超过半数的回复,立即给所有人发通知:1 号提议生效!收到的议员会修改他的记事本,将 1 号提议由记录改成正式的法令,当有人问他电费为多少时,他会查看法令并告诉对方:1 元/度。

  现在看冲突的解决:假设总共有三个议员 S1-S3,S1 和 S2 同时发起了一个提议:1 号提议,设定电费。S1 想设为 1 元/度, S2 想设为 2 元/度。结果 S3 先收到了 S1 的提议,于是他 做了和前面同样的操作。紧接着他又收到了 S2 的提议,结果他一查记事本,咦,这个提议 的编号小于等于我的当前编号 1,于是他拒绝了这个提议:对不起,这个提议先前提过了。 于是 S2 的提议被拒绝,S1 正式发布了提议: 1 号提议生效。S2 向 S1 或者 S3 打听并更新了 1 号法令的内容,然后他可以选择继续发起 2 号提议。

  如果议员人人平等,在某种情况下会由于提议的冲突而产生一个“活锁”(所谓活锁我的理解是大家都没有死,都在动,但是一直解决不了冲突问题)。Paxos 的作者 Lamport 在他的文章”The Part-Time Parliament“中阐述了这个问题并给出了解决方案—— 在所有议员中设立一个总统,只有总统有权发出提议,如果议员有自己的提议,必须发给总统并由总统来提出。

现在我们假设总统已经选好了,下面看看 ZK 是怎么实施的。

  • 情况一:

    总统突然挂了,议员接二连三的发现联系不上总统,于是各自发表声明,推选新的总统,总统大选期间政府停业,拒绝屁民(Client)的请求。呵呵,到此为止吧,当然还有很多其他的情况,但这些情况总是能在 Paxos 的算法中找到原型并加以解决。这也正是我们认为 Paxos 是ZooKeeper 的灵魂的原因。当然 ZK 还有很多属于自己特性的东西:Session, Watcher,Version 等等。

  • 情况二:

    屁民甲(Client)到某个议员(ZK Server)那里询问(Get)某条法令的情况(ZNode 的数据),议员毫不犹豫的拿出他的记事本(local storage),查阅法令并告诉他结果,同时声明:我的数据不一定是最新的。你想要最新的数据?没问题,等着,等我找总统 Sync 一下再告诉你。

  • 情况三:

    屁民乙(Client)到某个议员(ZK Server)那里要求政府归还欠他的一万元钱,议员让他在办公室等着,自己将问题反映给了总统,总统询问所有议员的意见,多数议员表示欠屁民的钱一定要还,于是总统发表声明,从国库中拿出一万元还债,国库总资产由 100 万变成99 万。屁民乙拿到钱回去了(Client 函数返回)。

在 ZK Server 里面 Paxos 是如何得以贯彻实施的:

  • 小岛(Island)—ZK Server Cluster(ZK服务器集群)
  • 议员(Senator)—ZK Server(ZK服务器)
  • 提议(Proposal)—ZNode Change(Create/Delete/SetData…)(ZK节点的改变)
  • 提议编号(PID)—Zxid(ZooKeeper Transaction Id)(ZK的事务ID)
  • 正式法令—所有 ZNode 及其数据(ZK树形结构的节点中的数据)
  • 总统—ZK Server Leader

6. ZooKeeper集群

在ZooKeeper使用过程中,有常见的两种模式:

  • 单节点模式(独立模式)

    ZooKeeper Server只有一台,又称为独立模式。这种模式存在一个严重的问题:单点故障。如果这台服务器出现故障,则它管理的集群就会整体陷入瘫痪。在工业生产中通常不会使用这种模式。

  • 集群模式(仲裁模式)

    集群模式正如下图所示。ZooKeeper集群常用的台数是3、5、7、9,都是奇数台。在后面做选举时,奇数台更便于选出Leader。

在ZooKeeper服务器使用过程中,有常见的四种状态:

  1. looking状态:服务器处于寻找leader的状态
  2. leading:作为leader状态
  3. following:作为follower状态
  4. observing:作为observer状态,不参与选举,但会同步server的状态,执行server存放在消息队列的操作

image-20211217194101420

攘其外:消息队列 (当ZooKeeper server处理的信息较多时,消息队列(先进先出)用来保证顺序性

安其内:选举(先比较事务ID,如果事务ID不同,则大的为新的Leader;如果事务ID相同,则比较选举ID,大的为Leader)

选举分为两种场景:

  1. 集群启动时

    启动又可以分为两种场景:

    • 同时启动
    • 顺序启动,在超过一半服务器启动后就开始了选举。此时,一般会将中间启动的作为Leader
  2. 集群工作时,且leader down掉时

    在follower中进行选举,先比较事务ID,如果事务ID不同,则大的为新的Leader;如果事务ID相同,则比较选举ID,大的为Leader

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值