kafka相关的概念总结
是什么
kafka是一个消息中间件,一个分布式流*台,作为一个集群运行在一个或多个服务器上
- 可发布订阅消息(流)
- 以容错(故障转移)方式存储消息(流)
- 在消息(流)发生时处理它们
核心API
- Producer API :用来发布消息到1个或多个topic(主题)中
- Consumer API :用来订阅一个或多个topic,并处理产生的消息
- Streams API :充当一个流处理器,从1个或多个topic消费输入流,并生产一个输出流到1个或多个输出topic,完成转换工作
- Connector API :将topic连接到应用程序或数据系统
- Admin API :用于管理和检查topic,broker
基本概念
record: kafka的数据单元,也叫消息,每个消息(也叫record)由一个key,一个value和时间戳构成
topic: kafka将消息分类,每一类消息称为一个主题(Topic),这是一个逻辑概念
producer: 发布消息的对象称之为主题生产者(Kafka topic producer)
consumer:订阅消息并处理发布的消息的对象称之为主题消费者(consumers)
broker: 已发布的消息保存在一组服务器中,称之为Kafka集群。集群中的每一个服务器都是一个代理(Broker)
消费者可以订阅一个或多个主题(topic),并从Broker拉数据,从而消费这些已发布的消息
partition: 一个分区就是一个提交日志,是一个物理的概念,存在于具体的broker上(每个broker上可以有很多分区),
每个分区对应一个文件夹,可以看作是一个顺序的消息队列,新消息被顺序添加到分区中。
生产者可以只关心topic,不用关心消息被发送到哪个broker上的哪个partition,
消费者可以并行的从不同的broker上的不同分区消费消息,因此分区可以实现水*扩展,且突破单个broker的瓶颈限制
segment:partition内部存储日志文件的基本单位,叫日志段,主要由消息日志文件(.log),位移索引文件(.index),时间戳
索引文件(.timeindex)组成
offset: partition中的消息都会被分配一个序列号,称为offset,消费者可控制的提交,consumer消费消息时,offset线性增加
在新版本中(0.9以后的,我们用的0.10+),这个值存在__consumer_offsets这个topic中,并不在zk中管理,存的是consumer
提交的位移
batch: 批次,就是一组消息,批次的大小要在时间延迟和吞吐量之间做权衡
rebalance:当分区数量或消费组中消费者数量发生变化时,kafka会进行rebalance操作
consumer group 消费者组
重要的概念,单独讲。消息模型一般可以分为以下两种
- queue模型:一组消费者读取消息,一条消息只有其中的一个消费者来处理
- publish-subscribe模型:消息被广播给所有的消费者,接收到消息的消费者都可以处理此消息
Kafka为两种模型提供了单一的消费者抽象模型: consumer group,消费者用一个groupId标记自己,消息被分发给此group中的一个消费者
- 假如所有的消费者都在一个组中,就变成了queue模型。
- 假如所有的消费者都在不同的组中,就完全变成了发布-订阅模型
- 可以创建一些消费者组作为逻辑上的订阅者。每个组包含数目不等的消费者,一个组内多个消费者可以用来扩展性能和容错
分区和顺序问题
发送到broker上的单个分区的消息可以保证顺序
但是并行消费不能保证消费到的消息的先后顺序
分区中消息只能由消费者组中的唯一一个消费者处理,基于这点,按照业务需要考虑以下两种方案:
单分区保证顺序+单consumer消费,这种没办法,顺序化基本没问题了
单分区保证顺序+多consumer消费,这里要保证consumer处理消息的能力(速度)基本是一样的
多分区+消息key路由保证一定顺序+多consumer消费
项目中遇到过具体业务,后续给出具体实践
几个注意点
kafka的每个topic中的消息消费时都有以下两种模式:
队列
: 允许同名的消费者组成员瓜分处理消息
发布订阅
:允许广播消息给多个消费者组
topic的parition设计为kafka提供了顺序保证和负载均衡
每个partition仅由同一个消费者组中的一个消费者按顺序消费到消息。并确保消费者是该partition的唯一消费者
每个topic有多个分区,则需要对多个消费者做负载均衡,但请注意,
相同的消费者组中不能有比分区数量更多的消费者,否则多出的消费者一直处于空等待,不会收到消息
流处理Stream API
kafka提供了读,写,存3个大功能,也支持实时流处理,如处理无序的数据,代码更改的再处理,执行状态计算等
Sterams API在Kafka中的位置:使用producer和consumer API作为输入,利用Kafka做状态存储,使用相同的组机制
在stream处理器实例之间进行容错保障
需要辨析理解的点
不同partition中的消息,消费时不保证顺序
一般情况下,消费组里的成员(消费者)消费时接**分消息
3个分区给组里的2个消费者,那么一个消费者会消费2个分区,一个只消费1个分区
获取消息一般很快,瓶颈一般在于消费下来的一批消息怎么做业务处理
关于__consumer_offsets
做项目的时候发生过单独处理offset的问题,比较好奇这个topic里消息到底是什么结构,找到一张图:
可以理解为每个offset值由groupId+topicName+partitionNum来唯一确定,对于有rebalance情况的消费者变化,
只关心这个topic下,某个分区内最新提交的offset值,至于consumer有没有变更,其实不用关心,不管哪个消费
者接管,都是识别该分区里最新的这个offset