基本介绍:
kafka是一个分布式数据流平台,可以运行在单台服务器上,也可以在多台服务器上部署形成集群。它提供了发布和订阅功能,使用者可以发送数据到kafka中,也可以从kafk中读取数据(以便后续的处理)。kafka具有高吞吐,低延迟,高容错等特点。
消息队列通信模型:
点的点模式(queue)
消息生产者生产消息发送到queue中,然后消费者从queue中取出并且消费消息,一条消息被消费以后,queue中就没有了,不存在重复消费。
发布/订阅(topic)
消息生产者(发布)将消息发布到topic中,同时有多个消费者(订阅)消费该消息。和点对点方式不同,发布到topic的消息会被所有订阅者消费。
注:发布/订阅模式下,当发布者消息量很大时,单个订阅者的处理能力是不足的。实际上现实场景中是多个订阅者节点组成一个订阅组负载均衡消费topic消息,既分组订阅,这样订阅者很容易实现消费能力线性扩展。可以看成是一个topic下有多个queue,每个queue是点对点方式,queue之间是发布订阅方式。
架构图:
· Producer:Producer即生产者,消息的生产者,是消息的入口。
· kafka cluster:kafka集群,一台或多台服务器组成。
Broker:Broker是指部署了kafka实例的服务器节点。每个服务器上有一个或多个kafka的实例,可以认为每个broker对应一台服务器。每个kafka集群内的broker都有一个不重复的编号,如图中的broker-0,broker-1等....
Topic:消息的主题,可以理解为消息的分类,kafka的数据就保存在topic。在每个broker上,都可以创建多个topic。实际应用中通常是一个业务线建立一个topic。
Partition:topic的分区,每个topic可以有多个分区,分布的作用是做负载,提高kafka的吞吐量。同一个topic在不同分区的数据是不重复的,partition的表现形式是一个一个的文件夹。
Replication:每一个分区都有多个副本,副本的作用是做备胎。当主分区(Leader)故障的时候会选择一个备胎(Follower)上位,成为Leader。在kafka中默认副本的最大数量是10个,且副本的数量不能大于Broker的数量,Follower和Leader绝对是在不同的机器,同一个机器对同一分区也只能存放一个副本(包括自己)。
· Consumer:消费者,即消费方,是消息的出口。
Consumer Group:我们可以将多个消费者组成一个消费组,在kafka的设计中同一个分区的数据只能被消费组中某一个消费者消费。同一个消费组的消费者可以消费同一个topic不同分区的数据,这也是为了提高kafka的吞吐量。
工作流程:
1.生产者从kafka中获取分区的leader信息。
2.生产者将消息发送给leder。
3.leader将消息写入本地磁盘。
4.follower从leader拉取消息数据。
5.follower将消息写入本地磁盘后向leader发送ACK
6.leader收到所有的follower的ACK后向生产者发送ACK。
选择Partition的原则:
在kafka中,如果某个topic有多个partition,producer又怎么知道该将数据发送给哪个partition呢?
1.pratition在写入的时候可以指定需要写入的partition,如果有指定,则写入对应的partitionww。
2.如果没有指定partition,但是设置了数据的key,则会根据key的值hash出一个partition。
3.如果即没有指定partition,又没有设置key,则会采取轮询方式,即每次取一小段时间的数据写入partition,下一小段时间写入下一个partition。
ACK应答机制:
producer在向kafka写入消息数据的时候,可以设置参数来确定是否确认kafka接收到数据,这个参数可以设置值为:0,1,all。
0.代表producer往集群发送数据的时候,不需要等集群的返回,不确保消息发送成功。安全性最低但是效率最高。
1.代表producer往集群发送数据只要leader应答就可以发送下一条,只确保leader的发送成功。
all.代表producer往集群发送数据需要所有的follower都完成从leader的同步才会发送下一条,确保leader发送成功和所有副本都完成备份,安全性最高,性能效率最低。
注:如果往不存在的topic写数据,kafka会自动创建topic,partition和replication的数量,默认配置都是1。
Topic和数据日志:
topic是同一类别的消息记录(record)的合集,在kafka中,一个主题通常有多个订阅者。对于每个主题,kafka集群维护了一个分区数据日志文件结构如下:
每个partition都是一个有序且不可变的消息记录合集。当新的数据写入时,就会被追加到partition的末尾。在每个partition中,每条消息都会被分配一个顺序的唯一标识,这个标识被称为offset,即偏移量。注:kafka只保证在同一个partition内部的消息是有序的,在不同的partition之间,并不能保证消息有序。
kafka可以配置一个保留期限,用来标识日志会在kafka集群内保留多长时间。kafka集群会保留在保留期限内的所有被发布的消息,不管这些消息是否被消费过。比如保留期限设置为两天,那么数据被发布到kafka集群的两天以内,所有的这些数据都可以被消费。当超过两天,这些数据都会被清空,以便为后续的数据腾出空间。由于kafka会把数据进行持久化存储(写到硬盘),所以保留的数据大小可以设置为一个比较大的值。
Partition结构:
partition在服务器上的表现形式就是一个一个的文件夹,每个partition的文件夹下面都会有的多组segment文件,每组segment文件又包含.index文件,.log文件,.timeindex文件三个文件,其中.log文件就是实际存储message的地方,而.index和.timeindex文件作为索引文件,用于检索消息。
消费数据:
多个消费者实例可以组成一个消费者组,并用一个标签来标识这个消费组。一个消费组中的不同消费者实例可以运行在不同的进程甚至不同的服务器上。
如果所有的消费者实例都在同一个消费者组中,那么消息记录会被很好的均衡的发送到每个消费者实例。
如果所有的消费者实例都在不同的消费者组,那么每一条消息记录会被广播到每一个消费者实例。但是一个消费者组中,只能有一个消费者实例消费一条数据。