分布式协作框架 Zookeeper

简介

Zookeeper 是一个分布式协调服务框架,可用于服务发现,分布式领导选举,配置管理等。Zookeeper 提供了一个类似于 Linux 文件系统的树形结构(存放了少量信息的内存文件系统,不适合存储大量文件或大文件),同时提供了对每个分布式节点的监控与通知机制。

优点:

  1. 可靠性: 2n+1
  2. 可扩展性:需要增加机器时,少许修改即可,且不用冷启动(停机)
  3. 同步: 服务器进程之间的像话排斥和协作。
  4. 原子性:数据转移完全成功或完全失败,但没有事物是部分的?
  5. 序列化: 根据特定规则对数据进行编码。

特性

  1. 顺序一致性:保证客户端操作是按照顺序生效的
  2. 原子性:更新成功或者失败,没有部分结果
  3. 内容一致性:单个系统映像,无论连接到哪个服务器,客户端都将看到相同的内容
  4. 可靠性:数据的变更不会丢失,除非被客户端覆盖修改
  5. 及时性:保证系统端当前读取到的数据是最新的

应用场景:

(1)分布式协调:这个其实是zk很经典的一个用法,简单来说,就好比,你A系统发送个请求到mq,然后B消息消费之后处理了。那A系统如何知道B系统的处理结果?用zk就可以实现分布式系统之间的协调工作。A系统发送请求之后可以在zk上对某个节点的值注册个监听器,一旦B系统处理完了就修改zk那个节点的值,A立马就可以收到通知,完美解决。

(2)分布式锁:对某一个数据连续发出两个修改操作,两台机器同时收到了请求,但是只能一台机器先执行另外一个机器再执行。那么此时就可以使用zk分布式锁,一个机器接收到了请求之后先获取zk上的一把分布式锁,就是可以去创建一个znode,接着执行操作;然后另外一个机器也尝试去创建那个znode,结果发现自己创建不了,因为被别人创建了。。。。那只能等着,等第一个机器执行完了自己再执行。

(3)元数据/配置信息管理:zk可以用作很多系统的配置信息的管理,比如kafka、storm等等很多分布式系统都会选用zk来做一些元数据、配置信息的管理,包括dubbo注册中心不也支持zk么

(4)HA高可用性:这个应该是很常见的,比如hadoop、hdfs、yarn等很多大数据系统,都选择基于zk来开发HA高可用机制,就是一个重要进程一般会做主备两个,主进程挂了立马通过zk感知到切换到备用进程

架构

Zookeeper 的设计采用的是观察者的设计模式,zookeeper 主要是负责存储和管理所必需的数据,然后接受观察者注册,一旦数据发送变化,Zookeeper 就将负责通知已经在 Zookeeper 上注册的观察者。从而实现集群的 master/slave 管理模式。
在这里插入图片描述
Zookeeper 适用于主从构架(客户端-服务端架构)的高可用集群,每个节点分别承担了不同的集群角色。

  • Leader
    一个 Zookeeper 集群同一时间内只能有一个实际工作的 Leader, 它会发起并维护各 Follwer 及 Observer 间的心跳。
    Zookeeper 的写请求会被发送到 Leader 节点,然后 Leader 将数据变更的内容同步到集群的其它节点(Follower,Observer)。
    Leader 节点在接收到数据变更请求后,首先将变更数据写入本地磁盘,以作恢复之用,当所有写请求持久化磁盘以后,才会将变更应用到内存中。

  • Follower
    跟随 Leader 指令的服务器节点
    一个 Zookeeper 集群可能同时存在多个 Follower,它会响应 Leader 的心跳.

  • Observer
    不参与选举的服务器节点。

文件系统的树结构

在这里插入图片描述

ZooKeeper 节点称为 znode, 每个 znode 由一个名称标识, 并用路径 (/)序列分隔。首先有一个由 “/” 分隔的 znode。 在根目录下,有两个逻辑命命名空间 config 和 workers。

config:命名空间用于集中式配置管理,每个znode 最多可存储 1MB 的数据
worker:命名空间用于命名

Znode 的类型

持久节点:

  1. 即使在创建该特定 znode 的客户端断开连接后,持久节点仍然存在
  2. 默认情况下,所有 znode 都是持久化的。

临时节点:

  1. 客户端活跃时,临时及诶单就是有效的。 当客户端与 ZooKeeper 集合断开连接时,临时节点会自动删除
  2. 只有临时节点不允许有子节点
  3. 临时节点在 leader 选举中起着重要作用

顺序节点:

  1. 顺序节点可以是持久的或临时的。
  2. 当一个新的 znode 被创建为一个顺序节点时,zookeeper 通过将 10 位的序列号附加到原始名称来设置 znode 的路径,
  3. 顺序节点在锁定和同步中起重要作用

如何保证数据的一致性

在集群中,当 follower 或 observer 收到客户端的事务请求,会将该事务转发给 leader。当 leader 处理事务请求时,也会向整个集群的 follower 节点对象发送广播提议,当 follower 收到消息后作出相应响应并向 leader 发送消息,表示事务被成功处理。然后再向收到请求的 follower 进行通知,告之其进行事务提交,并最终会返回客户端一个事务被成功处理的状态。如果还有 follower 没及时进行事务同步操作,那么也最终会从 leader 去进行状态的同步。保证数据与 leader 一致性。

leader 如何判断事务处理成功:超过总数的一半的 (n/2 +1)的数量才表明操作成功。

zk 写入流程

在这里插入图片描述
数据写入最终一致性zab算法。leader负责处理写事务请求,follower负责向leader转发写请求,响应leader发出的提议。

搭建

单机模式

解压安装包
      tar -zxf zookeeper-3.4.10.tar.gz -C /opt/moduels

修改配置文件
     修改文件名 conf/zoo_sample.cfg -> /conf/zoo.cfg
            mv conf/zoo_sample.cfg /conf/zoo.cfg
     制定本地存储数据的路径:zoo.cfg
           # the directory where the snapshot is stored.
           # do not use /tmp for storage, /tmp here is just
           # example sakes.
           dataDir=/opt/modules/zookeeper-3.4.5/data/zkData (myid文件的路径)

启动服务端
       bin/zkServer.sh start

查看状态
       bin/zkServer.sh status

启动客户端
       bin/zkCli.sh

分布式模式

解压安装包
    tar -zxf zookeeper-3.4.10.tar.gz -C /opt/app

修改配置文件
     修改文件名 conf/zoo-simple.cfg /conf/zoo.cfg
               cp  conf/zoo-simple.cfg /conf/zoo.cfg
     制定本地存储数据的路径 zoo.cfg
              dataDir=/opt/app/zookeeper-3.4.5/data/zkData (myid文件的路径)
      添加服务端
              server.1=192.168.47.135:2888:3888   编号1
              server.2=192.168.47.133:2888:3888   编号2
              server.3=192.168.47.132:2888:3888   编号3
     
      修改 /data/zkData, 如果没有,就创建该目录
              vi myid
                 写入本机及其编号: 1

分发文件到其他主机上
       scp -r zookeeper-3.4.10/ 192.168.47.133:/opt/app/
       scp -r zookeeper-3.4.10/ 192.168.47.132:/opt/app/
       修改每个机器上的myid: 2,3,...


分别启动服务端
       bin/zkServer.sh start

分别查看状态
       bin/zkServer.sh status

可能出现的问题

  1. 配置 myid 的问题。
    其路径就是我们配置的路径。dataDir=/opt/app/zookeeper-3.4.5/data/zkData
    如果配置错误,在查看状态时,会有提示 conf配置错误。

  2. 需要删除 zoo_sample.cfg
    两个 zoo *** 不可能共存,否则在查看状态时也会提示server的问题
    It is probably not running

  3. 有时在 bin/zkServer.sh status 会发生 java.net.ConnectException: Connection refused 的问题
    可以分别启动所有的节点,并通过 jps 来查看进程是否开启,最后再用 bin/zkServer.sh status。
    我在第一个节点上始终都会发生这种情况,但是都启动完成后,再次看第一个节点却发现正常了。
    如果无法 stop ,可以使用 kill 来杀掉该进程,再次 start 即可。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值