kafka随手记

1.Kafka?

kafka是一个高吞吐量,低延迟的分布式消息系统,它使用zookeeper来做集群管理。

最大的特点在于它的消息生产,消费中,引入了partition(分区)和group(组)的概念。produce(生产者)在发布消息时,可以选择partition数量,分区数量越多,该topic的吞吐量自然越大,因为它占有了更多的物理资源(这里可以简单的把分区类比做分布式系统中的服务节点)。

为什么要有分区?

如果一个topic(消息主题,可以理解为queue)只对应一个数据块/节点/服务器,那么这个机器的IO性能就决定了这个消息的吞吐性能,也就是所谓的吞吐量瓶颈。而有了分区之后,我们在发布消息时,kafka会根据msg的key来决定该条消息最终落地在哪个分区。不同的消息落地在不同的partition里,综合利用了分布式场景下多台机器的IO能力,从而极大的提高消息的吞吐能力。分区机制给kafka带来了水平扩容的能力。

什么是组?

consumer group,消费者分组,可以理解为对消息的消费者做了group的划分。同一个topic的同一条消息,只能被同一个group下的一个consumer消费到。但是多个consumer group可以同时消费到这一条消息。

这是Kafka用来实现一个Topic消息的广播(发给所有的Consumer)和单播(发给某一个Consumer)的手段。一个Topic可以对应多个Consumer Group。如果需要实现广播,只要每个Consumer有一个独立的Group就可以了。要实现单播只要所有的Consumer在同一个Group里。用Consumer Group还可以将Consumer进行自由的分组而不需要多次发送消息到不同的Topic。

2.几个常见的名词释义

broker:kafka节点,多个broker组成kafka集群。
topic:消息,主题,通常情况下可以单纯的类别为queue。
partition:物理上的分组,一个topic可以分为多个partition,每个partition是一个有序的队列。
segment:partition物理上由多个segment组成,每个Segment存着message信息。
producer : 生产message发送到topic。
message:消息,producer生产的消息归属于topic,根据key和分区情况被分派到不同的分区落地,并存储在segment中。
consumer : 订阅topic消费message, consumer作为一个线程来消费。
consumer Group:一个Consumer Group包含多个consumer。

3.消息投递可靠性
一个消息如何算投递成功,Kafka提供了三种模式:
第一种是啥都不管,发送出去就当作成功,这种情况当然不能保证消息成功投递到broker;
第二种是Master-Slave模型,只有当Master和所有Slave都接收到消息时,才算投递成功,这种模型提供了最高的投递可靠性,但是损伤了性能;
第三种模型,即只要Master确认收到消息就算投递成功;实际使用时,根据应用特性选择,绝大多数情况下都会中和可靠性和性能选择第三种模型

4.kafka的一些机制

持久化

kafka把消息存储于文件系统,这一特点使得磁盘的IO性能直接影响到kafka的吞吐性能。kafka把消息用日志追加的形式记录在文件中,为了提升IO性能,减少IO次数,broker选择把消息buffer起来,当缓存的消息个数/大小达到阈值,再一次性flush到磁盘中。可以类比于Java IO中的FileReader 和 BufferedReader之间的区别来理解。

性能:

IO不仅限于磁盘IO,网络IO也是直接影响kafka吞吐量的。kakfa在这里使用gzip/snappy等多种方式来进行消息压缩。

producer支持异步发送,可以理解为producer把消息buffer起来,一定程度后一次IO给broker进行处理。优点是,减少了小IO的操作次数,可以有效的降低网络延迟,缺点是:一旦producer挂掉,已经buffer起来,但还没有发送给broker的消息可能丢失。

offset

我们可以简单的把offset理解为消息的id,它是连续的。如果开启了kafka的auto commit,当consumer读取到消息时,不管消费者对消息做了什么处理,成功与否,都会把offset+1并且同步到zookeeper中去。

消息一致性

Kafka提供3种消息传输一致性语义:最多1次,最少1次,恰好1次。
最多1次:可能会出现数据丢失情况;
最少1次:可能会重传数据,有可能出现数据被重复处理的情况;
恰好1次:并不是指真正只传输1次,只不过有一个机制。确保不会出现“数据被重复处理”和“数据丢失”的情况。

at most once: 消费者fetch消息,然后保存offset,然后处理消息;当client保存offset之后,但是在消息处理过程中consumer进程失效(crash),导致部分消息未能继续处理.那么此后可能其他consumer会接管,但是因为offset已经提前保存,那么新的consumer将不能fetch到offset之前的消息(尽管它们尚没有被处理),这就是”at most once”.

at least once: 消费者fetch消息,然后处理消息,然后保存offset.如果消息处理成功之后,但是在保存offset阶段zookeeper异常或者consumer失效,导致保存offset操作未能执行成功,这就导致接下来再次fetch时可能获得上次已经处理过的消息,这就是”at least once”.

恰好一次
使用最少一次,并在消费者端记录已处理消息最大编号(offset),当新取到的msg编号小于当前记录值时,认为该消息已经被处理过。

参考&引用:
薛定谔的鸡@Kafka史上最详细原理总结