Kafka科普系列 | 轻松理解Kafka中的延时操做

本文起源于以前去面试的一道面试题,面试题大体上是这样的:消费者去Kafka里拉去消息,可是目前Kafka中又没有新的消息能够提供,那么Kafka会如何处理?html

以下图所示,两个follower副本都已经拉取到了leader副本的最新位置,此时又向leader副本发送拉取请求,而leader副本并无新的消息写入,那么此时leader副本该如何处理呢?能够直接返回空的拉取结果给follower副本,不过在leader副本一直没有新消息写入的状况下,follower副本会一直发送拉取请求,而且总收到空的拉取结果,这样徒耗资源,显然不太合理。 面试

在这里插入图片描述

这里就涉及到了Kafka延迟操做的概念。Kafka在处理拉取请求时,会先读取一第二天志文件,若是收集不到足够多(fetchMinBytes,由参数fetch.min.bytes配置,默认值为1)的消息,那么就会建立一个延时拉取操做(DelayedFetch)以等待拉取到足够数量的消息。当延时拉取操做执行时,会再读取一第二天志文件,而后将拉取结果返回给follower副本。微信

延迟操做不仅是拉取消息时的特有操做,在Kafka中有多种延时操做,好比延时数据删除、延时生产等。fetch

对于延时生产(消息)而言,若是在使用生产者客户端发送消息的时候将acks参数设置为-1,那么就意味着须要等待ISR集合中的全部副本都确认收到消息以后才能正确地收到响应的结果,或者捕获超时异常。 设计

在这里插入图片描述
假设某个分区有3个副本:leader、follower1和follower2,它们都在分区的ISR集合中。为了简化说明,这里咱们不考虑ISR集合伸缩的状况。Kafka在收到客户端的生产请求后,将消息3和消息4写入leader副本的本地日志文件,如上图所示。

因为客户端设置了acks为-1,那么须要等到follower1和follower2两个副本都收到消息3和消息4后才能告知客户端正确地接收了所发送的消息。若是在必定的时间内,follower1副本或follower2副本没可以彻底拉取到消息3和消息4,那么就须要返回超时异常给客户端。生产请求的超时时间由参数request.timeout.ms配置,默认值为30000,即30s。 3d

在这里插入图片描述
在这里插入图片描述

那么这里等待消息3和消息4写入follower1副本和follower2副本,并返回相应的响应结果给客户端的动做是由谁来执行的呢?在将消息写入leader副本的本地日志文件以后,Kafka会建立一个延时的生产操做(DelayedProduce),用来处理消息正常写入全部副本或超时的状况,以返回相应的响应结果给客户端。日志

延时操做须要延时返回响应的结果,首先它必须有一个超时时间(delayMs),若是在这个超时时间内没有完成既定的任务,那么就须要强制完成以返回响应结果给客户端。其次,延时操做不一样于定时操做,定时操做是指在特定时间以后执行的操做,而延时操做能够在所设定的超时时间以前完成,因此延时操做可以支持外部事件的触发。cdn

就延时生产操做而言,它的外部事件是所要写入消息的某个分区的HW(高水位)发生增加。也就是说,随着follower副本不断地与leader副本进行消息同步,进而促使HW进一步增加,HW每增加一次都会检测是否可以完成这次延时生产操做,若是能够就执行以此返回响应结果给客户端;若是在超时时间内始终没法完成,则强制执行。htm

回顾一下文中开头的延时拉取操做,它也一样如此,也是由超时触发或外部事件触发而被执行的。超时触发很好理解,就是等到超时时间以后触发第二次读取日志文件的操做。外部事件触发就稍复杂了一些,由于拉取请求不仅仅由follower副本发起,也能够由消费者客户端发起,两种状况所对应的外部事件也是不一样的。若是是follower副本的延时拉取,它的外部事件就是消息追加到了leader副本的本地日志文件中;若是是消费者客户端的延时拉取,它的外部事件能够简单地理解为HW的增加。blog

延迟操做背后还有一些更深层次的内容,好比对于“炼狱”、“收割机”的理解,嘿嘿~~这些内容都在《深刻理解Kafka》中


欢迎支持笔者小册:《图解Kafka之实战指南》和《图解Kafka之核心原理


欢迎支持笔者新做:《深刻理解Kafka:核心设计与实践原理》和《RabbitMQ实战指南》,同时欢迎关注笔者的微信公众号:朱小厮的博客。

相关文章
相关标签/搜索