具象化模型
下图以订单、运输、通知等信息,描述与kafka交互的过程,业务中的事件(如下单,支付,配送,评价,售后)会产生各类信息,最终以topic归类汇集到kafka中
分区
同一类的消息都会汇集到一个Topic中,一个Topic可以分为多个Partition,Partition是最小的储存单元,每一个Partition储存着一部分的消息,每个Partition都是一个单独的log文件,每条记录都以追加的形式写入
偏移量 & 消息顺序
Partition中每条记录都会被分配唯一的序号,称为Offset,即偏移量
Offset是一个递增的,不可变的数字,由kafka自动维护
当一条记录写入Partition的时候,它就被追加到log文件的末尾,并被分配一个序号,作为 Offset
- 所以从Partition来看,单个Partition内部是有序的,但从Topic来看,消息在Partition之间是无序的;如果希望消息保证完全的顺序,就只能存在一个Partition,又或者发送端指定发送到某个Partition,消费端指定从某个Partition消费
Partition 扩展 & 冗余
kafka集群由多个Broker构成,每个Broker中含有集群的部分数据,同一个Topic的多个 Partition将分布在多个Broker中;Partition会生成多个副本,它们会分散在不同的Broker中,
如果某个Broker故障了,Consumer可以在其他Broker上找到Partition的副本,继续获取消息
Message 写入
指定Partition
Producer发送消息时,可指定一个Partition Key 这样就可以写入特定的Partition Partition Key会根据一个Hash函数计算出写入哪个Partition Partition Key相同的消息,会被放到相同的Partition 这种方式需要注意数据倾斜问题
随机Partition
如果没有使用Partition Key,kafka则会使用轮询的方式来决定写入哪个Partition 消息会均衡的写入各个Partition,这样无法确保消息的有序性
自定义规则
kafka支持自定义规则,一个Producer可以使用自己的分区指定规则。
Message 读取
kafka的消息读取采用的是pull方式,Consumer需要主动从Topic的Partition拉取消息,Pull模式下,Consumer就可以根据自己的消费能力去决定消费策略
但Pull有个缺点是,如果broker没有可供消费的消息,将导致consumer不断在循环中轮询,直到新消息到达
为了避免这点,kafka有个参数可以让Consumer阻塞直到新消息到达,也可以阻塞直到消息的数量累积到某个特定的值再读取
消息的Offset就是Consumer的游标,根据Offset来记录消息的消费情况
读完一条消息之后,Consumer会推进到Partition中的下一个Offset继续读取消息
Offset由Consumer负责维护
消费组
Consumer Group下有一个或多个Consumer,这些Consumer有相同的groupId,groupId是一个字符串,消费组的唯一标识
Topic中的每个分区只能分配给某个Consumer Group的一个Consumer消费(该分区还可以被分配给其他消费组)
参考资料:
https://medium.com/event-driv...
本文中大部分的图来自上述博客,应该是一位印度工程师所写,原文为英文且查看需要翻墙
https://www.bilibili.com/read...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。