ZOOKEEPER和KAFKA简介

目录

KAFKA

1.    kafka的特性

2.    Kafka的架构组件简介

3.    重要组件或概念详解

Topic、Partition、Offset

Producers

Consumers

4.    Kafka的一些设计思想和基本概念

5.    Kafka核心特性

压缩

消息可靠性

备份机制

6.    Kafka的应用场景

zookeeper

1     zookeeper简介

2     zookeeper特性

3     Zookeeper的架构及原理

3.1      Zookeeper的基本概念

3.2      Zookeeper的数据模型

3.3      Zookeeper的数据同步

3.4      Zookeeper的leader选举

4     zookeeper应用场景


KAFKA

Kafka是由LinkedIn开发的一个分布式的、可分区的、可复制的消息系统

1.   kafka的特性

(1)高吞吐量、低延迟:kafka每秒可以处理几十万条消息,它的延迟最低只有几毫秒

(2)可扩展性:kafka集群支持热扩展,增减broker可以做到对消费者、生产者几乎无感知

(3)持久性、可靠性:消息被持久化到本地磁盘,并且支持数据备份防止数据丢失

(4)容错性:允许集群中节点失败(若副本数量为n,则允许n-1个节点失败)

(5)高并发:支持数千个客户端同时读写

2.   Kafka的架构组件简介

a)        Broker:Kafka的一个服务实例就是一个broker

b)        Producer:生产消息到topic的一方

c)        Consumer:订阅topic消费消息的一方

d)        Consumer group:消费组,一个消费者属于一个特定的组

e)        topic:消息存放的目录即主题,可以理解为一个逻辑管理单元

f)         partition:一个物理概念,一个partition可以理解为linux中的一个目录,一个topic的消息可以包含一个或多个partition,每个partition可以设置多个副本,partition的多个副本中有一个是leader,负责响应生产者、消费者对partition的读写

                                 

3.   重要组件或概念详解

 Topic、Partition、Offset

Kafka中的Message是以topic为基本单位组织的,不同的topic之间是相互独立的。Topic以partition的形式存放,每个topic可以分成几个不同的partition(每个topic有几个partition是在创建topic时指定的)。Producer在生产数据时,会按照一定规则(这个规则是可以自定义的)把消息发布到topic的各个partition中。把消息日志以Partition的形式存放有多重考虑,第一,方便在集群中扩展,每个Partition可以通过调整以适应它所在的机器,而一个topic又可以有多个Partition组成,因此整个集群就可以适应任意大小的数据了;第二就是可以提高并发,因为可以以Partition为单位读写了。

kafka中的数据是持久化的并且能够容错的。Kafka允许用户为每个partition设置副本(Replications)数量,副本数量决定了有几个broker来存放写入的数据。如果你的副本数量设置为3,那么一份数据就会被存放在3台不同的机器上,那么就允许有2个机器失败。一般推荐副本数量至少为2,这样就可以保证增减、重启机器时不会影响到数据消费。如果对数据持久化有更高的要求,可以把副本数量设置为3或者更多。但只有一个partition的副本会被选举成leader作为读写用。

关于如何设置partition值需要考虑的因素。一个partition只能被一个消费者消费(一个消费者可以同时消费多个partition),因此,如果设置的partition的数量小于consumer的数量,就会有消费者消费不到数据。所以,推荐partition的数量一定要大于同时运行的consumer的数量。另外一方面,建议partition的数量大于集群broker的数量,这样leader partition就可以均匀的分布在各个broker中,最终使得集群负载均衡。需要注意的是,kafka需要为每个partition分配一些内存来缓存消息数据,如果partition数量越大,就要为kafka分配更大的heap space。

如下图所示,创建1个topic包含4个Partition,2 Replication。每个partition放在不同的broker上,同属一个partition的不同副本也在不同的broker上。


每个partition存储一部分Message。每个Partition中的消息都是有序的,生产的消息被不断追加到Partition上。如下图所示


Partition中的每条Message由offset来表示它在这个partition中的偏移量,这个offset不是该Message在partition数据文件中的实际存储位置,而是逻辑上一个值,它唯一确定了partition中的一条Message。因此,可以认为offset是partition中Message的id。partition中的每条Message包含了以下三个属性:

·         offset

·         MessageSize

·         Data

消费方是是根据offset来顺序查找message,如果一个partition下的文件非常大,会影响查找效率。Kafka对partition下的文件进行了分段并建立了索引文件,索引文件和数据文件的名字是一样的,只是扩展名不一样,文件名是以数据文件里面消息的最小offset来命名的如下图所示。





partition



index文件中并没有为数据文件中的每条Message建立索引,而是采用了稀疏存储的方式,每隔一定字节的数据建立一条索引。这样避免了索引文件占用过多的空间,从而可以将索引文件保留在内存中。但缺点是没有建立索引的Message也不能一次定位到其在数据文件的位置,从而需要做一次顺序扫描,但是这次顺序扫描的范围就很小了

Kafka集群会保存所有的消息,不管消息有没有被消费;我们可以设定消息的过期时间,只有过期的数据才会被自动清除以释放磁盘空间。比如我们设置消息过期时间为2天,那么这2天内的所有消息都会被保存到集群中,数据只有超过了两天才会被清除。

Kafka需要维持的元数据只有一个–消费消息在Partition中的offset值,Consumer每消费一个消息,offset就会加1。其实消息的状态完全是由Consumer控制的,Consumer可以跟踪和重设这个offset值,这样的话Consumer就可以读取任意位置的消息。

Producers

Producers直接发送消息到broker上的leader partition,不需要经过任何中介一系列的路由转发。为了实现这个特性,kafka集群中的每个broker都可以响应producer的请求,并返回topic的一些元信息,这些元信息包括哪些机器是存活的,topic的leader partition都在哪,现阶段哪些leader partition是可以直接被访问的。

Producer客户端自己控制着消息被推送到哪些partition。实现的方式可以是随机分配、实现一类随机负载均衡算法,或者指定一些分区算法。Kafka提供了接口供用户实现自定义的分区,用户可以为每个消息指定一个partitionKey,通过这个key来实现一些hash分区算法。比如,把userid作为partitionkey的话,相同userid的消息将会被推送到同一个分区。

以Batch的方式推送数据可以极大的提高处理效率,kafka Producer 可以将消息在内存中累计到一定数量后作为一个batch发送请求。Batch的数量大小可以通过Producer的参数控制,参数值可以设置为累计的消息的数量(如500条)、累计的时间间隔(如100ms)或者累计的数据大小(64KB)。通过增加batch的大小,可以减少网络请求和磁盘IO的次数,当然具体参数设置需要在效率和时效性方面做一个权衡。

Producers可以异步的并行的向kafka发送消息,但是通常producer在发送完消息之后会得到一个future响应,返回的是offset值或者发送过程中遇到的错误。这其中有个非常重要的参数“acks”,这个参数决定了producer要求leader partition 收到确认的副本个数,如果acks设置数量为0,表示producer不会等待broker的响应,所以,producer无法知道消息是否发送成功,这样有可能会导致数据丢失,但同时,acks值为0会得到最大的系统吞吐量。

若acks设置为1,表示producer会在leader partition收到消息时得到broker的一个确认,这样会有更好的可靠性,因为客户端会等待直到broker确认收到消息。若设置为-1,producer会在所有备份的partition收到消息时得到broker的确认,这个设置可以得到最高的可靠性保证。

Kafka 消息有一个定长的header和变长的字节数组组成。因为kafka消息支持字节数组,也就使得kafka可以支持任何用户自定义的序列号格式或者其它已有的格式如Apache Avro、protobuf等。Kafka没有限定单个消息的大小,但我们推荐消息大小不要超过1MB,通常一般消息大小都在1~10kB之前。

Consumers

Kafka提供了两套consumer api,分为high-level api和sample-api。Sample-api 是一个底层的API,它维持了一个和单一broker的连接,并且这个API是完全无状态的,每次请求都需要指定offset值,因此,这套API也是最灵活的。

在kafka中,当前读到消息的offset值是由consumer来维护的,因此,consumer可以自己决定如何读取kafka中的数据。比如,consumer可以通过重设offset值来重新消费已消费过的数据。不管有没有被消费,kafka会保存数据一段时间,这个时间周期是可配置的,只有到了过期时间,kafka才会删除这些数据。

High-level API封装了对集群中一系列broker的访问,可以透明的消费一个topic。它自己维持了已消费消息的状态,即每次消费的都是下一个消息。

High-level API还支持以组的形式消费topic,如果consumers有同一个组名,那么kafka就相当于一个队列消息服务,而各个consumer均衡的消费相应partition中的数据。若consumers有不同的组名,那么此时kafka就相当与一个发布/订阅服务,会把topic中的所有消息广播到每个consumer。

消息队列服务:存在多个消费者,这些消费者同属一个comsumer group,对于一个消息而言,只会被一个消费者消费


发布/订阅服务:有不同的comsumer group,发布到topic的消息会被所有订阅者消费


4.   Kafka的一些设计思想和基本概念

kafka作为一个集群运行在一个或多个服务器上

kafka集群存储的消息是以topic为类别记录的。

每个消息(也叫记录record,我习惯叫消息)是由一个key,一个value和时间戳构成。

Consumergroup:各个consumer可以组成一个组,每个消息只能被组中的一个consumer消费,如果一个消息可以被多个consumer消费的话,那么这些consumer必须在不同的组。

消息状态:在Kafka中,消息的状态被保存在consumer中,broker不会关心哪个消息被消费了被谁消费了,只记录一个offset值(指向partition中下一个要被消费的消息位置),这就意味着如果consumer处理不好的话,broker上的一个消息可能会被消费多次。

消息持久化:Kafka中会把消息持久化到本地文件系统中,并且保持极高的效率。

消息有效期:Kafka会长久保留其中的消息,以便consumer可以多次消费,当然其中很多细节是可配置的。

批量发送:Kafka支持以消息集合为单位进行批量发送,以提高push效率。

push-and-pull : Kafka中的Producer和consumer采用的是push-and-pull模式,即Producer只管向broker push消息,consumer只管从broker pull消息,两者对消息的生产和消费是异步的。

Kafka集群中broker之间的关系:不是主从关系,各个broker在集群中地位一样,我们可以随意的增加或删除任何一个broker节点。

负载均衡方面: Kafka提供了一个 metadata API来管理broker之间的负载(对Kafka0.8.x而言,对于0.7.x主要靠zookeeper来实现负载均衡)。

同步异步:Producer采用异步push方式,极大提高Kafka系统的吞吐率(可以通过参数控制是采用同步还是异步方式)。

分区机制partition:Kafka的broker端支持消息分区,Producer可以决定把消息发到哪个分区,在一个分区中消息的顺序就是Producer发送消息的顺序,一个主题中可以有多个分区,具体分区的数量是可配置的。

离线数据装载:Kafka由于对可拓展的数据持久化的支持,它也非常适合向Hadoop或者数据仓库中进行数据装载。

插件支持:现在不少活跃的社区已经开发出不少插件来拓展Kafka的功能,如用来配合Storm、Hadoop、flume相关的插件。

5.   Kafka核心特性

 压缩

我们上面已经知道了Kafka支持以集合(batch)为单位发送消息,在此基础上,Kafka还支持对消息集合进行压缩,Producer端可以通过GZIP或Snappy格式对消息集合进行压缩。Producer端进行压缩之后,在Consumer端需进行解压。压缩的好处就是减少传输的数据量,减轻对网络传输的压力,在对大数据处理上,瓶颈往往体现在网络上而不是CPU(压缩和解压会耗掉部分CPU资源)。

那么如何区分消息是压缩的还是未压缩的呢,Kafka在消息头部添加了一个描述压缩属性字节,这个字节的后两位表示消息的压缩采用的编码,如果后两位为0,则表示消息未被压缩。

消息可靠性

在消息系统中,保证消息在生产和消费过程中的可靠性是十分重要的,在实际消息传递过程中,可能会出现如下三中情况:

一个消息发送失败

一个消息被发送多次

最理想的情况:exactly-once ,一个消息发送成功且仅发送

有许多系统声称它们实现了exactly-once,但是它们其实忽略了生产者或消费者在生产和消费过程中有可能失败的情况。比如虽然一个Producer成功发送一个消息,但是消息在发送途中丢失,或者成功发送到broker,也被consumer成功取走,但是这个consumer在处理取过来的消息时失败了。

从Producer端看:Kafka是这么处理的,当一个消息被发送后,Producer会等待broker成功接收到消息的反馈(可通过参数控制等待时间),如果消息在途中丢失或是其中一个broker挂掉,Producer会重新发送(我们知道Kafka有备份机制,可以通过参数控制是否等待所有备份节点都收到消息)。

从Consumer端看:前面讲到过partition,broker端记录了partition中的一个offset值,这个值指向Consumer下一个即将消费message。当Consumer收到了消息,但却在处理过程中挂掉,此时Consumer可以通过这个offset值重新找到上一个消息再进行处理。Consumer还有权限控制这个offset值,对持久化到broker端的消息做任意处理。

备份机制

备份机制是Kafka0.8之后版本的特性,备份机制的出现大大提高了Kafka集群的可靠性、稳定性。有了备份机制后,Kafka允许集群中的节点挂掉后而不影响整个集群工作。一个备份数量为n的集群允许n-1个节点失败。在所有备份节点中,有一个节点作为lead节点,这个节点保存了其它备份节点列表,并维持各个备份间的状体同步。

6.   Kafka的应用场景

1、消息队列:应用程度使用Kafka作为传统的消息系统实现标准的队列和消息的发布—订阅,比起大多数的消息系统来说,Kafka有更好的吞吐量,内置的分区,冗余及容错性,这让Kafka成为了一个很好的大规模消息处理应用的解决方案。消息系统 一般吞吐量相对较低,但是需要更小的端到端延时,并尝尝依赖于Kafka提供的强大的持久性保障。在这个领域,Kafka足以媲美传统消息系统,如ActiveMR或RabbitMQ。据了解,目前平安的F项目有使用kafka的消息队列实现与外部的通信

2、监控:主机通过Kafka发送与系统和应用程序健康相关的指标,然后这些信息会被收集和处理从而创建监控仪表盘并发送警告

3、用户追踪:为了更好地理解用户行为,改善用户体验,将用户查看了哪个页面、点击了哪些内容等信息发送到每个数据中心的Kafka集群上,并通过Hadoop进行分析、生成日常报告。据了解,平安互联网产品在应用该场景

4、日志聚合:使用Kafka代替日志聚合(log aggregation)。日志聚合一般来说是从服务器上收集日志文件,然后放到一个集中的位置(文件服务器或HDFS)进行处理。然而Kafka忽略掉 文件的细节,将其更清晰地抽象成一个个日志或事件的消息流。这就让Kafka处理过程延迟更低,更容易支持多数据源和分布式数据处理。比起以日志为中心的 系统比如Scribe或者Flume来说,Kafka提供同样高效的性能和因为复制导致的更高的耐用性保证,以及更低的端到端延迟


 

zookeeper

1     zookeeper简介

Zookeeper是一个工具,可以实现集群中的分布式协调服务。所谓的分布式协调服务,就是在集群的节点中进行可靠的消息传递,来协调集群的工作。Zookeeper之所以能够实现分布式协调服务,靠的就是它能够保证分布式数据一致性。所谓的分布式数据一致性,指的就是可以在集群中保证数据传递的一致性。Zookeeper能够提供的分布式协调服务包括:数据发布订阅、负载均衡、命名服务、分布式协调/通知、集群管理、分布式锁、分布式队列等功能。

2     zookeeper特性

A.   最终一致性:client不论连接到哪个Server,展示给它都是同一个视图,即zookeeper集群各个节点的数据都是一样的,这是zookeeper最重要的性能。 

B.   可靠性:具有简单、健壮、良好的性能,如果消息被到一台服务器接受,那么它将被所有的服务器接受,简单来说就是更新操作会确保在所有服务器都成功。 

C.   原子性:读写会操作节点的所有数据,要么读或写了完整的数据,要么就失败,不会出现只读或写了部分数据

D.   实时性:Zookeeper保证客户端将在一个时间间隔范围内获得服务器的更新信息,或者服务器失效的信息。但由于网络延时等原因,Zookeeper不能保证两个客户端能同时得到刚更新的数据,如果需要最新数据,应该在读数据之前调用sync()接口。 

E.   等待无关(wait-free):慢的或者失效的client不得干预快速的client的请求,使得每个client都能有效的等待。 

F.   顺序性:包括全局有序和偏序两种:全局有序是指如果在一台服务器上消息a在消息

b前发布,则在所有Server上消息a都将在消息b前被发布;偏序是指如果一个消息b在消息a后被同一个发送者发布,a必将排在b前面。

3     Zookeeper的架构及原理

3.1     Zookeeper的基本概念

Zookeeper包括以下几个角色:

Leader:领导者负责进行投票的发起和决议,更新系统状态

Follower:跟随者用于接收客户请求并返回结果(写操作需发给leader进行广播),在选主过程中参与投票

Observer:观察者可以接收客户端的请求,将写请求发给leader,但observer不参与投票过程,只同步leader的状态。

Client:请求发起方

Znode:ZooKeeper目录树中每一个节点对应一个Znode。每个Znode维护着一个属性结构,它包含着版本号(dataVersion),时间戳(ctime,mtime)等状态信息。ZooKeeper正是使用节点的这些特性来实现它的某些特定功能。每当Znode的数据改变时,他相应的版本号将会增加。每当客户端检索数据时,它将同时检索数据的版本号。并且如果一个客户端执行了某个节点的更新或删除操作,他也必须提供要被操作的数据版本号。如果所提供的数据版本号与实际不匹配,那么这个操作将会失败。

  Znode是客户端访问ZooKeeper的主要实体,它包含以下几个特征:

  (1)Watches

  客户端可以在节点上设置watch(我们称之为监视器)。当节点状态发生改变时(数据的增、删、改)将会触发watch所对应的操作。当watch被触发时,ZooKeeper将会向客户端发送且仅发送一条通知,因为watch只能被触发一次。

  (2)数据访问

  ZooKeeper中的每个节点存储的数据要被原子性的操作。也就是说读操作将获取与节点相关的所有数据,写操作也将替换掉节点的所有数据。另外,每一个节点都拥有自己的ACL(访问控制列表),这个列表规定了用户的权限,即限定了特定用户对目标节点可以执行的操作。

  (3)节点类型

ZooKeeper中的节点有两种,分别为临时节点和永久节点。节点的类型在创建时即被确定,并且不能改变。
  ZooKeeper的临时节点:该节点的生命周期依赖于创建它们的会话。一旦会话结束,临时节点将被自动删除,当然可以也可以手动删除。另外,需要注意是, ZooKeeper的临时节点不允许拥有子节点。 
  ZooKeeper的永久节点:该节点的生命周期不依赖于会话,并且只有在客户端显示执行删除操作的时候,他们才能被删除。

  (4)顺序节点(唯一性的保证)

   当创建Znode的时候,用户可以请求在ZooKeeper的路径结尾添加一个递增的计数。这个计数对于此节点的父节点来说是唯一的,它的格式为"%10d"(10位数字,没有数值的数位用0补充,例如"0000000001")。当计数值大于232-1时,计数器将溢出。

org.apache.zookeeper.CreateMode中定义了四种节点类型,分别对应:
  PERSISTENT:永久节点
  EPHEMERAL:临时节点
  PERSISTENT_SEQUENTIAL:永久节点、序列化
  EPHEMERAL_SEQUENTIAL:临时节点、序列化

3.2     Zookeeper的数据模型

Zookeeper会维护一个具有层次关系的数据结构,它类似于一个标准的文件系统,如下图所示

这种数据结构有如下特点:

每个子目录项如 NameService 都被称作为 znode,这个 znode 是被它所在的路径唯一标识,如 Server1 这个 znode 的标识为 /NameService/Server1

znode 可以有子节点目录,并且每个 znode 可以存储数据,注意 EPHEMERAL 类型的目录节点不能有子节点目录

znode 是有版本的,每个 znode 中存储的数据可以有多个版本,也就是一个访问路径中可以存储多份数据

znode 可以是临时节点,一旦创建这个 znode 的客户端与服务器失去联系,这个 znode 也将自动删除,Zookeeper 的客户端和服务器通信采用长连接方式,每个客户端和服务器通过心跳来保持连接,这个连接状态称为 session,如果 znode 是临时节点,这个 session 失效,znode 也就删除了

znode 的目录名可以自动编号,如 App1 已经存在,再创建的话,将会自动命名为 App2

znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个是 Zookeeper 的核心特性,Zookeeper 的很多功能都是基于这个特性实现的

3.3     Zookeeper的数据同步

不管访问zookeeper的那个server,数据都是一样的,所有各server间肯定存在数据同步,同步过程图如下:

查询请求只涉及1、6两个步骤,client端连接到其中一个server,server直接查询本地,把结果返回给client端

更新修改操作请求则需要经过以下所有步骤,follower收到client端的写请求,会把请求转发给leader,由leader广播给所有follower,follower数据写成功后,给leader以确认,leader收到半数以上的follower确认后,返回commit给接收请求的follower,follower再返回结果给client,写请求完成,

3.4     Zookeeper的leader选举

 Zookeeper的核心是原子广播,这个机制保证了各个server之间的同步。实现这个机制的协议叫做Zab协议。Zab协议有两种模式,它们分别是恢复模式和广播模式。当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数server的完成了和leader的状态同步以后,恢复模式就结束了。状态同步保证了leader和server具有相同的系统状态。

一旦leader已经和多数的follower进行了状态同步后,他就可以开始广播消息了,即进入广播状态。这时候当一个server加入zookeeper服务中,它会在恢复模式下启动,发现leader,并和leader进行状态同步。待到同步结束,它也参与消息广播。Zookeeper服务一直维持在Broadcast状态,直到leader崩溃了或者leader失去了大部分的followers支持。

Broadcast模式极其类似于分布式事务中的2pc(two-phrase commit 两阶段提交):即leader提起一个决议,由followers进行投票,leader对投票结果进行计算决定是否通过该决议,如果通过执行该决议(事务),否则什么也不做。

广播模式需要保证proposal被按顺序处理,因此zk采用了递增的事务id号(zxid)来保证。所有的提议(proposal)都在被提出的时候加上了zxid。实现中zxid是一个64为的数字,它高32位是epoch用来标识leader关系是否改变,每次一个leader被选出来,它都会有一个新的epoch。低32位是个递增计数。

当leader崩溃或者leader失去大多数的follower,这时候zk进入恢复模式,恢复模式需要重新选举出一个新的leader,让所有的server都恢复到一个正确的状态。

首先看一下选举的过程,zk的实现中用了基于paxos算法(主要是fastpaxos)的实现。具体如下:

1.每个Server启动以后都询问其它的Server它要投票给谁。

2.对于其他server的询问,server每次根据自己的状态都回复自己推荐的leader的id和上一次处理事务的zxid(系统启动时每个server都会推荐自己)

3.收到所有Server回复以后,就计算出zxid最大的哪个Server,并将这个Server相关信息设置成下一次要投票的Server。

4.计算这过程中获得票数最多的的sever为获胜者,如果获胜者的票数超过半数,则改server被选为leader。否则,继续这个过程,直到leader被选举出来。

此外恢复模式下,如果是重新刚从崩溃状态恢复的或者刚启动的的server还会从磁盘快照中恢复数据和会话信息。(zk会记录事务日志并定期进行快照,方便在恢复时进行状态恢复)

选完leader以后,zk就进入状态同步过程。

1.leader就会开始等待server连接

2.Follower连接leader,将最大的zxid发送给leader

3.Leader根据follower的zxid确定同步点

4.完成同步后通知follower 已经成为uptodate状态

5.Follower收到uptodate消息后,又可以重新接受client的请求进行服务了。

4     zookeeper应用场景

统一命名服务

       分布式环境下,经常需要对应用/服务进行统一命名,便于识别不同服务。类似于域名与ip之间对应关系,域名容易记住。通过名称来获取资源或服务的地址,提供者等信息按照层次结构组织服务/应用名称可将服务名称以及地址信息写到Zookeeper上,客户端通过Zookeeper获取可用服务列表类。例子:平安的ESG平台,服务方发布接口,会事先在zookeeper上创建一个服务编码的znode,然后服务方每一个服务器启动的时候都会把要发布的接口和ip端口信息作为子znode写入服务编码的znode下,供消费方订阅。

配置管理

       分布式环境下,配置文件管理和同步是一个常见问题。一个集群中,所有节点的配置信息是一致的,比如Hadoop。对配置文件修改后,希望能够快速同步到各个节点上配置管理可交由Zookeeper实现。可将配置信息写入Zookeeper的一个znode上。各个节点监听这个znode。一旦znode中的数据被修改,zookeeper将通知各个节点。

集群管理

       分布式环境中,实时掌握每个节点的状态是必要的。可根据节点实时状态作出一些调整。Zookeeper可将节点信息写入Zookeeper的一个znode上。监听这个znode可获取它的实时状态变化,如kafka的broker状态管理。

分布式通知/协调

分布式环境中,经常存在一个服务需要知道它所管理的子服务的状态。例如,NameNode须知道各DataNode的状态,JobTracker须知道各TaskTracker的状态。心跳检测机制和信息推送也是可通过Zookeeper实现。例子:ESG的消费方订阅:消费者事先在zookeeper上创建一个消费编码的znode,并在管理平台申请调用服务方的权限,管理平台对消费编码的znode设置了监听,当消费者服务器启动时,会把自己的ip信息作为子znode写入消费编码的znode下,会触发管理平台的监听,管理平台会把消费方所订阅的服务方ip、端口、接口等信息推送给消费方。

分布式锁

       Zookeeper是强一致的。多个客户端同时在Zookeeper上创建相同znode,只有一个创建成功。Zookeeper实现锁的独占性。多个客户端同时在Zookeeper上创建相同znode ,创建成功的那个客户端得到锁,其他客户端等待。Zookeeper 控制锁的时序。各个客户端在某个znode下创建临时znode (类型为CreateMode. EPHEMERAL _SEQUENTIAL),这样,该znode可掌握全局访问时序。例如多个客户端要修改一个文件的时候,可以采用zookeeper的分布式锁控制

分布式队列

       两种队列。当一个队列的成员都聚齐时,这个队列才可用,否则一直等待所有成员到达,这种是同步队列。队列按照 FIFO 方式进行入队和出队操作,例如实现生产者和消费者模型。(可通过分布式锁实现)
    同步队列。一个job由多个task组成,只有所有任务完成后,job才运行完成。可为job创建一个/job目录,然后在该目录下,为每个完成的task创建一个临时znode,一旦临时节点数目达到task总数,则job运行完成。


猜你喜欢

转载自blog.51cto.com/9615915/2134204