其他分享
首页 > 其他分享> > kafka之broker

kafka之broker

作者:互联网

不同broker之间的关系

Kafka使用zookeeper来维护集群成员的信息。每个broker都有一个唯一标识符,这个标识符可以在配置文件中指定,也可以自动生成。在broker启动时,它通过建立临时节点把自己的ID注册到zookeeper。kafka组件订阅broker在zookeeper上的注册路径,当有broker进入或退出集群时,这些组件就可以获得通知。
  在broker停机、出现网络分区或长时间垃圾回收停顿时,broker会从zookeeper上断开连接,此时broker在启动时创建的临时节点会自动从zookeeper上移除。监听broker列表的kafka组件会被告知该broker已移除。
  在关闭broker时,它对应的节点也会消息,不过它的iD会继续存在于其他数据结构中。例如,主题的副本列表里就可能包含这些iD。在完全关闭一个broker之后,如果使用相同的ID启动另一个全新的broker,它会立即加入集群,并拥有与旧broker相同的分区和主题。

控制器

控制器其实也是一个broker,只不过它除了具有一般broker的功能之外,还负责分区首领的选举。集群里第一个启动的broker通过在zookeeper里创建一个临时节点让自己成为控制器。其他的broker在控制器节点上创建zookeeper watch对象,这样他们就可以收到这个节点的变更通知。
  如果控制器被关闭或者与zookeeper断开连接,zookeeper上的临时节点就会消失。集群里的其他broker通过watch对象得到控制器节点消失的通知,他们尝试让自己成为新的控制器。第一个在zookeeper里成功创建控制器节点的broker成为新的控制器,其他的broker会在新的控制器节点上创建新的watch对象。每个新选出的控制器通过zookeeper的条件递增操作获得一个全新的数值更大的controller epoch。同时,控制器使用epoch来避免“脑裂”。脑裂是指两个节点同时认为自己是当前的控制器。
  当控制器发现一个broker已经离开集群(通过观察相关的zookeeper路径),它就知道,那些失去首领的分区需要一个新首领(这些分区的首领刚好是在这个broker上)。控制器遍历这些分区,并确定谁应该成为新首领,然后向所有包含新首领或者现有跟随者的broker发送请求。该请求中包含了谁是新首领以及谁是分区跟随者的信息。
  当控制器发现一个broker加入集群时,它会使用brokerID来检查新加入的broker是否包含现在分区的副本。如果有,控制器就把变更通知发送给新加入的broker和其他broker,新broker上的副本开始从首领那里复制消息。

复制

kafka使用主题来组织数据,每个主题被分为如干个分区,每个分区有多个副本。那些副本被保存在broker上,每个broker可以保存成百上千个属于不同主题和分区的副本。

副本类型

同步副本需要满足的条件

broker处理请求

kafka提供一个二进制协议,制定了请求消息的格式以及broker如何对请求作出响应。客户端发起连接和发送请求,broker按照请求到达的顺序来处理他们,这种顺序保证了kafka具有消息队列的特性,同时保证保存的消息也是有序的。
  那么broker是如何处理请求的呢?
  broker会在它所监听的每个端口上运行一个Acceptor线程,这个线程会创建一个连接,并把它交给Processor线程去处理。Processor线程(网络线程)的数量是可配置的。网络线程负责从客户端获取请求消息,把它们放进请求队列,请求消息放入请求队列后,IO线程会处理它们,并将处理结果放入响应队列,然后网络线程从响应队列中获取响应消息,把他们发送给客户端。
  生产请求和获取请求都必须发送给分区的首领副本。如果broker收到一个针对特定分区的请求,而该分区的首领在另一个broker上,那么发送请求的客户端会收到一个“非分区首领”的错误响应。同样获取请求时也会有同样的要求。kafka客户端要自己负责把生产请求和获取请求发送给正确的broker上。
  那么客户端怎么知道该往哪里发送请求呢?客户端使用了另一种请求类型,也就是元数据请求。这些请求中包含了客户端感兴趣的主题列表,以及这些主题包含的分区,每个分区都有哪些副本,以及哪个副本是首领。元数据请求可以发送给任何一个broker,因为所有broker都缓存了这些消息。
  一般情况下,客户端会把这些信息缓存起来,并直接往目标broker上发送生产请求和获取请求。客户端需要时不时地通过发送元数据请求来刷新这些信息(刷新频率可以通过metadata.max.age.ms配置)。如果客户端收到“非首领”错误,客户端在尝试重发请求之前先刷新元数据,因为这个错误说明了客户端正在使用过期的元数据信息。
  客户端从broker上获取消息时,客户端可以指定broker最多可以从一个分区里返回多少数据。这个限制非常重要的,因为客户端需要为broker返回的数据分配足够的内存。如果请求的偏移量存在,broker将按照客户端指定的数据上限从分区里返回读取消息,再把消息返回给客户端。kafka使用零复制技术向客户端发送消息—kafka直接把消息从文件里发送到网络通道,而不需要经过任何的缓冲区。客户端除了可以设置broker返回数据的上限,还可以设置下限。

分区分配

kafka的基本存储单元就是分区。分区无法在多个broker间进行再细分,也无法在同一个broker的多个磁盘上进行细分。
对于分区分配的理解,我们可以用一个实际场景来解释。例如,假设我们有6个broker,打算创建一个包含10个分区的主题,复制系数3,那么kafka就会有30个分区副本。在进行分区分配时,我们要达到如下的目标:

标签:副本,请求,首领,分区,broker,kafka,客户端
来源: https://blog.csdn.net/qq_38571892/article/details/115090201