在 Kafka 中,生产者写入消息、消费者读取消息的操作都是与leader副本进行交互的,从而实现的是一种主写主读的生产消费模型

在 Kafka 中,生产者写入消息、消费者读取消息的操作都是与 leader 副本进行交互的,从而实现的是一种主写主读的生产消费模型。数据库、Redis等都具备主写主读的功能,与此同时还支持主写从读的功能,主写从读也就是读写分离。

主写从读可以让从节点去分担主节点的负载压力,预防主节点负载过重而从节点却空闲的情况发生。但主写从读也
有 2 个很明显的缺点

  1. 数据一致性问题。

    数据从主节点转到从节点有一个延时的时间窗口,这个时间窗口会导致主从节点之间的数据不一致。

  2. 延时问题。

    类似 Redis 这种组件,数据从写入主节点到同步至从节点中的过程需要经历[网络→主节点内存→网络→从节点内存]这几个阶段,而在 Kafka 中,主从同步会比 Redis 更加耗时,它需要经历 [网络→主节点内存→主节点磁盘→网络→从节点内存→从节点磁盘]这几个阶段。对延时敏感的应用而言,主写从读的功能并不太适用。

主读从写可以均摊一定的负载却不能做到完全的负载均衡,对于数据写压力很大而读压力很小的情况,从节点只能分摊很少的
负载压力,而绝大多数压力还是在主节点上。而在 Kafka 中却可以达到很大程度上的负载均衡,而且这种均衡是在主写主读的架构上实现的

截屏2021-03-11 下午4.42.33

在 Kafka 集群中有 3 个分区,每个分区有 3 个副本,正好均匀地分布在 3 个 broker 上,每个 broker 都有消息从生产者流入; 当消费者读取消息的叫候也是从 leader 副本中读取的,每个 broker 都有消息流出到消费者。每个 broker 上的读写负载都是一样的,这就说明 Kafka 可以通过主写主读实现负载均衡。

上图展示是一种理想的部署情况,有以下几种情况会造成一定程度上的负载不均衡

  1. broker 端的分区分配不均。

    当创建主题的时候可能会出现某些 broker 分配到的分区数多而其他 broker 分配到的分区少,分配到的 leader 副本也就不均。

  2. 生产者写入消息不均。

    生产者可能只对某些 broker 中的 leader 副本进行大量的写入操作,而对其他 broker 中的 leader 副本不闻不问。

  3. 消费者消费消息不均。

    消费者可能只对某些 broker 中的 leader 副本进行大量的拉取操作,而对其他 broker 中的leader 副本不闻不问。

  4. leader 副本的切换不均。

    在实际应用中可能会由于 broker 宕机而造成主从副本的切换,或者分区副本的重分配等,这些动作都有可能造成各个 broker 中 leader 副本的分配不均。

针对第一种情况,在主题创建的时候尽可能使分区分配得均衡,Kafka 中相应的分配算法也是地追求这一目标,如果是自定义的分配,则需要注意这方面的内容。对于第二和第三种情况,主写从读也无法解决。对于第四种情况,Kafka 提供了优先副本的选举来达到 leader 副本的均衡,与此同时,也可以配合相应的监控、告警和运维平台来实现均衡的优化。

Kafka 只支持主写主读有几个优点

  1. 可以简化代码的实现逻辑,减少出错的可能
  2. 将负载粒度细化均摊,与主写从读相比,不仅负载效能更好,而且对用户可控
  3. 没有延时的影响
  4. 在副本稳定的情况下,不会出现数据不一致的情况