举个例子
想象这么一个游戏,有一排柜子,刚好这排柜子嵌在了墙里,在墙的两面柜子都有门,也就是你可以在墙这面打开柜门,看到里边的美好事物,过一把眼瘾,也可以在墙的那面打开柜子的另一侧的门,看里边。
然后是规则,有A和B两队人,每队有若干人,两队人分别在墙的不同侧,然后人挨着个往前走,可以打开柜门看柜子里边的东西,但是必须顺序看,而且还不能看本组别人看过的柜子,然后每个人争先恐后的看,看完就报告看了哪个,然后去跟管柜子的人要接下来我能看哪个。
例子不是太贴切,灵感来源于和珅纪晓岚的看洋片桥段,稍加改动。接着说,这AB队就相当于kafka里边的消费组,队里的人就相当于每个消费者,装柜子的墙就像是broker,这排柜子就像是消息队列,如果有多个柜子就组成了主题,简单说就是某一类性质一样的内容组成了一个小团体。
再看看kafka
kafka的消息模型基本和上边的例子相当,只是上边的例子没有提到生产者,顾名思义,生产者就是产生消息的一方。那生产者、主题、broker、消费组、消费者到底是以什么样的形式工作的呢?
- 生产者,产生消息然后把消息和该消息要存放的主题传给kafka,kafka正确处理消息后,给生产者一个回信儿,告诉它处理完毕,然后生产者的这条消息的活就干完了,接着干下一条
- topic、Partition与broker,kafka收到消息后,根据某种规则(可以是随机选一个或者轮询这里不细说,咱们只聊模型)发到某个broker上的这个主题的Partition里,对于初学者来说这个broker到底是啥,结合上边的例子,其实就是存消息的地方,再说白了,就是机器,至于有多少broker就看你有多少机器了,多少Partition,需要自己指定。其实说白了Partition就是充当队列的作用。
- 消费组,其实就是消费消息的一帮client,但是这个消费组只消费它关心的主题消息,比如有个消费组G1,他名下有三个消费client,C1、C2、C3,刚才说了,消费组只消费关心的主题消息,那么C1-3也只能关注消费组关心的主题消息,要服从组织。同时有一点需要注意,不同消费组相互独立,谁也不影响谁。
- 消费者,就是消费组的一员了,同组的消费者正常情况下不重复消费,另外一个Partition只能被同组的一个消费者消费,当组内消费者数量比Partition多时,多出来的消费者闲着,啥也不干。如果消费者数量少于Partition,那消费者就多消费几个,多干点。
看一下模型图
一些问题
kafka消息存几份
对于使用者来说,感觉就存了一份,但实际不然,每个Partition都有副本,为了应对消息丢失,但实际你消费时,只能消费一份。
既然只有一份消息,怎么做到不同消费组之间不影响呢
消息是有编号的,kafka里用偏移量offset标识,在kafka内部存储了每个消费组的消费进度,也就是消费到哪条消息了,不同消费组就做到了消费的隔离。可以看一下下表
主题 | broker | 队列 | 消费组 | 消费进度 |
---|---|---|---|---|
topic1 | broker1 | Partition1 | 消费组1 | 123 |
topic1 | broker1 | Partition2 | 消费组1 | 110 |
topic1 | broker2 | Partition3 | 消费组1 | 130 |
topic1 | broker1 | Partition1 | 消费组2 | 1233 |
topic1 | broker1 | Partition2 | 消费组2 | 1180 |
topic1 | broker2 | Partition3 | 消费组2 | 1530 |
topic2 | broker1 | Partition1 | 消费组3 | 13 |
怎么保证同组消费者不重复消费
这个问题要建立在正常情况下,如果消费者非要自定义传offset,那就另说了,如果offset是存在kafka端就可以保证同组消费者不重复消费,有没有注意看上边的表,kafka记录的消费进度,和消费者没有关系,只记录消费组的,也就是当消费者过来拉消息时,只要报上”家门”(消费组),卡发卡就给这个“家门”消费进度后边的消息,并记录消费后的新进度。
以上就是对kafka消息模型的简单描述,希望能帮助刚开始入门的同学,方便后边的学习。