kafka核心概念和角色
文章目录
1.概述
kafka里面的消息是有topic来组织的,简单的我们可以想象为一个队列
-
一个topic就是一个消息队列,然后它把每个topic又分为很多个partition
- 这个是为了做并行的,更加方便扩展,而且提高了吞吐量
- 在每个partition内部消息强有序,相当于有序的队列,其中每个消息都有个序号offset,比如0到12,从前面读往后面写。
-
一个partition对应一个broker,一个broker可以管理多个partition
比如说,topic有6个partition,有两个broker,那每个broker就管3个partition。
-
partition可以想象为一个文件,当数据发过来的时候它就往这个partition上面追加就行,消息不经过内存缓冲,直接写入文件
kafka和很多消息系统不一样,很多消息系统是消费完了就把它删掉,而kafka是根据时间策略删除,而不是消费完就删除,在kafka里面没有一个消费完这么个概念,只有过期这样一个概念。
-
producer自己决定往哪个partition里面去写,这里有一些的策略,譬如hash。
consumer自己维护消费到哪个offset,每个consumer都有对应的组
- 组内:是queue消费模型,各个consumer消费不同的partition,因此一个消息在group内只消费一次
- 组间:是发布/订阅消费模型,各个组各自独立消费,互不影响,因此一个消息只被每个组消费一次
- Topic可以类比为数据库中的库
- partition可以类比为数据库中的表
- 一个topic就是一个消息队列,然后它把每个topic又分为很多个partition
- 一个topic可以有多个消费者组
- 同一个消费者组内的消费者在消费同一个topic时,这个topic中相同的数据只能被消费一次,即每个partion只会把消息发给该消费者组中的一个消费者
- 不同的消费者组消费同一个topic互不影响
- 一台kafka服务器节点就是一个broker。一个集群由多个broker组成。一个broker可以容纳多个topic。
2.Producer
消息生产者,就是向kafka broker发消息的客户端。生产者负责将记录分配到topic的指定 partition(分区)中
生产者会决定发送到哪个Partition,有两种发送的机制:
-
轮询(Round robin)
先随机到某一个partition上一直持续的写,大概写个十分钟,再随机到一个partition再去写,所以一般建议生产消息都按照建个key来按照hash去分,还可以自定义按照key怎么去分
-
key的hash
如果key为null,就是轮询,否则就是按照key的hash
3.Consumer
消息消费者,向kafka broker取消息的客户端。每个消费者都要维护自己读取数据的offset。
- 每个consumer都有自己的消费者组group
- 同一个消费者组内的消费者在消费同一个topic时,这个topic中相同的数据只能被消费一次
- 不同的消费者组消费同一个topic互不影响
- 低版本0.9之前将offset保存在Zookeeper中,0.9及之后保存在Kafka的“__consumer_offsets”主题中。
4.Consumer Group
每个消费者都会使用一个消费组名称来进行标识。同一个组中的不同的消费者实例,可以分布在多个进程或多个机器上。
消费者组,由多个consumer组成。
-
一个topic可以有多个消费者组。topic的消息会复制(不是真的复制,是概念上的)到所有的CG,但每个partion只会把消息发给该CG中的一个consumer。
-
消费者组内每个消费者负责消费不同分区的数据,一个分区只能由一个消费者消费;
-
消费者组之间互不影响。
-
所有的消费者都属于某个消费者组,即消费者组是逻辑上的一个订阅者。
-
如果所有的消费者实例在同一消费组中,消息记录会负载平衡到每一个消费者实例(单播)。即每个消费者可以同时读取一个topic的不同分区!
消费者组是kafka用来**实现一个topic消息的广播(发给所有的消费者)和单播(发给任意一个消费者)**的手段。
-
如果需要实现广播,只要每个消费者有一个独立的消费者组就可以了。
-
如果需要实现单播,只要所有的消费者在同一个消费者组。用消费者组还可以将消费者进行自由的分组而不需要多次发送消息到不同的topic。
5.Broker
kafka集群的server,一台kafka服务器节点就是一个broker,负责处理消息读、写请求,存储消息,在kafka cluster这一层这里,其实里面是有很多个broker
- 一个集群由多个broker组成。一个broker可以容纳多个topic。
- broker是组成kafka集群的节点,broker之间没有主从关系,各个broker之间的协调依赖于zookeeper,如数据在哪个节点上之类的
Kafka集群中有一个broker会被选举为Controller,负责管理集群broker的上下线,所有topic的分区副本分配和leader选举等工作。
Controller的管理工作都是依赖于Zookeeper的。
6.Topic
Topic 就是数据主题,kafka建议根据业务系统将不同的数据存放在不同的topic中。如:日志的消息可以放在一个topic,金额的消息可以放在一个topic,不同类别的消息放在不同的topic内,这次取消息更方便
- Kafka中的Topics总是多订阅者模式,一个topic可以拥有一个或者多个消费者来订阅它的数据
- 一个大的Topic可以分布式存储在多个kafka broker中
- Topic可以类比为数据库中的库
一个topic就是一个消息队列,然后它把每个topic又分为很多个partition
- 这个是为了做并行的,更加方便扩展,而且提高了吞吐量
- 在每个partition内部消息强有序,相当于有序的队列,其中每个消息都有个序号offset,比如0到12,从前面读往后面写。
7.Partition
-
一个topic可以分为多个partition,通过分区的设计,topic可以不断进行扩展。即一个Topic的多个分区分布式存储在多个broker(服务器)上。此外通过分区还可以让一个topic被多个consumer进行消费。以达到并行处理。分区可以类比为数据库中的表。
-
partition内部有序,但一个topic的整体(多个partition间)不一定有序
kafka只保证按一个partition中的顺序将消息发给consumer,partition中的每条消息都会被分配一个有序的id(offset),每个partition内部消息是一个强有序的队列,但不保证一个topic的整体(多个partition间)的顺序。
-
一个partition对应一个broker,一个broker可以管理多个partition
比如说,topic有6个partition,有两个broker,那每个broker就管3个partition。
-
partition可以很简单想象为一个文件,partition对应磁盘上的目录,当数据发过来的时候它就往这个partition上面追加,消息不经过内存缓冲,直接写入文件
kafka为每个主题维护了分布式的分区(partition)日志文件,每个partition在kafka存储层面是append log。任何发布到此partition的消息都会被追加到log文件的尾部,在分区中的每条消息都会按照时间顺序分配到一个单调递增的顺序编号,也就是我们的offset,offset是一个long型的数字,我们通过这个offset可以确定一条在该partition下的唯一消息。在partition下面是保证了有序性,但是在topic下面没有保证有序性。
-
每个partition都会有副本,可以在创建topic时来指定有几个副本
8.Offset
kafka的存储文件都是按照offset.kafka来命名,用offset做名字的好处是方便查找。例如你想找位于2049的位置,只要找到2048.kafka的文件即可。当然the first offset就是00000000000.kafka
数据会按照时间顺序被不断第追加到分区的一个结构化的commit log中!每个分区中存储的记录都是有序的,且顺序不可变!
这个顺序是通过一个称之为offset的id来唯一标识!因此也可以认为offset是有序且不可变的!
在每一个消费者端,会唯一保存的元数据是offset(偏移量),即消费在log中的位置,偏移量由消费者所控制。通常在读取记录后,消费者会以线性的方式增加偏移量,但是实际上,由于这个位置由消费者控制,所以消费者可以采用任何顺序来消费记录。例如,一个消费者可以重置到一个旧的偏移量,从而重新处理过去的数据;也可以跳过最近的记录,从"现在"开始消费。
这些细节说明Kafka 消费者是非常廉价的—消费者的增加和减少,对集群或者其他消费者没有多大的影响。比如,你可以使用命令行工具,对一些topic内容执行 tail操作,并不会影响已存在的消费者消费数据。
图1 Topic拓扑结构
图2 数据流
9.持久化
Kafka 集群保留所有发布的记录—无论他们是否已被消费—并通过一个可配置的参数——保留期限来控制。举个例子, 如果保留策略设置为2天,一条记录发布后两天内,可以随时被消费,两天过后这条记录会被清除并释放磁盘空间。
Kafka的性能和数据大小无关,所以长时间存储数据没有什么问题。
10.Replica副本机制
副本,为保证集群中的某个节点发生故障时,该节点上的partition数据不丢失,且kafka仍然能够继续工作,kafka提供了副本机制,一个topic的每个分区都有若干个副本,一个leader和若干个follower。
日志的分区partition (分布)在Kafka集群的服务器上。每个服务器在处理数据和请求时,共享这些分区。每一个分区都会在已配置的服务器上进行备份,确保容错性。
每个分区都有一台 server 作为 “leader”,零台或者多台server作为 follwers 。leader server 处理一切对 partition (分区)的读写请求,而follwers只需被动的同步leader上的数据。当leader宕机了,followers 中的一台服务器会自动成为新的 leader。通过这种机制,既可以保证数据有多个副本,也实现了一个高可用的机制!
同一个partition可能会有多个replication(对应 server.properties 配置中的 default.replication.factor=N)。没有replication的情况下,一旦broker 宕机,其上所有 partition 的数据都不可被消费,同时producer也不能再将数据存于其上的patition。引入replication之后,同一个partition可能会有多个replication,而这时需要在这些replication之间选出一个leader,producer和consumer只与这个leader交互,其它replication作为follower从leader 中复制数据。
基于安全考虑,每个分区的Leader和follower一般会错在在不同的broker!
leader
每个分区多个副本的“主”,生产者发送数据的对象,以及消费者消费数据的对象都是leader。
follower
每个分区多个副本中的“从”,实时从leader中同步数据,保持和leader数据的同步。leader发生故障时,某个follower会成为新的follower。
11.zookeeper
元数据信息存在zookeeper中,包括:broker,topic,partition的元数据消息(存储消费偏移量,topic话题信息,partition信息)。kafka0.8之前还可以存储消费者offset
Kafka集群中有一个broker会被选举为Controller,负责管理集群broker的上下线,所有topic的分区副本分配和leader选举等工作。
Controller的管理工作都是依赖于Zookeeper的。