Kafka原理——fabric1.0版本中的节点排序方法

Kafka原理

可参考Zookeeper一起理解,后续自己在项目中实现,会再来补充一些实践的内容。

Zookeeper整理:https://blog.csdn.net/yangwei256/article/details/83786917


目录

概述.... 

1 Kafka的基本原理.... 1

1.1 什么是kafka. 1

1.2 kafka有什么优点?.... 1

1.3 kafka架构由什么组成?... 1

2 kafka的成员解析、原理和工作流程.... 4

2.1 主题Topic、分区partion和偏移量offset 4

2.2 分区写入和读取消息.... 5

2.3 分区(partion)和broker集群... 6

2.4 生产者(producer) 7

2.5 消费者和消费者群体.... 8

2.6 一致性和可用性.... 10

2.7 处理消息写入.... 11

2.8 处理出问题情况.... 12

2.9 作为Kafka客户端的一致性... 14

3 Kafka问题汇总.... 16

概述

Kafka和Zookeeper是经常一起使用的,不可分割的一对好基友好朋友。详细了解Zookeeper请参考:https://blog.csdn.net/yangwei256/article/details/83786917

Kafka使用Zookeeper进行以下操作(Zookeeper在kafka中的作用):

1、选择控制器。控制器是一个Broker,负责维护所有分区的领导者(leader)/跟随者(follower)关系。当节点关闭时,控制器会告诉其他副本成为分区领导者,以替换正在消失的节点上的分区领导者。Zookeeper用于选择控制器,确保只有一个控制器,如果它崩溃,则选择一个新控制器。

2、管理集群成员资格 - 哪些Broker还活着并且是集群的一部分?这也是通过ZooKeeper管理的。

3、主题配置 - 存在哪些主题,每个主题有多少个分区,副本在哪里,谁是首选领导者,为每个主题设置了哪些配置。

4、配额管理 - 允许每个客户端读取和写入多少数据

5、ACLs(访问控制列表) - 允许读取和写入哪个主题。

6、管理老的多级别消费者(old level consummer) - 存在哪些消费者群体,谁是他们的成员以及每个群组从每个分区获得的最新偏移量。ZooKeeper是一种服务,它允许客户端访问客户端到类似树的结构,

1)树中的每个节点称为zNode
2)树中的每个zNode都有路径
3)标识.zNode类型持久和短暂
4)每个zNode将存储一个值或数据,可能是子节点
5)无法重命名 zNodes 
6)我们可以添加/删除WATCHzNode

Zookeeper在Kakfa中扮演的角色细节:

1、Kafka将元数据信息保存在Zookeeper中,但是发送给Topic本身的数据是不会发到Zk上的。

2、kafka使用zookeeper来实现动态的集群扩展,不需要更改客户端(producer和consumer)的配置。

3、broker会在zookeeper注册并保持相关的元数据(topic,partition信息等)更新。而客户端会在zookeeper上注册相关的watcher。

一旦zookeeper发生变化,客户端能及时感知并做出相应调整。这样就保证了添加或去除broker时,各broker间仍能自动实现负载均衡。

这里的客户端指的是Kafka的消息生产端(Producer)和消息消费端(Consumer)端使用zookeeper用来"发现"broker列表,以及和Topic下每个partition的leader建立socket连接并发送消息。

也就是说每个Topic的partition是由Leader角色的Broker端使用zookeeper来注册broker信息,以及监测partition leader存活性。Consumer端使用zookeeper用来注册consumer信息,其中包括consumer消费的partition列表等,同时也用来发现broker列表,并和partition leader建立socket连接,并获取消息.

 

1 Kafka的基本原理

1.1 什么是kafka

Kafka是一个分布式的,基于发布/订阅(pub-sub)的消息传递系统,具有快速,高度可扩展、高可靠的特性。

1.2 kafka有什么优点?

Kafka的分布式设计赋予它几个优点。

  1. Kafka允许大量永久或临时消费者。
  2. Kafka具有高性能、高可用性和对节点故障的弹性,并支持自动恢复。在现实世界的数据系统中,这些特性使Kafka成为大规模数据系统组件之间通信和集成的理想选择。

1.3 kafka架构由什么组成?

(1)Broker

Kafka集群包含一个或多个服务器,这种服务器被称为broker

(2)Producer(生产者)

消息生成者,负责发布消息到Kafka broker

(3)Consumer(消费者)

消息消费者,向Kafka broker读取消息的客户端。

(4)Topic(主题)

每条发布到Kafka集群的消息都有一个类别,这个类别被称为Topic。(物理上不同Topic的消息分开存储,逻辑上一个Topic的消息虽然保存于一个或多个broker上,但用户只需指定消息的Topic即可生产或消费数据而不必关心数据存于何处)。

(5)Partition(分区)

Parition是物理上的概念,每个Topic包含一个或多个Partition.

(6)Consumer Group

每个Consumer属于一个特定的Consumer Group(可为每个Consumer指定group name,若不指定group name则属于默认的group)。

kafka基本组成架构如图1所示,其中 Broker,Topic、Partion都属于kafka cluster内部的东东。

http://kafka.apache.org/images/producer_consumer.png

图1 kafka基本组成架构

Kafka集群的拓扑结构如图2所示,实际就是把图1扩展开来,包含若干Producer(可以是web前端产生的Page View,或者是服务器日志,系统CPU、Memory等),若干broker(Kafka支持水平扩展,一般broker数量越多,集群吞吐率越高),若干Consumer Group,以及一个Zookeeper集群。(关于Zookeeper可以参考另一篇介绍) Kafka通过Zookeeper管理集群配置,选举leader,以及在Consumer Group发生变化时进行rebalance。Producer使用push模式将消息发布到broker,Consumer使用pull模式从broker订阅并消费消息。

https://res.infoq.com/articles/kafka-analysis-part-1/zh/resources/0310020.png

图2 kafka集群拓扑结构

 

 

2 kafka的成员解析、原理和工作流程

2.1 主题Topic、分区partion和偏移量offset

一个主题包含多个分区,每个分区可以放在单独的机器上,允许多个使用者并行地从主题中读取。消费者也可以并行化,以便多个消费者可以从主题中的多个分区读取,从而允许非常高的消息处理吞吐量。

如何设置partition值?一个partition只能被一个消费者消费(一个消费者可以同时消费多个partition),因此,如果设置的partition的数量小于consumer的数量,就会有消费者消费不到数据。所以,推荐partition的数量一定要大于同时运行的consumer的数量。另外一方面,建议partition的数量大于集群broker的数量,这样leader partition就可以均匀的分布在各个broker中,最终使得集群负载均衡需要注意的是,kafka需要为每个partition分配一些内存来缓存消息数据,如果partition数量越大,就要为kafka分配更大的heap space。

分区中的每条消息都有一个称为其偏移量(offset)的标识符。消费者可以从特定偏移量开始读取消息,并允许从他们选择的任何偏移点读取消息,允许消费者在他们认为合适的任何时间点加入群集。鉴于这些约束,Kafka集群中的每个特定消息都包含主题(topic),分区(partion)和分区内的偏移量(offset)。结构如图2-1所示。

https://sookocheff.com/post/kafka/kafka-in-a-nutshell/log-anatomy.png

2-1 一个主题的组成图

​​​​​​​2.2 分区写入和读取消息

每个分区都是一个有序的,不可变的记录序列,不断附加到结构化的提交日志中。分区中的记录每个都分配了一个称为偏移(offset)的顺序ID号,它唯一地标识分区中的每个记录。

数据保留多久?Kafka集群持久使用可配置的保留期保存所有已发布的记录 ,无论是否已使用 。例如,如果保留策略设置为两天,则在发布记录后的两天内,它可供使用,之后将被丢弃以释放空间。Kafka的性能在数据大小方面实际上是恒定的,因此长时间存储数据不是问题。

实际上,基于每个消费者保留的唯一元数据是该消费者在日志中的偏移或位置。这种偏移由消费者控制:通常消费者在读取记录时会线性地提高其偏移量(读完一条继续读下一条),但事实上,由于该位置由消费者控制(消费者可以改变offset,从而指向不同的消息),因此它可以按照自己喜欢的任何顺序消费记录。例如,消费者可以重置为较旧的偏移量来重新处理过去的数据,或者跳到最近的记录并从“现在”开始消费。

日志中的分区有多种用途。首先,它们允许日志扩展到超出适合单个服务器的大小。每个单独的分区必须适合托管它的服务器,但主题可能有许多分区,因此它可以处理任意数量的数据。其次,它们充当了并行的单元。在图4中,生产者正在写入日志,而消费者A和B正在以不同的偏移量从日志中读取数据。

http://kafka.apache.org/20/images/log_consumer.png

图4 写入和读取消息

​​​​​​​2.3 分区(partion)和broker集群

每个broker都拥有许多分区,每个分区可以是主题的领导者(leader)或副本(replica)。消息的写入和读取都需要通过领导者,且领导者负责与副本协调更新数据。如果领导者失败,副本将作为新领导者接管。

https://sookocheff.com/post/kafka/kafka-in-a-nutshell/partitions.png

5 分区领导者和副本

​​​​​​​2.4 生产者(producer)

生产者将消息写入到领导者,同一时刻只能有一个领导者,以便每个写入可以由单独的代理和机器提供服务。在下图像中,生产者负责将消息写入到主题的分区0,而分区0复制到其他可用副本。

https://sookocheff.com/post/kafka/kafka-in-a-nutshell/producing-to-partitions.png

6、生产者写入分区

在图6中,生产者正在写入主题的分区0,分区0复制消息写入到其他broker的可用副本分区。

https://sookocheff.com/post/kafka/kafka-in-a-nutshell/producing-to-second-partition.png

7、生产者写入第二个分区。

在图7中,生产者正在写入主题的分区1,分区1复制消息写入到其他broker的可用副本分区。

由于每次是由不同的服务器即broker写入,因此整个系统的吞吐量增加。

​​​​​​​2.5 消费者和消费者群体

(1)单主题单消费者群的情况

消费者从任何单个分区读取,允许您以与消息生成类似的方式扩展消息吞吐量。消费者也可以被组织成针对给定主题的消费者群组 - 群组中的每个消费者从唯一分区读取,并且整个群组消耗来自整个主题的所有消息。如果您拥有的消费者多于分区,那么一些消费者将处于空闲状态,因为他们没有可读取的分区。如果您有比消费者更多的分区,那么消费者将从多个分区接收消息。如果您拥有相同数量的使用者和分区,则每个使用者从一个分区中按顺序读取消息。下边引用的一组图可以形象的说明情况。

     

8系列 消费者群组读取分区消息类别

(2)单个主题的多分区多消费者群

单个主题的多分区多消费者群的kafka集群如图9所示。服务器1保存分区0和3,服务器2保存分区1和2。我们有两个消费者组,A和B。A由两个消费者组成,B由四个消费者组成。消费者组A有两个两个分区的消费者 ,每个消费者从两个分区读取。另一方面,消费者组B与分区具有相同数量的消费者,并且每个消费者从一个分区中读取。

https://sookocheff.com/post/kafka/kafka-in-a-nutshell/consumer-groups.png

9 多群组的kafka集群

​​​​​​​2.6 一致性和可用性

在开始讨论一致性和可用性之前,请记住,只要您生成一个分区并从一个分区读取消息,就能保证一致性和可用性。如果您使用两个消费者从同一分区读取或使用两个生产者写入同一分区,则一致性和可用性都不能保证。

Kafka通过以下几点确保数据一致性和可用性:

(1)发送到主题分区的消息将按发送顺序附加到提交日志中。

(2)单个消费者实例将按照它们出现的顺序查看消息日志,

(3)当所有同步副本已将其应用于其日志时,消息被“提交”,

(4)任何已提交的消息都不会丢失,只要至少有一个同步副本处于活动状态。

第一和第二保证确保为每个分区保留消息排序。请注意,无法保证整个主题的消息排序。第三和第四个保证确保可以检索已提交的消息。在Kafka中,选举领导者的分区负责将收到的任何消息同步到副本。一旦副本确认了该消息,该副本就被认为是同步的。为了进一步理解这一点,让我们仔细看看写入过程中会发生什么。

​​​​​​​2.7 处理消息写入

与Kafka群集通信时,所有消息都将发送到分区的负责人。领导者负责将消息写入自己的同步副本中,并且一旦提交了该消息,负责将消息传播到不同代理上的其他副本。每个副本都确认已收到消息,现在可以同步调用。

https://sookocheff.com/post/kafka/kafka-in-a-nutshell/leader-writes-to-replicas.png

10 领导者写入副本

当集群中的每个broker都可用时,消费者和生产者可以愉快地从主题的主要分区读取和写入而不会出现问题。不幸的是,无论是领导者还是副本都可能出现问题(如宕机),我们需要处理这些情况。

​​​​​​​2.8 处理出问题情况

副本出错时会发生什么?写入将不再到达有问题的副本,它将不再接收消息,进而与领导者不同步。在下图11中,副本3不再接收来自领导者的消息。

https://sookocheff.com/post/kafka/kafka-in-a-nutshell/first-failed-replica.png

11 一个副本挂掉

当第二个副本挂掉时会发生什么?第二个副本也将不再接收消息,它也会与领导者不同步。

https://sookocheff.com/post/kafka/kafka-in-a-nutshell/second-failed-replica.png

12 二个副本挂掉

此时,只有领导者同步。在Kafka术语中,我们仍然有一个同步副本,即使该副本恰好是此分区的领导者。

如果领导者死了怎么办?我们留下了三个死亡的复制品。

https://sookocheff.com/post/kafka/kafka-in-a-nutshell/third-failed-replica.png

13 三副本都挂掉

副本1实际上仍处于同步状态 - 它无法接收任何新数据,但它与可能接收的所有内容同步。副本二缺少一些数据,副本三(第一个下降)缺少更多数据。鉴于这种状态,有两种可能的解决方案。第一个也是最简单的方案是等到领导者重新开始后再继续。一旦领导者回来,它将开始接收和写入消息,并且当副本重新联机时,它们将与领导者同步。第二种情况是选出一个Broker作为新的领导者回来。这个Broker将与现有的领导者不同步,并且在该经纪人倒闭和被选举之间所写的所有数据都将丢失。随着其他Broker的回归,他们会看到他们已经提交了新领导者不存在的消息并删除了这些消息。通过尽快选举新的领导者可能会丢弃消息但我们将最小化停机时间,因为任何新机器都可以成为领导者

退一步,我们可以查看领导者在同步副本仍然存在的情况下发生故障的情况。

https://sookocheff.com/post/kafka/kafka-in-a-nutshell/leader-fails.png

14 领导者挂掉

在这种情况下,Kafka控制器将检测领导者挂掉并从同步副本池中选出新的领导者。这可能需要几秒钟,并导致客户端出错Leader Not Available。但是,只要生产者和消费者处理这种可能性并适当地重试,就不会发生数据丢失。

​​​​​​​2.9 作为Kafka客户端的一致性

Kafka的客户端有两种:生产者和消费者。这些中的每一个都可以配置为不同的一致性级别。

对于生产者,我们有三种选择。在每条消息上,我们可以(1)等待所有同步副本以确认消息,(2)仅等待领导者确认消息,或(3)不等待确认。这些方法中的每一种都有它们的优点和缺点,系统实现者可以根据一致性和吞吐量等因素来决定系统的适当策略。

在消费者方面,我们只能读取已提交的消息(即,已经写入所有同步副本的消息)。鉴于此,我们有三种方法作为消费者提供一致性:(1)最多接收一次消息,(2至少接收一次消息,或(3)接收每个消息一次。这些方案中的每一个都值得讨论它自己的方案。

对于最多一次消息传递,消费者从分区读取数据,提交它已读取的偏移量,然后处理消息。如果消费者在提交偏移和处理消息之间崩溃,它将从下一个偏移重新开始,而不处理消息。这将导致潜在的不期望的消息丢失。

更好的选择是至少一次消息传递。对于至少一次传递,消费者从分区读取数据,处理消息,然后提交它已处理的消息的偏移量。在这种情况下,消费者可能在处理消息和提交偏移之间崩溃,并且当消费者重新启动它时将再次处理消息这会导致下游系统中出现重复消息,但不会丢失数据。

通过让消费者处理消息并将消息的输出与偏移一起提交给事务系统,可以确保一定交付。如果消费者崩溃,它可以重新读取最后提交的事务并从那里恢复处理。这不会导致数据丢失,也不会导致数据重复。然而,在实践中,这样做意味着显著降低系统的吞吐量,因为每个消息和偏移都被提交为事务。

实际上,大多数Kafka消费者应用程序至少选择一次交付,因为它提供了吞吐量和正确性之间的最佳平衡。下游系统将以自己的方式处理重复的消息。

3 Kafka问题汇总

1、该共识机制的原理是什么?

Kafka是一种分布式的、基于消息发布/订阅的消息处理模式。

2、该机制解决什么问题?

解决分布式系统中,消息的一致性和快速处理的问题。

3、该机制如何在区块链系统中应用?

Fabric1.0系统中选用该机制提高系统的吞吐量,相比0.6版本的PBFT,该机制不会随着节点的增加而降低系统吞吐量。(可以随着节点增加增加Broker的数量,虽然成本有所增加,但总比性能太差好太多)

4、该共识机制分为哪些步骤?

  1. Push过程:Producer客户端发起写入请求,Broker根据消息分类将消息写入到一个Topic中的一个Partion中。
  2. Pull过程:Consummer客户端发起访问请求,Broker根据访问消息的Topic、Partion和Offset找到对应的访问消息读取。

5、该共识机制的特征有哪些,需要满足哪些前提条件?

特征:支持多线程处理,提高系统吞吐量。

        同时提供离线处理和实时处理,达到性能和需求的平衡。

6、该共识机制的优点和缺点有哪些,与其他共识机制对比呢(最好表现在表格上)?

Kafka的分布式设计赋予它几个优点。

  1. Kafka允许大量永久或临时消费者,节点允许随时加入和退出,不影响系统。
  2. Kafka支持多线程处理,具有可水平扩展、异步通信、高性能、高可用性和对节点故障的弹性,并支持自动恢复。在现实世界的数据系统中,这些特性使Kafka成为大规模数据系统组件之间通信和集成的理想选择。

7、该共识机制的过程中可能出现哪些问题,如何处理?

  1. 在消费者获取消息时,需要让消费者处理消息并将消息的输出与偏移一起提交给事务系统,确保不会丢失未处理的消息,但这样需要再做一次事务提交,降低了系统性能。
  2. 只能对同一个Topic中同一个Partion的消息进行排序,且具有唯一性,不支持跨Partion跨Topic的排序处理。

8、该共识机制可能存在哪些攻击,该如何处理?

  1. 伪装Consummer或者Producer进行消息读取和写入。

引入安全认证,如CA等,保证节点身份可靠。

引入权限控制(Authorization):设计并实现Topic级别的权限模型。Topic的权限分为READ(从Topic拉取数据)、WRITE(向Topic中生产数据)、CREATE(创建Topic)和DELETE(删除Topic)。

Producer(或Consumer)启动后需要经过如下步骤与Broker建立安全的Socket连接,如下图所示。

(1)Producer向KDC认证身份,通过则得到TGT(票证请求票证),否则报错退出。

(2)Producer使用TGT向KDC请求Kafka服务,KDC验证TGT并向Producer返回SessionKey(会话密钥)和ServiceTicket(服务票证)。

(3)Producer使用SessionKey和ServiceTicket与Broker建立连接,Broker使用自身的密钥解密ServiceTicket,获得与Producer通信的SessionKey,然后使用SessionKey验证Producer的身份,通过则建立连接,否则拒绝连接。


引用:

1、官方文档http://kafka.apache.org/documentation/

  1. https://sookocheff.com/post/kafka/kafka-in-a-nutshell/
  2. https://zhuanlan.zhihu.com/p/37405836
  3. http://www.infoq.com/cn/articles/kafka-analysis-part-1
  4. https://blog.csdn.net/suifeng3051/article/details/48053965
  5. https://blog.csdn.net/u012501054/article/details/80241921
  6. https://ask.hellobi.com/blog/transwarp/6229
  7. https://www.jianshu.com/p/8a61bb2a9219(Zookeeper在kafka中的角色)
  8. https://www.quora.com/What-is-the-actual-role-of-Zookeeper-in-Kafka-What-benefits-will-I-miss-out-on-if-I-don%E2%80%99t-use-Zookeeper-and-Kafka-together(Zookeeper在kafka中的作用)

 

 

猜你喜欢

转载自blog.csdn.net/yangwei256/article/details/83787293