因为生产者、消费者都只通分区的LEADER打交道,故生产者、消费者需要从众多分区副本中找到LEADER。
一、生产者
生产者通过元数据请求,请求包含了客户端感兴趣的主题列表;服务端返回的响应指出了这些主题包含哪些分区以及每个分区的LEADER。元数据请求可以发送给任意一个broker,所有broker都缓存了这些信息。如果一个客户端发送数据请求(非元数据请求)到一个非LEADER的broker,该客户端会收到一个“非分区LEADER”的错误响应。
一般的,生产者会将分区信息缓存下来,往LEADER分区发送数据请求。不时地通过元数据请求更新(通过meta.max.age.ms配置)。另外,如果生产者收到“非分区LEADER”的错误时说明分区LEADER已经发生变化,缓存的信息已经过期故需要立即发送元数据请求得到最新的分区信息后再发送数据请求。
LEADER收到数据请求后,首先看acks是否合法,然后判断是否是all,如果是判断当前同步副本数是否满足要求,不满足则拒绝写入;写入LEADER后看acks如果是0 1则直接返回如果是all则先缓存直到分区所有副本复制完成才返回。
二、消费者
消费者也是先通过元数据请求获取分区LEADER。
发送数据请求时,包括特定主题的分区的特定偏移量如“主题A分区0的偏移量从53开始的消息和主题A分区3里的偏移量19开始的消息”以及消息数。
如果请求的偏移量存在,broker按照客户端指定的数量上限从分区读取消息返回给客户端,零复制技术。LEADER在消息还没有在被写入到所有同步副本之前是不会发给消费者即使消费者想要获取这些消息也会得到空,如果允许消费者读取未完全同步的消息将破坏一致性。等待副本复制的延迟时间可以通过replica.lag.time.max.ms配置。