页面树结构

2017-11-09 ApacheCN 开源组织,第二期邀请成员活动,一起走的更远 : http://www.apachecn.org/member/209.html


MachineLearning 优酷地址 : http://i.youku.com/apachecn

转至元数据结尾
转至元数据起始

Apache Kafka是一个分布式流处理平台。这到底意味着什么?

我们知道流处理平台有以下三种特性:

  1. 可以让你发布和订阅流式的记录。这一方面和消息队列或者企业消息系统类似。

  2. 可以储存流式的记录,并且有较好的容错。

  3. 可以在流式记录产生的时候就进行处理。

Kafka适合什么样的场景?

它可以用于两大类别的应用:

  1. 构造实时流数据管道,它可以在系统或应用之间可靠的获取数据。 (相当于message queue)

  2. 构建实时流式应用程序,对这些流数据进行转换或者影响。      (就是流处理,通过kafka stream topic和topic之间内部进行变化)

为了理解Kafka是如何做到上面所说的功能,我们将从下面开始深入探索Kafka的特性。

首先是一些概念

  • Kafka作为一个集群,运行在一台或者多台服务器上。

  • Kafka 通过 topic 这个词对存储的流数据进行分类。

  • 每条记录中包含一个key,一个value和一个timestamp(时间戳)。

Kafka有四个核心的API

  • Producer API 允许一个应用程序发布一串流式的数据到一个或者多个Kafka topic。

  • Consumer API 允许一个应用程序订阅一个或多个 topic ,并且对发布给他们的流式数据进行处理。

  • Stream API 允许一个应用程序作为一个流处理器,消费从一个或者多个topic产生的输入流,然后生产一个输出流到一个或多个topic中去,在输入输出流中进行有效的转换。

  • Connector API 允许构建和运行可重用的生产者或者消费者,将Kafka topics连接到已存在的应用程序或者数据系统.比如,连接到一个关系型数据库,捕捉每一个对表的改变。

kafka-apis

在Kafka中,客户端和服务器使用一个简单的,高性能的,支持多语言的  TCP协议 进行通信.此协议版本化并且向前兼容老版本。我们为Kafka提供了Java客户端,还支持许多其他语言的客户端。

Topics和日志(Topics and Logs

我们首先深入Kafka的核心概念,提供一串流式的记录--topic。

Topic是一个类别或者订阅名称,用来接受发布的记录。Topics 在Kafka中总是多订阅者模式,一个topic可以有一个或者多个消费者来订阅写入的数据。

对于每一个topic, Kafka集群都会维持一个分区日志,像下面这样:

partitioned log

每个分区都是有序的,不断追加顺序不可变的记录----结构化的提交日志。分区中的每一个记录都会分配一个表示顺序的id号,我们称之为offset,offset用来唯一的标识分区中每一条记录。

Kafka 集群保留所有发布的记录,无论他们是否已被消费--并通过使用一个可配置的保留期限参数来控制。举个例子,如果保留策略设置为2天,一条记录发布后两天内,可以随时被消费,两天过后这条记录会被抛弃并释放磁盘空间。Kafka的性能和数据大小无关,所以长时间存储数据没有什么问题.

log_consumer

事实上,唯一保存在每一个消费者中的元数据是offset(偏移量)或者消费在log中的位置.偏移量被消费者所控制:通常消费者会在读取记录后以线性的方式增加偏移量,但是事实上,由于这个位置由消费者控制,所以消费者可以通过任何顺序消费记录.例如,一个消费者可以重置回一个旧的偏移量,重新处理过去的数据或者跳过最近的记录,并从"现在"开始消费。

这些细节综合起来说明Kafka 消费者是非常便宜的--消费者增加和减少,对集群或者其他消费者没有多大的影响.例如,你可以使用命令行工具,对一些topic内容执行 tail操作,并不会影响已经存在的消费者消费数据。

日志中的 partition(分区)有下面几个目的.第一,当日志大小超过了单台服务器的限制,允许日志进行扩展。每个单独的分区都必须受限于主机的文件限止,但一个主题可能有多个分区,因此可以处理无限数量的数据。第二,可以作为并行的单元集合,关于这一点更多细节如下。

分布式 (Distribution)

日志的分区partition (分布)在Kafka集群不同的服务器上。每一台服务器处理数据和请求的时候,共享这些分区。每一个分区都会配置服务器备份数量,保证容错.

每个分区都有一台 server 作为 “leader”,零台或者多台server作为 follwers 。leader server 处理所有对 partition (分区)的读写请求,而follwers只需要被动的同步leader上的数据。当leader宕机了,followers 其中一台server会自动成为新的 leader。每台 server 都会成为某些分区的 leader 和某些分区的 follower,因此集群的负载是平衡的。

生产者(Producers)

生产者可以发布数据到所选择的topic(主题)中。生产者负责将哪一条记录分配到topic的哪一个 partition(分区)中。可以使用循环topic partitions(分区) 的方式实现简单地负载均衡,或者可以根据某些语义分区函数(例如:基于记录中的key)来完成。下面会介绍更多分区的使用。

消费者(Consumers)

消费者使用一个消费者组名来进行标识,发布到topic中的每条记录被分配到订阅的消费组其中一个消费者实例.消费者实例可以分布在多个进程中或者多个机器。

如果所有的消费者实例在同样的消费组中,消息记录会有效的负载平衡到每一个消费者实例.

如果所有的消费者实例在不同的消费组中,每条消息记录都会广播到所有的消费者进程。

consumer-groups

一个有两台 server 的 Kafka 集群,一共有四个分区(p0-p3)和两个消费者组.消费组A有两个消费者,消费组B有四个消费者。
通常情况下,每个 topic 都会有一些消费组,一个消费组对应一个"逻辑订阅者"。每个消费组由许多消费者实例组成,便于可扩展性和容错性。这就是发布和订阅的概念,只是订阅者是一组消费者而不是单个进程。
在Kafka中实现消费的方式是将日志中的分区划分到每一个消费者实例上,以便每个实例在任何时间点都可以是分区唯一的消费者。维护消费组中的消费关系由kafka协议动态处理。如果新的实例加入组,他们将从组中的其他成员接管一些 partition 分区;如果一个实例消失,拥有的分区将被分发到剩余的实例.
Kafka 只保证分区内的记录是有序的。而不是主题中不同分区的顺序。每个 partition 分区按照key值排序足以满足大多数应用程序的需求.但是,如果你需要总共订单在记录之上,则可以使用仅一个分区的主题来实现,这意味着每个消费者组只有一个消费者进程.

保证(Guarantees)

high-level Kafka给予以下保证

  • 生产者发送到特定topic partition 的消息将按照发送的顺序进行追加。也就是说,如果记录M1和记录M2由相同的生产者发送,并且先发送M1记录,那么M1将具有比M2更小的偏移,并且在日志中较早出现。
  • 一个消费者实例按照记录存储在日志中的顺序查看记录。
  • 对于具有复制因子N的主题,我们将容忍最多N-1个服务器故障,并且不会丢失任何提交到日志的记录.

Kafka作为消息系统(Kafka as a Messaging System)

Kafka流的概念与传统的企业消息系统相比如何?

传统的消息系统有两个模块:队列(queuing)发布-订阅(publish-subscribe)。在队列中,可能有一个消费者的池子从server读取数据,每条记录被池子中一个消费者消费;在发布订阅中,记录被广播到所有的消费者。两者都有优点和缺点。队列的优点在于它允许你将处理数据的过程分给多个消费者实例,你可以扩展你的处理。不幸的是,队列不是多订阅者者的---一旦一个进程读取了数据,数据就会丢弃。发布订阅系统允许你广播数据到多个进程,但是无法扩展处理,因为每条消息都会发送给所有的订阅者。  消费组在Kafka有两层概念。在队列中,消费组允许你将处理过程分发给一系列进程(消费组中的成员)。发布订阅中,Kafka允许你将消息广播给多个消费组。

Kafka设计的优势在于每个topic都有以下特性:可以缩放处理并且可以多订阅者---不需要只选择其中一个。

Kafka相比于传统消息队列还具有更严格的顺序保证。

传统队列在服务器上保存顺序的记录,如果多个消费者消费队列中的数据,服务器将按照存储顺序输出记录。然而,虽然服务器按顺序输出记录,但是记录被异步传递给消费者,所以记录可能会无序的到达不同的消费者。这意味着在并行消耗的情况下,记录的顺序是丢失的。消息系统通常通过使用“唯一消费者”的概念,也就只让一个进程从队列中消费,但这就意味不能够并行的处理数据。

Kafka 设计的更好。topic中的partition是一个并行的概念,Kafka能够在为一个消费者池子提供顺序保证和负载平衡。这是通过将主题中的分区分配给消费者组中的消费者来实现的,以便每个分区由消费组其中一个消费者消耗。通过这样做,我们确保消费者是该分区的唯一读者,并按顺序消费数据。由于有许多分区,保证了对多个消费者实例负载均衡。但请注意,消费者组中的消费者实例不能超过分区的数量。

Kafka作为存储系统(Kafka as a Storage System)

许多消息队列可以发布消息,除了消费消息之外还可以充当中间数据的存储系统。那么Kafka作为一个优秀的存储系统有什么不同的呢?

数据写入Kafka后被写入到磁盘,并且为了容错进行备份。Kafka允许生产者等待确认,直到完全备份才认为完成写入,并且即使写入失败也会保证继续写入.

Kafka使用磁盘结构能够很好的扩展。50kb和50TB的持久数据在server上表现一致。
由于可以存储大量数据,并且客户端可以控制它读取数据的位置,您可以认为Kafka是一种专门用于高性能,低延迟的提交日志存储,备份和传播的分布式文件系统。

Kafka用来做流处理 (Kafka for Stream Processing)

Kafka 流处理不仅仅是用来读写和存储流式数据,最终的目的是为了能够进行实时的流处理。

在Kafka中,流处理器一个不断从输入的topic获取流数据,处理数据后,再不断生产流数据到输出的topic中去。

例如,零售应用程序可能会收到销售和出货的输入流,再输出一串流式数据,这些数据是经过价格调整后计算的。

简单的数据处理可以直接用生产者和消费者的API.但是对于复杂的数据变换,Kafka提供了Streams API。Stream API 允许应用做一些复杂的处理,比如将流数据聚合或者join。

这个功能有助于解决下面这种应用程序所面临的问题:处理无序数据,当消费端代码变更后重新处理输入,执行有状态计算等。

Streams API建立在Kafka核心属性之上:它使用Producer和Consumer API作为输入,使用Kafka进行有状态的存储,并在流处理器实例之间使用相同的消费组机制来实现容错。

批处理(Putting the Pieces Together)

消息,存储和流处理综合起来看上去不一般,但是这是Kafka作为流平台所必须的.

像HDFS这样的分布式文件系统允许存储用于批处理的静态文件。 一个系统如果可以存储和处理历史数据是很不错的。

传统的企业消息系统允许你处理订阅之后到达的数据。 以这种方式构建的应用程序,并用来处理即将到达的数据。

Kafka结合了上面所说的两种特性,这两个特性 对于Kafka 可以作为一个流应用程序平台或者流数据管道是至关重要的。

通过组合存储和低延迟订阅,流式应用程序可以以相同的方式处理过去和未来的数据。 这是一个单一的应用程序可以处理历史记录的数据,而不是在到达最后一条记录时结束,可以持续处理不断到达的数据。 这是一个广泛的流处理概念,其中包含批处理以及消息驱动应用程序。

同样,对于流数据管道,能够订阅实时事件使得Kafk可以作为具有非常低延迟的管道; 但是Kafka还具有可靠存储数据的特性,可以用来存储重要的支付数据,或者和离线系统交互,系统可间歇性的加载数据,或者停机维护后再次加载数据。 流处理功能使得数据可以在到达时转换数据。

  • 无标签