简单介绍
- Kafka 是一个分布式遵循消息发布-订阅模式的消息系统,其特点是具有高吞吐量
- 具有高性能、持久化、多副本备份、横向扩展能力
- 工作方式为由Producer向Topic推数据,Consumer从Topic拉数据
- 支持消息批量推送和拉取以及批量压缩来保证高吞吐量特性,多被用于日志收集、统计等数据收集业务
- 借助ZK进行Broker节点元数据信息存储以及Watch机制进行节点负载均衡和剔除操作
- Producer通过ZK拿到Leader节点信息并建立Socket连接传递消息
最后: Kafka速度的秘诀在于,它把所有的消息都变成一个批量的文件,并且进行合理的批量压缩,减少网络IO损耗。写入数据的时候由于单个Partion是末尾添加所以速度最优;读取数据的时候配合sendfile直接暴力输出
名词概念
术 语
| 概 念 |
---|---|
Broker | Kafka服务端节点 |
Topic | 主题,即队列概念,消息发送到Topic上进行保存.一个逻辑Topic的消息物理上可能存储于多个broker上(多个分区在不同broker上).多个逻辑Topic消息分开存储 |
Partition | 分区(文件),一个Topic可以有多个Partition.Producer可以将消息推送到不同分区,多个消费者消费不同分区消息来提高并发消费能力,提高吞吐量. |
Segment | 分段文件,存储于Partition文件中.其包含.index文件、.timeindex文件、.log文件(前两个用于检索消息,log存储消息),文件命名以该segment最小offset命名.实现Partition中消息分段存储功能 |
offset | 偏移量.分区上的消息定位,确定消息在Partition中的位置.各自Consumer维护自己在Partition上消费到的Offset |
Producer | 生产者.负责发送消息至Broker,需指定Topic.如推送Topic未创建,则Kafka会自动创建Topic.默认1个Partition(配置文件可以配置默认值) |
Consumer | 消费者负责从Broker取消息.需指定监听队列以及Topic |
Consumer Group | 消费者组,可指定消费者groupId,同一组内消费者不能消费同一Partition |
Message | 消息,消息主要包含Offset、Size(消息大小)、消息体(压缩后)、压缩类型 |
功能特性
- Kafka将每一个Tpoic的Partition作为具有顺序排列的日志,同一Partition的消息有一个唯一偏移量,所以只在Partition上保证消息的顺序性
- Kafka只保持跟踪未读消息,不管理已读状态的消息
- 集群模式下,分区消息发送和拉取只和Leader节点对接,Follower节点仅负责同步数据(主动批量拉取).当Leader节点故障,Follower升级为Leader节点
- kafka利用分段+索引+顺序存储的方式来解决查找效率的问题
- 每个消费者都属于一个Group,可指定消费者组名称,不设置则为默认消费者组
- 新Message直接追加到磁盘文件末尾,而不是随机的写入,保证Kafka的大吞吐量
Producer三种投递模式
新增的Partition直接参与新的Message分配,旧的Message不会重新分配.
- 指定分区精准投递
- 指定消息的Key,根据Key的Hash值计算投递分区(hash(message)%brokernum)
- 分区和Key均为指定则通过轮询方式投递至分区
消费模式
一条消息只能被一个消费者组内一个消费者消费,一个消费者可以消费多个Partition的消息
自定义分区分配策略可继承org.apache.kafka.clients.consumer.internals.AbstractPartitionAssignor
- 一个group下的consumer会消费掉Topic所有partition,即只会有空闲的consumer不会有空闲的partition.
- 多个Consumer Group对同一Topic下的各个分区消费情况互不影响,
- Broker节点/Consumer数量发生变动.会触发Reblance操作,对Consumer和Partition重分配.
消费者分区分配策略
- 平均分配 : (同一Topic)如遇到不能均分的会将多出的分给排序靠前的消费者
- 轮询分配 : (多Topic)将所有可分配Partition和Consumer进行轮询分配
ISR同步副本集合
- Kafka针对每个Topic动态维护的高度同步状态副本集合
(a set of in-sync replicas)
,简称ISR- 某分区的Leader不可用时,该集合中副本有被选为Leader的优先权
- Broker同步状态滞后会被剔除,当它重新跟上同步则会被重新加入
- 可指定ISR集合大小,当ISR大于最小值分区才接收写入操作.用以防止突发情况.该设置再acks=all情况下生效
replica.lag.time.max.ms
如果一个Follower在这个时间内没有发送fetch请求或消费Leader日志到结束的offset,Leader将从ISR中移除这个Followerreplica.fetch.wait.max.ms
,Follower同Leader之间通信的最大等待时间,有失败重试机制. 此值始终应始终小于replica.lag.time.max.ms
,以防止针对低吞吐量topic频繁收缩ISR
消息可靠性/消息确认机制
生产者:
- 生产者可设置消息推送确认参数为0(不开启ACK应答机制)、1(只leader确认)、2(一个leader和一个follower确认)、N、all/-1(follower完成同步,确保leader接收成功并且follower已完成备份)
- 可设置需要多少Follower完成同步即可确认投递成功,而不需要所有的Follower均完成同步.来平衡速度和安全性
- 当指定需同步节点挂掉,生产者等待同步超时.Kafka会将该Replica从ack确认列表移除,直到该Replica正常运行后再手动加入
消费者:
- Kafka消费者消费消息采取消费者主动找Leader拉取的方式
- 手动提交消费确认,消费者执行完消费逻辑即可提交
消息持久化介绍
kafka使用文件存储消息
- Kafka将数据保存在磁盘,并且以顺序写入数据和读取数据(效率比随机写入高).
- Kafka对日志文件采取append操作,并且为减少IO次数,会先将消息进行buffer,当消息数量/大小到达阈值再flush入磁盘.
- Consumer消费Partition会有消费的Offset来记录消费当前位置,由客户端负责保存
- 消息无论是否被消费都会被保存而不是立即删除.旧数据删除策略有两种:
基于时间,默认配置是168小时(7天);
基于大小,默认配置是1073741824;
- kafka读取特定消息的时间复杂度是O(1),删除过期的文件并不会提高kafka的性能
- 当某个Segment上的消息条数达到配置值或消息发布时间超过阈值时,segment上的消息会被flush到磁盘
- segment达到一定的大小后将不会再往该segment写数据,broker会创建新的segment
- 只有flush到磁盘上的消息consumer才能消费
集群思想
Kakfa Broker集群依赖Zookeeper管理,天然支持集群,单节点也是集群模式运行
Kafka节点注册到同一Zookeeper即为同一集群
- 故障转移/选举机制
如果Broker Controller宕机了,在ZK上面的那个临时节点就会消失,所有的Broker会一起去 Zk上注册临时节点,只有一个Broker会注册成功,这个成功的Broker会成为新的Broker Controller,其他的Broker Follower.这个Controller会监听其他的Kafka Broker的所有元信息.当旧的Broker Controller恢复后会Shutdown掉之前开启的各种节点和监听 - 数据备份容灾
每个partition可以在其他broker上存储副本Replica,存储副本的方式为按照broker顺序存储且副本数量不能大于节点数量.当一个broker宕机,Controller会读取该broker上partition存在zk上的状态,并选取一个replica作为新的patition leader(优先选取ISR列表的),如果没有存活的replica则会将这些patition leader设置为-1等到有replica时再将其选为leader.不同的Partition的Leader会均匀分布在不同的Broker上.(当ISR全部宕机,默认进行unclean leader选举来保证可用性,不保证消息可靠性) - 持久化同步机制
数据在Leader中从Page Cache刷盘到Disk后才可以被Follower同步.
数据同步到Follower写入Page Cache后,才会返回ACK.此时Leader断点,Follower还会有消息,新的Leader可以同步回去.所有机器宕机Leader磁盘中也有记录启动即可
优化设置
- 每个Topic的partition原则上大于等于broker数量可以保证吞吐量
- 为保证高可用,同一Partition的Replica应尽量分散至不同机器
- 禁用unclean leader选举,设置最少ISR数量