消息中间件--02. Kafka架构

几个概念

broker:集群中的每一台服务器,称为Broker

topic或者subject:队列名

partition:一个队列中的消息可以存储到多台broker上面,一个broker中的分区,称为partition

kafka的架构

消息队列的流程从生产者生产消息,通过TCP协议的网络请求发送到Kafka集群,然后Consumers来进行消费,具体如下图:

Kafka架构

其中生产者和消费者都相当于客户端。

Topic/Log/Partition

Topic是一个类别的名称,所有的Message都发送到Topic下面。对于每一个topic,都会有一个或者多个Partition.具体的写入方式如下

Kafka架构

partition 也可以看成一个有序的Message序列,这个message按顺序追加到一个叫commit log的文件。

kafka的消息生产流程

当生产者通过TCP协议向kafka服务器发送消息的时候,kafka会选择对应的Partition, 选择机Partition制有三种:

  1. 根据partitionId进行选择
  2. 没有partitionId,则根据key的haskValue来选择
  3. 没有id和key的情况下,会采用round-robin方式做简单的负载

    根据partition找到Broker机器群,找到集群中的leader节点,顺序写入消息

    Kafka架构

    注意:Kafka的读写都在leader上面,与zookeeper不同。

    Broker收到消息后顺序写入对应的partition文件中,同时由其他的follower同步到硬盘中。

    注意:每个broker都是自己所管理的partition的leader,同时又是其他broker所管理partitions的followers,kafka通过这种方式来达到负载均衡。

kafka的消费

传统的消息的传递模式有2种,队列(queuing)和(publish-subscribe)。在queuing模式中,多个consumer从服务器中读取消息,消息只会到达一个Consumer。publish-subcribe模型中,消息会广播给所有的consumer。Kafka基于这2个模型提供了一个Consumer group概念。

每个Consumer都有一个自己归属的Group,发布到topic中的message中的message会被传递到consumer group 中的一个consumer实例。Consumer的实例可以运行在不同的进程上,也可以运行在不同的物理机器上。消费者结构如下图:

Kafka架构

消费的顺序保证

在传统的消息队列中,消息按照先后顺序进入队列。然后由多个消费者进行消费,如果多个Consumer存在异步的情况,则会导致先取到的消息后消费,导致消费的顺序无法保证。

这个场景说明,多个Consumer并行进行消费的时候,消息在多个消费之间可能会失去顺序性。

在Kafka中, 为了保证Consumer的并行性和顺序性,采用了一个topic下的一个partition只能由一个Consumer group下的一个实例来消费。这样就保证了一个partition只有个一个消费者,从而保证了顺序性和并发性。

但是也同样会带来一个问题,如果消费者数量多于partirion的话,就会有消费者空闲。,从而造成资源的浪费。

Kafka的文件机制

所以,kafka的最合理的分配机制是partition与consumer的成倍数关系,而且一个partition只能被一个消费者消费。

局部有序和全局有序

上面的说的有序是针对一个消费者在一个partition的中的有序,并不是指全局的有序。 如果kafka想实现全局的有序,一个topic只有一个partition。但全局有序,在实际的业务场景中非常的少,局部有序就能够满足绝大部分要求。