Kafka 四

元数据请求:

因为kafka所有的请求都必须经过分区首领,但是分区首领(因为建立了分区副本)是分布在不同的broker上面的,所以生产者在发送消息之前必须获取分区的元数据信息。这就是元数据请求。这种请求包含了客户端感兴趣的主题列表。服务器端的响应消息里指明了这些主题所包含的分区、每个分区都有哪些副本, 以及哪个副本是首领。元数据请求可以发送给任意一个 broker ,因为所有 broker 都缓存了这些信息。

一般情况下,客户端会把这些信息缓存起来,并直接往目标 broker 上发送生产请求和获取请求。它们需要时不时地通过发送元数据请求来刷新这些信息(刷新的时间间隔通metadata.max.age.ms参数来配置),从而知道元数据是否发生了变更一一比如,在新broker 加入集群时,部分副本会被移动到新 broker 上。另外,如果客户端收到“非首领”错误,它会在尝试重发请求之前先刷新元数据,因为这个错误说明了客户端正在使用过期的元数据信息,之前的请求被发到了错误的 broker上。

生产者请求:

生产者在获取到元数据信息后,将消息发送到包含首领副本的broker上,通过配置acks来判断是否我们写入成功,不同的acks的写入成功是不样的。之后,消息被写入本地磁盘。在 Linux 系统上,消息会被写到文件系统缓存里,并不保证它们何时会被刷新到磁盘上。Kafka不会一直等待数据被写到磁盘上一一它依赖复制功能来保证消息的持久性。

如果消息的acks被设置为all,那么需要所有同步副本收到消息才算写入成功。请求会被保存在一个叫做炼狱的缓冲区里,直到首领发现所有的跟随者副本都复制了消息,才会给客户端响应。

获取请求(消费者):

消费者可以指定分区和offset来对消息进行消费,同时也可以指定消费消息的上限大小和下限。分区首领获取到请求后会先检查请求是否有效,比如偏移量在分区上是否存在等等。如果请求的偏移量存在,broker将按照客户端指定的数量上限从分区里读取消息,再把消息返回给客户端。Kafka使用零复制技术向客户端发送消息——也就是说,Kafka直接把消息从文件(或者更准确的说是从liunx文件系统缓存)里发送到网络通道,而不需要进过任何中介缓冲区。

并不是所有的消息都可以被消费者消费的,只有哪些同步到了所有同步副本中的消息才能被消费者消费。消息同步的延迟时间可以通过参数replica.lag.time.max.ms来配置,它指定了副本在复制消息时可被允许的最大延迟时间。

同步副本是指持续请求首领副本并得到最新消息的副本。在首领发生失效时,只有同步副本才有可能被选为新首领。

同步副本的要求:

与Zookeeper之间有一个活跃的会话,也就是说,它在过去的6s(可配置)内向Zookeeper 发送过心跳。

在过去的10s 内(可配置)从首领那里获取过消息。

在过去的10s内从首领那里获取过最新的消息。光从首领那里获取消息是不够的,它还必须是几乎零延迟的。



猜你喜欢

转载自blog.csdn.net/yidan7063/article/details/80810777