分布式专题
Kafka
- 一、Kafka 入门及部署
- 二、Kafka核心架构原理
Kafka 核心架构图
Kafka消息存放
1、Kafka是根据offset获取对应的消息,消费者获取到消息之后不会像RabbitMQ一样移除
2、Kafka 的Topic分成不同的Partition分区,每个Partition存在多个segment分段存储
3、Kafka 一个分区的消息数据对应存储在一个文件夹下,以topic名称+分区号命名,消息在分区内是分段(segment)存储,每个segment对应两个文件,分别为.index索引和.log数据文件
segment结构
- 00000000000000000000.index
存储消息的索引
- 00000000000000000000.log
存储消息文件
- 00000000000000000000.timeindex
消息的发送时间索引文件,kafka每次往分区发4K消息就会记录一条当前消息的发送时间戳与对应的offset到timeindex文件
结构如下图所示:
Kafka索引机制
- .index(偏移量索引文件)用来建立消息偏移量(offset)到物理地址之间的映射关系,方便快速定位消息所在的物理文件位置
- .timeindex(时间戳索引文件)根据指定的时间戳(timestamp)来查找对应的偏移量信息
kafka中的 索引文件没有对每个消息建立索引,目的是为了节约我们空间的资源
其利用稀疏索引算法+二分查找算法,定位到邻居, 在根据顺序遍历查找
Kafka Broker控制器原理
- 在kafka集群中会有多个不同的broker组成,其只会有一个broker选举成为
Kafka Controller 控制器 角色。
- 它主要负责维护集群中所有分区和副本的状态,当某个分区
Leader 副本数据(一个分区中存在多个不同的副本,只有Leader副本提供对外服务)出现故障时,由控制器负责为该分区选举新的leader副本
- 当检测到某个分区的ISR集合发生变化时,由控制器负责通知所有broker更新其元数据信息。当为某个Topic增加分区数量时,由控制器负责分区的重新分配
控制器选举的原理
- 在kafka集群启动的时候,会自动选举一台broker作为controller来管理整个集群,选举的过程是集群中每个broker都会尝试在zookeeper上创建一个 /controller 临时节点
- zookeeper会保证有且仅有一个broker能创建成功,这个broker就会成为集群的总控器controller,底层依赖zookeeper临时节点机制
- 控制器的故障转移:如果当控制器宕机之后,会发送事件通知给其他Broker重新开始竞争控制器管理者
Kafka Partition副本选举机制
副本机制的概念
- 备份机制,通常是指分布式系统在多台互联网的机器上保存相同的数据拷贝
- 提供高伸缩性
- 提供数据冗余,其中一个Broker宕机,整体还可正常运行
1、同一个分区下的所有副本保存有相同的消息序列,这些副本分散保存在不同的 Broker 上。
2、副本分成两类:Leader副本(Leader Replica)和Follower 副本(Follower Replica)。每个分区在创建时都要选举一个副本,称为Leader副本,其余的副本自动称为Follower 副本。
3、在 Kafka 中,Follower 副本是不对外提供服务的。Follower 副本不处理客户端请求,它唯一的任务就是从Leader 副本异步拉取消息,并写入到自己的提交日志中,从而实现与Leader 副本的同步。
4、controller感知到分区leader所在的broker挂了(controller可以感知到broker存活),controller会从ISR列表里选举一个broker作为leader
消费者Rebalance机制
rebalance就是说如果消费组里的消费者数量有变化或消费的分区数有变化,kafka会重新分配消费者消费分区的关系。
如下情况可能会触发消费者rebalance
- 消费组里的consumer增加或减少了
- 动态给topic增加了分区
- 有消费者宕机或者下线
- 消费组订阅了更多的topic
rebalance过程中,消费者无法从kafka消费消息,这对kafka的TPS会有影响,如果kafka集群内节点较多,比如数百个,那重平衡可能会耗时极多,所以应尽量避免在系统高峰期的重平衡发生。
消费者消费消息的offset记录机制
- 每个consumer会定期将自己消费分区的offset提交给kafka内部topic:__consumer_offsets
- 存储的格式:Key:group.id(consumerGroupId)+topic+分区号,Value 就是 offset 的值
- kafka会定期清理topic里的消息,最后就保留最新的那条数据
- kafka 默认为该 topic 创建了50个分区,分散到不同的 __consumer_offsets 分区上
- consumer消费的offset提交分区的计算公式:
hash(consumerGroupId) % __consumer_offsets主题的分区数