大数据基础系列之kafka知识点和优点

 浪尖 浪尖聊大数据

一,流式平台介绍

1,一般来说一个通用的流平台必须具备以下三个重要的能力:

1),能够允许你订阅和发布流式消息。在这方面,它类似于消息队列或企业消息系统。

2),它允许您以容错方式存储流式消息。

3),他可以允许你实时处理流式消息。

2Kafka常被用于两大类应用程序:

1),构建可在系统或应用程序之间可靠获取数据的实时流数据流水线

2),构建对数据流进行变换处理的实时流应用程序

3,首先介绍一些基本概念:

1),kafka是以集群的方式运行,可以有一个或者多个Broker server

2),kafka集群以topic为类别的方式存储消息。

3),每一条消息记录由一个key,一个value,和一个时间戳组成。

4Kafka提供了四种核心的API

1),producer API:允许应用程序往kafkatopic写数据流

2),consumer API:允许应用程序订阅一个或者多个topic,然后从中消费数据。

3),Streams API:允许应用程序充当一个流处理器,消费topic数据,转换处理后,再写回kafka

4),Connector APIConnector  API允许构建和运行将Kafka主题与现有应用程序或数据系统相连接的可重复使用的生产者或消费者。例如,关系数据库的连接器可能会捕获表的每个更改。

kafka集群中客户端和服务端的交流,使用的是一个简单,高容错,语言无关的TCP 协议。可以实现版本之间向下兼容。提供了多语言版本的client

二,topicslogs

我们先来看看kafka提供的一个流数据存储的核心抽象-topic

Topic代表发布消息的一个类别。Topic可以有很多订阅者,来订阅写到topic的数据。

针对每个topickafka集群都会维护多个已分区的log,如下:

大数据基础系列之kafka知识点和优点_Java

每个分区是一个有序的,不可变的记录序列,不断附加到结构化的提交日志中。每个分区中的记录都被分配一个顺序的id号,称为唯一标识分区内每个记录的偏移量。

Kafka集群保留所有的消息,无论这些消息是否已经被消费,然后我们可以通过配置一个存储时间,来决定消息什么时候被删除。例如,保存消息的策略是保存两天,从消息被发布的两天内,都可以随时被消费,但是超过两天消息就会从磁盘上删除。

大数据基础系列之kafka知识点和优点_Java_02

事实上,对于一个消费者,唯一需要保留的元数据信息就是它消费的偏移。这个偏移由消费者控制:通常消费者会在读取记录后线性地提高其偏移,但实际上,由于消费偏移由消费者控制,它可以以任何顺序消费消息记录。例如,消费者可以重置为较旧的偏移量以重新处理旧的数据,或者跳过最近的记录,并从“现在”开始消费。

这种特征的组合意味着kafka消费者非常方便 他们可以随意开始停止消费数据而对群集或其他消费者没有太大的影响。比如,你可以使用命令行消费者消费任何topic的数据,而不会对现有的消费者产生影响。

日志中分区有几个目的。首先,分区允许日志调整尺寸到适合单个服务器的大小。每个单独的分区必须适合存储到单台server上,一个topic有很多个分区,这样就使kafka能适用于任何数据量大小的数据。第二,它们作为并行性的单元 更多的是在这一点上。

三,分布

日志的分区分布在Kafka集群中的服务器上,每个服务器处理数据并请求分区的一部分。每个分区都会有可以配置数目个副本,用来容错。

每个分区都有有一个server当做leader,零个或者多个servers作为flowersLeader负责数据的读写,Follower负责从Leader同步数据。如果leader宕机,Followers中的一个会自动成为leader,每个Server既充当一些分区的leader,也会充当另一些分区的Followers,所以负载在集群中是均衡的。

具体的分区分配策略,请看浪尖的另一篇文章<>

五,生产者

生产者往选定的topic上发数据。生产者负责决定将消息发往哪个topic的哪个分区。可以通过轮训的方式来进行负载均衡,也可以根据一些语义功能,比如消息的key来决定分区(默认是keyhash之后对分区数取余,作为发往分区的id)。

六,消费者

消费者通过使用相同的组名字构成一个组,topic中的每一条消息记录只会被一个消费者组里的一个消费者实例消费。消费者实例可以运行在不同的进程中或者不同的机器上。

如果所有的消费者实例有相同的消费者组名,那么就可以实现消费者实例消费消息的负载均衡。(保证通过一个组的消费者数目,小于等于分区数)

如果所有的消费者实例拥有不同的消费者组名,那么每个消息会广播发送给所有的消费组。

大数据基础系列之kafka知识点和优点_Java_03

Kafka消费的实现是将日志分区尽量均匀的分布于消费者实例上,以使每个分区都会被消费者消费。组内消费者实例和分区的对应关系是被kafka动态维护的。如果有新的消费者实例加入,新的消费者实例会从同组内的其它消费者获取一些分区。如果有消费者死掉,它的分区也会被发到其余的消费者实例。

Kafka只会保证一个分区内的消息全局有序,不保证topic的所有分区总的有序。按key分区,进而保证分区内有序,足以满足大部分应用。然而,如果你需要整个topic的消息都是有序的,那么只能是一个topic只有一个分区,也就意味着一个消费者组内,只能有一个消费者。

七,担保

kafka提供以下保证:

1,发送到指定topic分区的消息,会按照被发送的顺序追加到日志里。比如,假如m1m2先发送到集群,意味着m2的偏移比m1大。

2,消费者实例看到的消息顺序跟kafka存储的消息顺序一致。

3,假如一个topic的分区有N个副本,那么就可以容忍N-1Server宕机,而且不会丢失数据。

八,kafka作为一个消息系统

Kafka流的概念和传统的消息队列有何区别?

传统的消息队列有两个模型:队列和发布-订阅。作为消息队列,消费者池会从从服务器读取消息,每条记录都转到其中一个消费者;在订阅发布系统中,消息会被广播到所有的消费者。队列的优点是它允许您在多个消费者实例上分配数据处理,从而可以扩展你的处理。不幸的是队列的方式不支持多订阅,一旦被消费,消息就不存在了。订阅发布系统运行你讲消息广播到多处理程序,但是无法扩展处理,因为每条消息都会发给所有的订阅者。

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

Kafka模型的优势就是每个topic都有这两个属性:

1,可以很好的动态扩展处理

2,支持多订阅者

比传统的消息系统,kafka也有强的顺序保证。

传统的队列在server端,消息是有序保存的,并且如果有很多消费者从队列里消费消息,server按照存储的顺序分发消息。但是,尽管server按顺序分发消息,消息记录是异步发给消费者的,所以消息在到达不同的消费者后可能已经乱序。这也就意味着在并行消费的情况下消息的顺序性丢失。消息系统通常也可以通过只有一个独享消费者来从队列里消费消息,但是这当然也意味着失去了并行处理的能力。

这点kafka就做的很好。通过使用topic的分区的概念,使kafka既能提供消息有序的保证,也能实现多消费者的负载均衡。实现方式是将分区分配给消费者组内的消费者,保证每个分区仅被同一个分组内的一个消费者消费。通过这点就可以保证一个分区的消息被一个消费者顺序消费。加上同一个topic内有很多分区,这也实现了多消费者的负载均衡。注意,无论如何都不要让同一个组内消费者实例数目大于分区数。消费组内的消费者与分区之间的关系请阅读<Kafka源码系列之分组消费的再平衡策略>

九,kafka作为一个存储系统

允许发布消息,消费消息的消息队列有效地充当stream中消息的存储系统。Kafka的不同之处在于它是一个很好的存储系统。

写到kafka的数据会写到磁盘并且同步到其它节点进行容错。可以配置使kafkaproducer等待服务端应答,服务端在所有副本都commit成功之后才给producer应答,producer此时才认为消息发送成功。Kafka的磁盘结构要求,使得磁盘可以很好的扩展,所以无论你存了50k还是50TB,都不会影响到kafka性能。

由于存储并允许客户端控制其读取位置,您可以将Kafka视为专用于高性能,低延迟的提交日志存储,副本和传播的专用分布式文件系统。

十,kafka做流处理

仅读取,写入和存储数据流是不够的,kafka的设计目的是实现流的实时处理。

Kafka的流处理器主要是实现,从kafka接受数据,对数据进行一些处理,在将数据写入输出的topic。例如,零售应用程序可能会收到销售和出货的输入流,并输出根据该数据计算的重新排序和价格调整。

kafkaproducerConsumer API来实现简单的处理是足够了。但是对于复杂的流式处理操作,kafka提供了一整套完整的Streams API.这允许构建应用程序进行复杂的处理,以计算流中的聚合或将流连接在一起。

该功能有助于解决下面几种类型的应用程序面临的问题:处理无序数据,重新处理输入作为代码更改,执行有状态计算等。

Streams API基于spark核心原始api构建的:使用producerConsumerAPIs实现输入输出,用kafka实现状态存储,使用相同的组的概念来实现stream processor实例的容错处理。

十一,总结

消息,存储和流处理的这种组合似乎是很奇怪的,但是对于kafka作为流处理平台的角色定位是非常重要的。

hdfs这样的分布式文件系统可以存储静态文件,用来做批处理。这样的系统允许存储和处理历史数据。

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

Kafka结合了这两种功能,这种组合对于Kafka作为流应用程序和流数据管道平台来说至关重要。

通过组合存储和低延迟订阅,流式应用程序可以以相同的方式处理过去和未来的数据。一个单一的程序可以处理历史的,已存储的数据,但是并不是处理到最后一条的时候结束,他可以在将来的数据到达是继续处理。

同样的,对于流数据管道,对实时消息订阅的组合使得kafka可以作为低延迟的数据管道。但是可靠性地存储数据的能力使得可以将其用于保证重要的数据传输,或者与需要定期加载处理的离线数据进行整合或者可能长时间停机进行维护。流处理功能使得实时转换数据成为可能。

大数据基础系列之kafka知识点和优点_Java_04