sarama架构

1.client

创建producer或consumer时,都会创建一个client与之关联,client负责获取metadata信息,并且client会启动一个backgroundMetadataUpdater,定期获取metadata。

client维护一个broker表,client在创建时,就连接到kafka broker,并启动broker的responseReceiver,用于接收kafka server返回的响应。

broker负责与kafka server的网络通信。

2. producer

  1. 数据流

    asyncProducer->topicProducer->partitionProducer->aggregator->flusher->broker

    asyncProducer:无缓冲

    topicProducer:有缓冲

    partitionProducer:有缓冲

    aggregator:无缓冲

    flusher:无缓冲

    broker:无channel,在flusher里发送。

  2. aggregator:对消息作批量聚集,一批消息最少有batch.num.messages,最多有queue.buffering.max.messages。

    flusher:每次把一批消息传递给brokerProduer。如果因为网络延时导致当前这批消息无法及时发送出去,那么就进一步导致aggregator正在做聚合的后一批消息数量堆积增多,直到达到queue.buffering.max.messages后,aggregator阻塞,然后导致上游的partitionProducer,topicProducer,asyncProducer全部阻塞。

    • kafka官方文档提到,kafka producer的消息压缩是批量压缩,即将多条消息一起压缩,相对于把每条消息单独压缩然后再拼到一起的的方式来讲,批量压缩的效果更好。但是saram的producer并没有使用实现批量压缩,仍然是对每条消息单独压缩。

3.consumer

  1. 数据流

    partitionConsumer<-brokerConsumer<-broker

  2. consumer维护一个broker与brokerConsumer的映射。

  3. partitionConsumer启动两个goroutine: dispatcher, responseFeeder。

    dispatcher:从client的meta信息中获取自己的leader(这是broker类型),并用此leader取得consumer中对应的brokerConsumer。然后将此“引用”信息发给brokerConsumer,触发brokerConsumer的subscriptionManager。

    responseFeeder:接收brokerConsumer传递回来的消息。

  4. brokerConsumer启动两个goroutine:subscriptionManager,subscriptionConsumer。

    subscriptionManager:接收新引用了该brokerConsumer的partitionConsumer对象,将新的partitionConsumer传给subscriptionConsumer。如果没有新的partitionConsumer,就传递nil。所以subscriptionConsumer是由subscriptionManager驱动的。

    subscriptionConsumer:把新关联的partitionConsumer保存起来。获取所有partitionConsumer的消息,并把消息传递给partitionConsumer的feeder,由此驱动partitionConsumer的responseFeeder被驱动执行。当该brokerConsumer的所有partitionConsumer都处理完了这个响应消息之后,brokerConsumer就检查所有partitionConsumer的处理结果,并决定是否触发partitionConsumer的dispatcher。

你可能感兴趣的:(kafka,架构,golang,sarama)