【Kafka入门】Kafka基础结构和知识

时间:2024-08-12 15:06:02

基本概念的总结

在基本的Kafka架构中,producer将消息发布到Kafka话题中,一个Kafka话题通常指消息的类别或者名称,Kafka话题被集群中一个充当Kafka server角色的

broker创建。Kafka broker用来存储消息,consumer可以订阅一个或者多个话题来获取话题中的消息。其中Kafka brokers用Zookeeper来获取消息状态,

而Kafka consumers则利用Zookeeper来跟踪消息的offset。具体如下图所示:

【Kafka入门】Kafka基础结构和知识

上图是一个只有一个Kafka broker的架构,其中包含一个topic,该topic包含4个partition,上图包含了Kafka中最重要的5个组件:Zookeeper, Broker, Topic, Producer, and Consumer。

在Kafka话题中,每一个partition都被映射到一个逻辑日志文件中,日志文件呈现为一组大小相等的段文件。每一个partition是一个有序的,不可变的消息序列;每一次当有消息被发布到这个partition,负责该partition的broker将新来的消息追加到该partition最后一个段文件中。在存储的消息的条数达到配置的消息条数或者当过了一段时间后,这些段文件将刷写到磁盘中。一旦段文件被刷写到磁盘,这些消息就可以被Kafka consumer消费。

每个消息在partition中都有一个称为offset的标记,该标记是有序,唯一的序号。每个partition可以有选择的冗余多份,以保证可用性。在多个partition存在的情况下,有一个称为leader的partition,其他partition都称为follower。其中leader负责该partition所有的读写请求,而follower则异步的更新本地来和leader保持一致,所以在消息的一致性上,follower是要延迟于leader的。

Kafka动态维护一组同步副本(ISR),该副本紧跟leader与其内容保持一致,并将最新的ISR同步给Zookeeper。如果leader挂了,一个follower(在ISR同步副本中)将自动成为新的leader。在Kafka集群中,每个server都扮演双重角色,它作为一些partition的leader的同时,也作为其他partition的follower,这确保了Kafka集群内的负载平衡。

在Kafka中有一个consumer group的概念,每个consumer只是consumer group中的一个进程。一个话题中的一条消息只能被consumer group中的一个consumer进程消费,也就是说,如果要求该话题中的某消息被多个consumer消费,则这些consumer必须在不同的consumer group中。

consumer总是从一个特定的partition顺序地消费消息,并应答消费了的消息的offset,已经应答的offset意味着consumer已经消费了这些信息。consumer发出了一个包含消息offset的异步请求给broker,并得到字节的缓冲区。

在Kafka的设计中,broker是无状态的,也就是说,在broker中不存储哪些消息被哪些consumer消费了,这些消费记录被设计存储在consumer中,也就是说,broker根本不知道哪些消息被消费了。在Kafka中,给消息定义了一个SLA (service level agreement),SLA表示消息的保留时间,一旦消息保留时间超过SLA,则会被删除,这种设计有意无意的提示了consumer去消费旧消息,不然就会被删除。

Kafka设计的一些重点总结:

1. Kafka最重要的基石是消息在文件系统上的缓冲和存储。在Kafka中,消息是立即写到操作系统内核页的,数据的缓冲和刷写到磁盘都是可配置的。

2. Kafka提供消息的长时间存储,即使消息已经被消费过,它支持consumer再消费。

3. Kafka利用消息集合来group消息,从而减小网络带宽的消耗。消息被消费的元数据不是存储在server上,而是在consumer上。这可以避免“消息的丢失”和“同一消息的多次传输”。

4. consumers将状态信息储存在Zookeeper上,Kafka也允许将这些信息存储到其他存储系统上。

5. 在Kafka中,producer和consumer以一种推-拉的模式工作,其中producer将信息推到Kafka broker上,然后consumer则从broker上拉取信息。

6. Kafka的设计中没有master的概念,所有的broker都是对等的。这种设计使得broker的添加和删除变得简便,因为broker的元数据信息被Zookeeper维护着并被所有的consumer共享。producer在发送数据给broker时也可以在同步和异步的模式中作选择。

消息压缩

在Kafka中,支持对消息分组压缩,以获得更高效的信息传输,这种压缩一次压缩多个消息,而不是一个消息。一组消息压缩后然后在发送给broker,这能有效减少网络带宽的消耗。

在Kafka0.8中,每个分区的leader broker在消息追加到日志上前,需要给每一个消息赋予一个独一无二的逻辑offset,所以如果消息是压缩的,broker需要解压缩,然后才能给每条消息赋予offset,对于压缩的数据,在赋予完offset后,broker还需要再压缩这些数据然后再刷写到磁盘上。所以,数据的压缩对broker的CPU的负载是一大挑战。

消息最初的压缩是发生在producer端的,可支持的压缩协议包括GZIP和Snappy,具体配置如下:

Property name

Description

Default value

compression.codec

This parameter specifies the compression codec for all data generated by this producer. Valid values are none, gzip, and snappy.

none

compressed.topics

This parameter allows you to set whether compression should be turned on for particular topics. If the compression codec is anything other than none, enable compression only compressed.topics for specified topics, if any. If the list of compressed topics is empty, then enable the null specified compression codec for all topics. If the compression codec is none, compression is disabled for all topics.

null

消息partition

对消息如何partition由producer决定,broker按照消息来的先后顺序存储,在Kafka broker可以为每一个topic配置partition数目。

partition冗余

冗余是Kafka0.8的新特性,冗余可以提高Kafka的可用性,其中producer和consumer都是可感知冗余的。下图形象展示了冗余的特性:

【Kafka入门】Kafka基础结构和知识

在冗余机制下,每个拥有n个冗余的partition可以容忍n-1个冗余的不可用,在这n个冗余中,其中有一个担任leader的冗余,其余的冗余称为follower,这些可用的follower构成一个ISR集合,Zookeeper维护着每个partition的leader的信息和ISR的信息。

partition冗余方式

1. 同步冗余:消息在producer端分成了不同的partition,对于每一个partition,producer首先同Zookeeper确定该partition的lead broker,然后将消息发布到该broker上,当消息都发布完了,消息将刷写到lead broker的log上,然后关于该partition的所有follower都在该lead broker拉取该partition,通过单一通道来保证消息的顺序。每个follower拉取完毕partition并存储到本地log后,会返回一个应答给lead broker。当收到所有follower的应答后,lead broker则返回一个应答给producer。此时,该partition可以被consumer消费。

2. 异步冗余:异步冗余则不会等待所有的follower的应该就应答producer,这种机制如果lead broker挂掉的话则不能保证消息的正常消费。

对于某个ISR集合中的follower挂掉后,leader则将该follower从ISR集合中剔除,其他的follower继续同步信息;
如果是leader挂掉了,就算失败发生在最后的应答前,producer还是会再次发布该partition到新的leader上。

leader挂掉会经历如下几个过程:

1)从ISR集合中,所有follower中最早注册的replica称为新的leader,其他的依然为follower;

2)新leader的log end offset(LEO)成为该partition的最终提交消息;

3)新leader在配置时间过了后或者所有的replica都同步好了后,将新的ISR同步给Zookeeper,并启动读写服务。

Kafka学习刚入门,如有理解错误请给位指正!