1、Kafka学习分享|概念介绍-V1.0

Kafka学习分享|概念介绍

“截止今日Kafka学习分享的1.0版正式出炉,继续迭代精进”

.1       什么是Kafka

Apache Kafka是一个开源的流处理平台,由 Apache Software Foundation使用Scala and Java编写发展而来。Kafka™用于构建实时数据管道和流媒体应用。 它具有水平可扩展性,容错性,快速性,并在数千家公司生产中运行。

它的主要功能:数据流的发布和订阅、数据流的处理、数据流的存储。像一个消息系统一样发布和订阅数据流,有效且实时地处理数据流,在一个分布式备份的集群中安全地处理存储数据流。

 

 

.2       Kafka详细介绍

.2.1             流处理平台的三个关键功能

l  它允许发布和订阅可记录的流。在这个方面,它类似于一个消息队列或者一个企业消息系统。

l  它允许以一种容错的方式存储可记录的流。

l  它允许当可记录的流发生的时候来处理它们。

.2.2             Kafka的好处是什么?

它被用于两类广泛的应用程序:

l  构建能够可靠地在系统和应用程序之间获取数据的实时流数据管道。

l  构建对流数据转换和响应的实时流应用程序。

.2.3             Kafka是如何运行的?

为了理解Kafka是怎样做这些事情的,让我们自下而上深入探索Kafka的能力。

 

一些概念

l  Kafka作为一个集群在一个或多个服务器上运行;

l  Kafka集群存储可记录的流的类别,称为topics;

l  每条记录包含一个key,一个value和一个timestamp;

Kafka有四个核心的APIs

l  Producer API 允许一个应用程序将一条可记录的流发布到一个或多个Kafka topics.

l  Consumer API 允许一个应用程序订阅一个或多个Kafka topics,并且处理生成给它们的可记录流。

l  Streams API允许一个应用程序扮演一个流处理器,消费来自一个或多个topics的输入流并且生产输出流给一个或多个topics,有效地将输入流转换成输出流。

l  Connector API允许构建和运行可复用的,将Kafka topics和现有应用程序或数据系统连接起来的生产者或消费者。如,一个相关数据的连机器可能捕获一张表的每一个变化。

 

 

在Kafka中,客户端和服务端之间的通信是由一个简单的、高性能的、跨语言的TCP协议完成的。这种协议是版本控制的,并且与旧版本保持后向兼容。我们提供了一个Java客户端给Kafka,但是客户端支持多种语言。

Topics and Logs

一个Topic 就是记录被发布的一个类别或者提要名称,kafka用topic来标识存储的一系列数据。每个topic可以有多个数据消费者和生产者,换句话说,一个topic可以有0个、一个、或多个订阅了它的数据的消费者。

对于每一个topic,Kafka集群保持一个分区的log,如下图:

 

 

每一个分区都是一个有序的,不变的可记录的序列,这些序列不断地添加到一个结构化的提交日志中。分区的记录各自都被分配一个连续的ID号,被称为偏移量,偏移量在分区中唯一标识每条记录。

Kafka集群保留所有发布的记录无论他们是否被消费,使用一个可配置的保留期。例如:如果保留策略设置为两天,然后在一个记录被发布后的两天之内,它可以用于消费,之后它将被丢弃以释放空间。Kafka可以存储很长时间的数据且性能不受数据量大小的影响。“类似于MQ里面的queue,但是kafka的数据是持久化在磁盘上,在超时时间内,是可以反复按顺序消费的。”

 

 

事实上,在每一个消费者基础上保留的唯一的元数据是日志中消费者的偏移量或者位置。这个偏移量是由消费者控制的:通常,消费者会线性地提高它的偏移量来读取记录,但是,事实上,由于位置是由消费者控制的,消费者可以按照它想要的任何顺序来消费记录。例如,一个消费者可以重新设置为旧的偏移量,以重新处理过去的数据,或者跳到最近的记录,并从“now”开始消费。“偏移量是记在ZooKeeper上,以消费者组为单位,路径为/consumers/groupId/offsets/topicName/Partition;”

这种组合的特性意味着Kafka消费者是非常便宜的,他们的来去不会对集群或者其他的消费者产生一些影响。例如:你能够使用我们的命令行工具来“tail”任何topic的内容,而不需要改变任何被现有消费者消费的内容。

日志中的分区有几个目的。首先,他们允许日志扩展到超出一个适合单个服务器的大小。每个独立的分区必须适合承载它的服务器,但是一个topic应该有许多的分区,因此它能够处理任意数量的数据。其次,他们作为一个并行的单元,在这方面做的更多。

分布式

日志的分区分布在Kafka集群中不同的服务器上,每个服务器处理数据并请求共享分区。每个分区在一个可配置数量的服务器上进行复用,用于容错。

每个分区有一个作为“leader”的服务器和0个或多个作为“followers”的服务器。主服务器处理该分区的所有读写请求,而从服务器被动地复制主服务器。如果主服务器出现故障,那么其他从服务器中的一个将自动成为新的主服务器。每个服务器充当某些分区的领导者,并为其他一些分区提供一个追随者,因此在集群中负载均衡。

生产者

生产者发布它们选择的数据给每个topics。生产者负责在topic中选择哪条记录分配到哪个分区上。这可以以循环的方式简单实现负载均衡或者它可以根据一些语义分区函数(据说是根据记录上的一些关键字)来完成。“具体的将数据发送到哪个分区下,由消费者决定,需要根据业务场景;没有特殊要求的,可以随机发送,尽可能的分摊到每个分区下,这样对消费者那边的多线程处理效率有比较大的提升;如果告警,最少需要将同一条告警的活跃和清除告警发送到同一个分区上。”

消费者

消费者给自己贴上一个消费者团体的标签,每个被发布到一个topic的记录都被交付到每个订阅消费者团体中的一个消费者实例。消费者实例可以在单独的进程中,也可以在单独的机器上。“每个消费者都归属一个组,同一个组内的消费者,只能有一个消费者同时消费一个topic下某个分区下面的数据,换句话说,kafka的数据消费,是以topic的分区+消费者组为单位进行消费的。这样的话,不同消费者组内的消费者可以同时消费同一个topic下同一个分区的数据。”

如果所有的消费者实例有相同的消费者团体,然后这些记录将在这些消费者实例中有效地实现负载均衡。

如果所有的消费者实例有不同的消费者团体,然后每个记录将被广播到所有的消费者进程中。

 

 

一个两个服务器的Kafka集群承载4个分区(P0-P3),其中有两个消费者团体。消费者团体A有两个消费者实例,并且消费者团体B有四个消费者实例。

然而,更常见的是,我们发现有少量消费者群体的topics,每个消费者都是“logical subscriber”。每个团体有许多用于可伸缩性和容错的消费者实例组成。这只不过是,订阅-发布语法,订阅用户是一组消费者而不是单个的进程。

在Kafka中实现消费的方式是将日志中的分区划分成多个消费者实例,因此,每个实例都是在任何时间点上“公平分享”分区的唯一的消费者。

团体中维护资格的进程由Kafka协议自由控制的。如果一个新的实例加入这个团体,他们将从其他团体成员中接管一些分区;如果一个实例死了,它的分区将被分配给其他剩余的实例。

Kafka只在一个分区内提供记录的一个完整顺序,而不是在一个topic内的不同分区之间。对于大多数应用程序来说,每个分区排序和按主键分区数据的能力都是足够的。但是,如果你需要所有的记录的一个完整的顺序,这可以通过一个只有一个分区的topic实现,尽管这个将意味着每个消费者团体只有一个消费进程。

保障

一个高级别的Kafka将提供一下保障:

l  消息从一个生产者发送给一个特定的主题分区时将会附加上他们被发送的顺序。也就是说,如果一条记录M1和M2是有同一个生产者发送出去的,并且M1是先发送出去的,则M1的偏移量将会比M2的低,并且出现在log里更早。

l  一个消费者实例将按他们在log中存储的顺序来理解这些记录。

l  对于一个具有备份元素N的topic,我们将容忍N-1服务器故障,而不会丢失任何记录到日志中的记录。

More details on these guarantees are given in the design section of the documentation.

.2.4             Kafka作为一个消息系统

Kafka消息系统与传统企业消息系统的对比。

传统消息有两种模型:队列和发布-订阅( queuing and publish-subscribe.)。

在对列中,一池的消费者将从一个服务上选读,并且每条记录都会被其中的一个消费者读到;在发布-订阅中,记录将被广播到所有的消费者。这两种模型都有其优势和劣势。序列的优势是它允许将数据处理进程分配给多个消费者实例,这样可以让你扩展你的进程。不幸的是,序列不是多用户的,一旦一个进程读取数据,数据就会消失。发布-订阅,允许你广播数据到多个进程,但是由于每条消失数据去了每个订阅者,因此没有办法扩展进程。

Kafka中消费者团体的概念概括了这两个概念。与队列一样,消费者组允许您通过一系列进程(消费者组的成员)来划分处理。与发布订阅一样,Kafka允许您将消息广播到多个消费者组。

Kafka模型的优点是,每个主题都具有这两个属性 - 它可以扩展处理,也是多用户 - 不需要选择一个或另一个。

Kafka也比传统的消息系统有更强的顺序保证。

一个传统的队列在服务器上保留的消息记录是按序的,如果多个用户从该服务器消费消息,然后该服务器将按照消息存储的顺序分发消息。但是,尽管服务按序分发消息,这些消息是异步分发给消费者的,因此它们可能到达不同消息者的顺序不同。这实际意味着消息的顺序在并行消费的过程中丢失了。消息系统通常通过提供一个“独有消费者”的概念来解决这个问题,独有消费者允许一个进程从一个序列上消费,当然,这意味着进程处理过程中无并行性。

Kafka在这点上做得更好。通过在主题中各个分区有一个的并行概念,Kafka能够同时提供顺序保证和在一群消费者进行中实现负载均衡。这通过将一个TOPIC中的各个分区分配给一个消费者群体中的各个消费者来实现的,因此每一个分区只能被消费者群体的一个消费者消费掉。

通过这样做我们确保这个消费者是这个分区的唯一的读者并且消费按顺序消费数据。由于这儿有许多分区,所以许多消费者实例之间仍然能够实现负载均衡。注意:但是在一个消费者群体里消费者实例的个数不能超过分区数。

 

.1.1             Kafka流处理

仅仅读、写、存储数据流是不够的,真正的目的是能够实现流数据的实时处理。

在Kafka中,一个流处理器是任何从输入主题中获取连续数据流的东西,在这个输入上执行一些进程,并且生产连续的数据流给输出主题。

例如,一个零售的应用程序可能会接收销售和发货的输入流,并且输出一连串的重新订单和价格调整,计算这些数据。

它让直接使用生产者和消费者的APIs进行简单的处理成为可能。但是,对于更多复杂转换,Kafka提供了一个完全集成流API。这允许建立重大的处理的应用程序,它从流中计算聚合或者加入流。

这个工具帮助解决了这类应用程序所面临的难题:处理无序数据,处理输入代码更改,执行有状态计算等等。

流API构建于Kafka提供的核心基础之上:它使用生产者和消费者的API进行输入,使用Kafka实现有状态的存储,并在流处理器实例中使用相同的群组机制来进行容错。

 

.1.2             把分块放在一起

消息、存储和流处理的结合也许看起来不同寻常,但是这些对于Kafka作为一个流处理平台是必不可少的。

一个文件分发系统(像HDFS)允许存储用于批处理的静态文件。实际上一个系统像这样允许从过去存储和处理历史的数据。

一个传统企业消息系统允许处理未来的消息,这个将在你订阅之后实现。按照这种方式建立的应用程序随着未来数据的到来而处理它。

Kafka 将这些能力结合在一起,并且这个结合对于Kafka作为一个流处理应用程序和流数据管道是至关重要的。

通过结合存储和低时延订阅,流处理应用程序能够用同样的方式对待过去的和将来的数据。

那是一个单一的应用程序,能够处理过去和未来的数据,而不是结束,当它到达最后的记录时它可以继续处理未来的数据。这是一个通用的流处理概念,它包含批处理和消息驱动的应用程序。

同样的流数据管道订阅实时事件的组合可以使用卡夫卡非常低延迟管道;但是可靠地存储数据的能力使它可以使用它必须保证关键数据的数据或与离线系统的集成,数据加载只定期或长时间进行维护。流处理工具使在到达时转换数据成为可能。

For more information on the guarantees, apis, and capabilities Kafka provides see the rest of the documentation.

 

PS:本文完全参考“https://kafka.apache.org/”,即kafka官方主页。

posted on 2017-06-17 20:02  Alice-feng  阅读(1700)  评论(0编辑  收藏  举报

导航