架构设计:系统间通信(29)——Kafka及场景应用(中2)

本文详细介绍了Apache Kafka的复制功能,确保消息在消费前不会丢失。Kafka通过在多个Broker上存储分区的副本,利用Leader和Follower角色保证消息一致性。此外,探讨了生产者的原理,包括如何指定分区、同步和异步发送消息,以及如何配置强一致性或弱一致性复制。实验结果显示,生产者并不直接连接Zookeeper进行协调,而是从Broker获取信息,验证了Kafka设计中避免滥用协调装置的原则。
摘要由CSDN通过智能技术生成

接上文:《架构设计:系统间通信(28)——Kafka及场景应用(中1)

4-3、复制功能

我们在上文中已经讨论了Kafka使用分区的概念存储消息,一个topic可以有多个分区它们分布在整个Kafka集群的多个Broker服务节点中,并且一条消息只会按照消息生产者的要求进入topic的某一个分区。那么问题来了:如果某个分区中的消息在被消费端Pull之前,承载该分区的Broker服务节点就因为各种异常原因崩溃了,那么在这个Broker重新启动前,消费者就无法收到消息了。

为了解决这个问题,Apache Kafka在V 0.8+版本中加入了复制功能:让topic下的每一个分区存储到多个Broker服务节点上,并由Zookeeper统一管理它们的状态。

这里写图片描述

请注意Kafka中Partition(分区)和replication(复制)是两个完全不同的概念,很多读者容易将这两个概念混淆——虽然它们都和“如何存储消息”这件事情有关:前者是说将若干条消息按照一定的规则分别存放在不同的区域,一条消息只存入一个区域(且Topic下多个分区可以存在于同一个Broker上);后者是说,为了保证消息在被消费前不会丢失,需要将某一个区域中的消息集合复制出多个副本(同一个分区的多个副本不能存放在同一个Broker上)。

Kafka将分区的多个副本分为两种角色:Leader和Follower,Leader Broker是主要服务节点,消息只会从消息生产者发送给Leader Broker,消息消费者也只会从Leader Broker中Pull消息。Follower Broker为副本服务节点,正常情况下不会公布给生产者或者消费者直接进行操作。Follower Broker服务节点将会主动从Leader Broker上Pull消息。

在这种工作机制下,Follower和Leader的消息复制过程由于Follower服务节点的性能、压力、网络等原因,它们和Leader服务节点会有一个消息差异性。当这个差异性扩大到一定的范围,Leader节点就会认为这个Follower节点再也跟不上自己的节奏,导致的结果就是Leader节点会将这个Follower节点移出“待同步副本集”ISR(in-sync replicas),不再关注这个Follower节点的同步问题。

只有当ISR中所有分区副本全部完成了某一条消息的同步过程,这条消息才算真正完成了“记录”操作。只有这样的消息才会发送给消息消费者。至于这个真正完成“记录”操作的通知是否能返回给消息生产者,完全取决于消息生产者采用的acks模式(后文会讲到)。

现在我们可以回过头看看上文中4-1-3-5小节给出的“查看Topic状态”命令以及命令结果:

# 脚本命令范例
kafka-topics.sh --describe --zookeeper 192.168.61.139:2181 --topic my_topic2

# 显示的结果
Topic:my_topic2 PartitionCount:4        ReplicationFactor:2     Configs:
        Topic: my_topic2        Partition: 0    Leader: 2       Replicas: 2,1   Isr: 2,1
        Topic: my_topic2        Partition: 1    Leader: 1       Replicas: 1,2   Isr: 1,2
        Topic: my_topic2        Partition: 2    Leader: 2       Replicas: 2,1   Isr: 2,1
        Topic: my_topic2        Partition: 3    Leader: 1       Replicas: 1,2   Isr: 1,2

以上命令行用于显示指定topic名称的基本状态信息。Partition表示分区号,Replicas表示所有副本的所在位置的Broker.id信息,Isr表示当前状态正常可以进行消息复制的副本所在位置的Broker.id信息。

那么从命令结果来看,名叫“my_topic2”的topic一共有4个数据分区,每一个分区有两个副本。其中:0号分区的Leader Broker服务节点的id为2,0号分区的两个副本分别在id为2和id为1的Broker服务节点上,且id为2和id为1的Broker上的副本状态都是正常的;同理,1号分区的Leader Broker服务节点的id为1,1号分区的两个副本分别在id为2和id为1的Broker服务节点上,且id为2和id为1的Broker上的副本状态都是正常的。。。

4-4、Kafka原理:生产者

请注意之前我们给出的Kafka集群方案的示意图,在图中消息生产者并没有连接到zookeeper协调服务,而是直接和多个Kafka Server Brokers建立了连接。和其他种类的消息队列的设计不同,在整个Kafka方案中消息生产者(Producer)会有很多重要规则的决定权,例如:

  • 消费生产者(Producer)可以决定向指定的Topic的哪一个分区(Partition)发送消息。而不是由Broker来决定。

  • 消息生产者(Producer)可以决定消息达到Kafka Broker后,Producer对消息的一致性关注到什么样的级别,又或者根本不关心消息在Broker上的一致性问题。

  • 消息生产者(Producer)可以决定是以同步方式(sync)还是异步方式(aSync)向Broker Server List发送消息。

  • 在异步方式下,消费生产者(Producer)还可以决定以什么样的间隔(周期)向Broker Server List发送消息。

  • 随机选定Broker Server List中某一个服务节点,读取当前Topic下的分区和复制表信息,并保存在本地Pool中的工作也是由消息生产者(Producer)主动完成。

  • 另外,Kafka中的消息生产者没有类似ActiveMQ中那样的事务机制(可参见文章《架构设计:系统间通信(23)——提高ActiveMQ工作性能(中)》)。这样的设计和Kafka主要的业务场景有关——用来收集各种操作日志。这样的场景对消息的可靠性要求并不高:漏掉一两条日志并不影响后端大数据平台对日志数据的分析结果;而且这样的设计大量简化了Broker的设计结构:它不需要像ActiveMQ那样专门为达成传输但还未进行commit的消息专门创建存储区域“transaction store”,并在进行了commit或者rollback操作后进行标记。这种处理机制是Apache Kafka高效性能的又一种保障。

  • Kafka中的多个消息生产者(Producer)并不需要ZooKeeper服务中的任何信息为它们协调发送过程,因为没有什么可协调的。生产者唯一需要知道的Topic有多少个分区以及每个分区,分别存在于哪些Broker上的信息都是来源于对某一个Broker的直接查询。所以Kafka集群中只剩下了Broker和Consumer需要进行协调(这个问题会在后文中进行详细讨论)。

  • 这是分布式系统建设思想中一个重要的原则——不可滥用协调装置:完成同一件工作时,协调N个参与角色要比协调N-1个参与角色耗费更多的时间和性能;所以,只协调需要

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值