zoukankan      html  css  js  c++  java
  • zookeeper集群搭建及常用场景实现

    本文完整源码地址

    基于zookeeper的常用用法、分布式锁、分布式队列及leader选举实现
    https://github.com/killianxu/zookeeper_example

    zookeeper集群搭建

    1.linux下安装jdk
    yum list java*
    yum install java-1.8.0-openjdk-devel.x86_64
    查看jdk是否安装:java -version
    2.下载apache-zookeeper-3.5.5-bin.tar.gz,tar -zxvf解压
    3.进入conf目录,将zoo_sample.cfg重命名为zoo.cfg,改配置文件如下,其中server.1、server.2、server.3表示zookeeper集群服务器,以server.1为例,1表示服务器server id,用于标识服务器,106.52.210.34表示服务器ip,2881端口Leader和Follower或Observer交换数据使用,3881端口用于选举。clientPort表示客户端连接服务器的端口。

    4.dataDir 目录下创建名为 myid 的文件,在文件第一行写上对应的 Server id。
    5.执行./zkServer.sh start,开启zookeeper服务器进程。
    6../zkServer.sh status查看zookeeper进程状态。

    zookeeper基本概念及用法

    zookeeper内部数据模型类似目录树,每个节点称为zNode,每个节点可以存储数据且可以有子节点。每个zNode根据路径去标识,比如/app1/p_1表示p_1节点,zNode节点有版本的概念,且zNode节点可以被监控,当节点数据或子节点发生变化,监控程序可以收到通知。zNode节点有四种类型,分别为:持久节点(PERSISTENT)、持久顺序节点(PERSISTENT_SEQUENTIAL)、临时节点(EPHEMERAL)、临时顺序节点(EPHEMERAL_SEQUENTIAL)。PERSISTENT节点创建后,就一直存在,直到有删除操作来主动清除这个节点。PERSISTENT_SEQUENTIAL在持久节点的基础上,在创建节点过程中,ZK会自动为给定节点名加上一个数字后缀,作为新的节点名。EPHEMERAL
    客户端会话失效,这个节点就会自动被清除掉。EPHEMERAL_SEQUENTIAL在EPHEMERAL基础上ZK会自动为给定节点名加上一个数字后缀。

    zookeeper编程实例:

    运行结果如下:

    zookeeper应用场景

    1.配置中心,发布者将数据发布到ZK节点上,供订阅者动态获取数据,实现配置信息的集中式管理和动态更新。例如全局的配置信息,服务式服务框架的服务地址列表等就非常适合使用。(数据量很小,但是数据更新可能会比较快的场景)
    2.负载均衡,指软负载均衡。在分布式环境中,为了保证高可用性,通常同一个应用或同一个服务的提供方都会部署多份,达到对等服务。而消费者就须要在这些对等的服务器中选择一个来执行相关的业务逻辑,其中比较典型的是消息中间件中的生产者,消费者负载均衡。比如生产者根据分区信息轮询发送到不同分区。
    3.命名服务(Naming Service),在分布式系统中,通过使用命名服务,客户端应用能够根据指定名字来获取资源或服务的地址,提供者等信息。被命名的实体通常可以是集群中的机器,提供的服务地址,远程对象等等——这些我们都可以统称他们为名字(Name)。其中较为常见的就是一些分布式服务框架中的服务地址列表。通过调用ZK提供的创建节点的API,能够很容易创建一个全局唯一的path,这个path就可以作为一个名称。
    4.分布式通知/协调,watcher注册与异步通知机制,能够很好的实现分布式环境下不同系统之间的通知与协调,实现对数据变更的实时处理。
    5.集群管理与Master选举。集群机器监控,快速对集群中机器变化作出响应。过去的做法通常是:监控系统通过某种手段(比如ping)定时检测每个机器,或者每个机器自己定时向监控系统汇报“我还活着”。 这种做法可行,但是存在两个比较明显的问题:集群中机器有变动的时候,牵连修改的东西比较多;有一定的延时。利用ZooKeeper有两个特性,就可以实时另一种集群机器存活性监控系统:客户端在节点 x 上注册一个Watcher,那么如果 x的子节点变化了,会通知该客户端;创建EPHEMERAL类型的节点,一旦客户端和服务器的会话结束或过期,那么该节点就会消失。
    集群master选举,所有参与选举的机器像zookeeper发起创建EPHEMERAL_SEQUENTIAL类型节点,都允许创建成功,选取创建zNode编号最小的机器为master,每个机器监控比它小的下一个编号节点。比它小一号的节点被删除,则收到通知自己变成master节点。
    6.分布式锁,锁服务可以分为两类,一个是保持独占,另一个是控制时序。所谓保持独占,就是所有试图来获取这个锁的客户端,最终只有一个可以成功获得这把锁。通常的做法是把zk上的一个znode看作是一把锁,通过create znode的方式来实现。所有客户端都去创建 /distribute_lock 节点,最终成功创建的那个客户端也即拥有了这把锁。 控制时序,就是所有视图来获取这个锁的客户端,最终都是会被安排执行,只是有个全局时序了。做法和上面基本类似,只是这里 /distribute_lock 已经预先存在,客户端在它下面创建临时有序节点(这个可以通过节点的属性控制:CreateMode.EPHEMERAL_SEQUENTIAL来指定)。Zk的父节点(/distribute_lock)维持一份sequence,保证子节点创建的时序性,从而也形成了每个客户端的全局时序。
    7.分布式队列,一种是常规的先进先出队列,另一种是要等到队列成员聚齐之后的才统一按序执行。先进先出队列和分布式锁类似,在 /queue 这个znode下预先建立一个/queue/num 节点,并且赋值为n(或者直接给/queue赋值n),表示队列大小,之后每次有队列成员加入后,就判断下是否已经到达队列大小,决定是否可以开始执行了。这种用法的典型场景是,分布式环境中,一个大任务Task A,需要在很多子任务完成(或条件就绪)情况下才能进行。这个时候,凡是其中一个子任务完成(就绪),那么就去 /taskList 下建立自己的临时时序节点(CreateMode.EPHEMERAL_SEQUENTIAL),当 /taskList 发现自己下面的子节点满足指定个数,就可以进行下一步按序进行处理了。

    关键代码

    分布式锁

    分布式队列

    入队:

    出队:

    选举

    参考文献

    1. zookeeper集群搭建.https://juejin.im/post/5ba879ce6fb9a05d16588802
    2. 分布式服务框架 Zookeeper — 管理分布式环境中的数据.https://www.ibm.com/developerworks/cn/opensource/os-cn-zookeeper/index.html
    3. ZooKeeper典型应用场景一览.http://jm.taobao.org/2011/10/08/1232/
    4. Zookeeper源码分析目录.https://www.cnblogs.com/leesf456/p/6518040.html
  • 相关阅读:
    使用 SVC 修改代码
    USB device classes
    QUEUE Implement a first in, first out linked list
    Delphi Memory 函数
    ARM CortexM 分支指令编码
    W25Q16 driver
    TStringList.SaveToStream TStringStream.SaveToStream
    CreateFile, DeviceIoControl, ReadFile, WriteFile, CancelIo, CloseHandle, GetOverlappedResult
    CortexM3 / M4 SVC Handler
    move to www.csdn.net
  • 原文地址:https://www.cnblogs.com/killianxu/p/11254898.html
Copyright © 2011-2022 走看看