七 月
11
火曜日

Kafka一瞥

apache-kafka-logo


Kafka的原理

Kafka由 BrokerProducerConsumer 三部分组成。Producer负责发布消息,Consumer读取消息。而作为Kafka的核心,Broker以集群的形式维护着在Consumer和Producer之间收发消息的消息队列。

apache-kafka-structure

消息的交互

Kafka通过 Topic 来进行消息的交互。Topic类似于消息的类别,逻辑上即可被认为是一个队列。如,可以将和搜索相关的数据以Search的Topic名发送至Broker。在有此类数据的需求时,就通过Search这个Topic来向Broker请求数据。

Pull vs Push

是Broker将数据 Push 到Consumer还是Consumer从Broker把数据 Pull 过来?这对整个消息系统的设计会产生很大的影响。当然各方都有支持和反对的声音。但是Kafka还是选择使用Pull型的Consumer。如果以Push的方式,对于处理各式各样不同的Consumer来说会比较困难。而且Broker必须对数据流量等信息有所感知。Kafka立意于以最快的速度消费数据,如果因为一些预想不到的原因,如网络堵塞等,误判了数据的发送量,则有可能带垮Consumer。如果以Pull的方式,Consumer可以自行进行管理以适当的速率对消息进行消费。

快速的消息消费

Kafka有趣的地方在于为了使Consumer能快速从Broker读取消息的架构。简单描述一下这是如何实现的。

并行读取消息队列的问题

对于快速消费消息而言,并行读取Broker的数据是肯定的了。在“初衷”里说到多个Consumer并行读取消息队列的问题:

  • 为了避免重复发送,需要记录每条消息被哪个Consumer读走
  • 并行读取和多Consumer的读取都会破坏消息队列在写入消息时的顺序性

Kafka在设计上解决了这些问题。

Broker中消息的保存

Kafka对于每个Topic都将消息保存在一个或多个 Partition 上。每条消息都会被追加在各个Partition的末尾。由此,每个Partition就保证了消息地顺序性。下图表示了消息被追加在Topic的3个Partition的过程。

anatomy-of-a-topic

Partition是如何被使用的

总的来说Partition有两个目的:

  • 将多个服务器的消息分散(这样使得消息的保存不受限于一个服务器的容量)
  • 并行处理

Consumer以 Consumer Group 为单位读取消息。并行处理通过同一个Partition的数据,只能被同一Consumer Group中的同一Consumer消费的制约来实现,但多个Consumer Group可同时消费一个消息。下图描述了所属于两个Consumer Group的多个Consumer对消息进行并行处理的情况。可以看出,虽然Group内部是并行的,从Group之间的角度看却是传统的发布/订阅范式。

consumer-groups