Kafka生产者消息分区机制原理剖析

目录

 

1.kafka简单介绍

2.Kafka 生产者的分区策略


1.kafka简单介绍

Kafka 是一种分布式的消息引擎系统,它的主要功能是提供一套完备的消息发布与订阅解决方案。在 Kafka 中,发布订阅的对象是主题(Topic),向主题发布消息的客户端应用程序称为生产者(Producer),而订阅这些主题消息的客户端应用程序就被称为消费者(Consumer)。生产者和消费者统称为客户端(Clients)。Kafka 的服务器端由被称为 Broker 的服务进程构成,即一个 Kafka 集群由多个 Broker 组成,Broker 负责接收和处理客户端发送过来的请求,以及对消息进行持久化。

kafka在储存消息时,会将每个主题划分成多个分区每个分区是一组有序的消息日志。生产者生产的每条消息只会被发送到一个分区中,每个分区下可以配置若干个副本,其中只能有 1 个领导者副本和 N-1 个追随者副本。生产者向分区写入消息,每条消息在分区中的位置信息由一个叫位移(Offset)的数据来表征。

Kafka 的三层消息架构

  1. 第一层是主题层,每个主题可以配置 M 个分区,而每个分区又可以配置 N 个副本。
  2. 第二层是分区层,每个分区的 N 个副本中只能有一个是领导者,对外提供服务;其他 N-1 个副本是追随者副本,只做数据冗余。
  3. 第三层是消息层,分区中包含若干条消息,每条消息的位移从 0 开始,依次递增。客户端程序只能与分区的领导者副本进行交互。

kafka集群如何保证高可用?

  • 将不同的 Broker 分散运行在不同的机器上,这样如果集群中某一台机器宕机,即使在它上面运行的所有 Broker 进程都挂掉了,其他机器上的 Broker 也依然能够对外提供服务。
  • 备份机制(Replication)Kafka 定义了两类副本:领导者副本(Leader Replica)和追随者副本(Follower Replica)。领导者副本主要负责与客户端程序进行交互;而追随者副本只是被动地追随领导者副本而已,不能与外界进行交互。即生产者总是向领导者副本写消息;而消费者总是从领导者副本读消息。对于追随者副本,它只负责向领导者副本发送请求,请求领导者把最新生产的消息发给它,这样它能保持与领导者的同步。

Kafka Broker 是如何持久化数据的?

Kafka 使用消息日志(Log)来保存数据,在 Kafka 底层,一个日志又近一步细分成多个日志段,消息被追加写到当前最新的日志段中,当写满了一个日志段后,Kafka 会自动切分出一个新的日志段,并将老的日志段封存起来,Kafka 在后台还有定时任务会定期地检查老的日志段是否能够被删除,从而实现回收磁盘空间的目的。(日志段(Log Segment)机制定期地删除消息)消息日志文件是一个只能追加写消息的物理文件。因为只能追加写入,故避免了缓慢的随机 I/O 操作,改为性能较好的顺序 I/O 写操作,这也是实现 Kafka 高吞吐量特性的一个重要手段。

 

2.Kafka 生产者的分区策略

Kafka 生产者的分区策略决定生产者将消息发送到哪个分区。Kafka 提供了默认的分区策略,同时也支持自定义分区策略。

  • 轮询策略:即顺序分配。比如一个主题下有 3 个分区,那么第一条消息被发送到分区 0,第二条被发送到分区 1,第三条被发送到分区 2,以此类推。当生产第 4 条消息时又会重新开始,即将其分配到分区 0。

轮询策略是 Kafka 默认提供的分区策略。如果未指定partitioner.class参数,那生产者程序会按照轮询的方式在主题的所有分区间均匀地“码放”消息。轮询策略它总是能保证消息最大限度地被平均分配到所有分区上。

随机策略:先计算出该主题总的分区数,然后随机地返回一个小于它的正整数。

实现随机策略版的 partition 方法:


List<PartitionInfo> partitions = cluster.partitionsForTopic(topic);
return ThreadLocalRandom.current().nextInt(partitions.size());

按消息键保序策略:Kafka 支持为每条消息定义消息键 Key。一旦消息被定义了 Key,就可以保证同一个 Key 的所有消息都进入到相同的分区里面,由于每个分区下的消息处理都是有顺序的,故这个策略被称为按消息键保序策略。

实现按消息键保序策略的 partition 方法:


List<PartitionInfo> partitions = cluster.partitionsForTopic(topic);
return Math.abs(key.hashCode()) % partitions.size();

Kafka 默认分区策略同时实现了两种策略:如果指定了 Key,那么默认实现按消息键保序策略;如果没有指定 Key,则使用轮询策略。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章