MQ(MessageQueue),Message 是跨进程传递的信息,Queue 是 FIFO(先进先出)的数据结构。
所有的 MQ 类型产品都有以下三个主要作用:
Kafka 是 MQ 的一种具体实现,它以 发布-订阅 的模式来传递消息,早期的 Kafka 的使用包括集群都需要搭配 Zookeeper,从 Kafka 4.0 开始,放弃了 Zookeeper,通过自己的 Kraft 组件实现集群管理。
Kafka 是一种可用性优先于数据安全性的 MQ 产品,并且利用了零拷贝和顺序写机制提高性能。所以其特点是:⾼吞吐量、高可用、低延迟,但是会发生也允许发生少量数据的丢失(这并不是设计缺陷,而是默认配置就是倾向于高吞吐量,可以通过更改配置来实现零数据丢失,但是会牺牲性能)。
1. Kafka 中的核心概念:
它们的关系如下:
2. 进一步细分 Kafka 中的核心概念:
进一步细分后关系如下:
图中内容解释:
图中是两个 broker 组成的 kafka 集群,两个 broker 中拥有相同的主题 topic1 和 topic2,每个主题内的消息都分散在两个分区中 partition1 和 partition2。
partition1 和 partition2 又分别被复制一份,所以一个主题下会有四个分区 partition1 Leader、partition1 Follow、partition2 Leader、partition2 Follow,
因为只有 Leader 分区才会响应客户端请求,如果把 partition1 Follow 和 partition2 Follow 放到同一个 Broker 中,会导致该 Broker 闲置,浪费性能,所以为了充分利用机器性能,partition 1 和 partition 2 的 Leader 分区被分开存放到两个 Broker 中。
3. 进一步细分 Kafka 生产者中的核心概念:
相对完整一点的 Kafka 各部件关系如下:
Kafka 采取状态信息和消息分离的设计思想,将各个 Broker 的状态信息保存在 Zookeeper 中,将消息保存在 Broker 本地。
Zookeeper 中保存的状态信息最为主要的有两个:
Controller 的选举,使用的是抢占式的方式。当集群中的 Broker 启动时,会尝试在 Zookeeper 中创建一个 /Controller 临时节点,并将自己的 brokerId 写到节点中。创建 /Controller 临时节点成功的那个 Broker 就是 Controller。
其他未成功创建的 Broker 则会监听这个 /Controller 临时节点,一旦 /Controller 临时节点被删除了,则会触发监听器,所有 Broker 会重新抢占 /Controller 临时节点。
选举产⽣的 Controller 节点,就会负责监听 Zookeeper 中的⼀些关键节点:
在 Kafka 中,一个 Topic 的所有消息,会被分开存储到不同的 Partition 中,而每个 Partition 又可以进行复制备份。在 Partition 的众多备份中,需要选举出⼀个Leader Partition,负责对接所有的客户端请求,并将消息优先保存,然后再通知其他 Follower Partition 来同步消息。
Partition Leader 的选举机制⾮常简单⾼效。在选举 Leader Partition 时,会按照 ISR(每个分区存活的副本集合) 中的排名顺序,靠前的优先选举。当选举完成后,Zookeeper 中的信息也会被及时更新,这样选举结果,就可以在所有 Broker 中达成共识。
想明白 Partition 故障恢复前,需要先明白两个概念:
有了上面的基础,就很好理解故障恢复机制。
第一种情况, Follow 节点发生了故障,这个时候其实对整个集群没有什么影响,无非就是少了一个备份,会将其踢出 ISR。 当 Follow 节点恢复时,并不会直接加入到 ISR 中,而是将高于自己本地保存的 HW 的信息全部删除,然后以本地保存的 HW 为起点对 Leader 发起同步,等到该 Follow 的 LEO >= 最新的 HW 后,才会重新加入 ISR。
第二种情况,Leader 节点发生了故障,Leader 节点会被踢出 ISR,然后从 ISR 中重新选举新的 Leader。当新的 Leader 确定后,所有 Follow 节点会将 HW 之后的消息全部删除,然后从 新 Leader 中同步。当 旧的 Leader 恢复后,将作为 Follow 节点进行数据恢复。
在 Leader 节点发生故障的这种场景下,当 HW 过小时,新 Leader 选举成功后,很有可能发生数据丢失,这是 Kafka 允许的,因为 Kafka 默认的理念就是可用性大于数据安全性。