kafka作为一个消息中间件,和所有中间件一样,都需要解决两个问题:
- 单点问题
- 性能问题
我们可以参考AKF模型,看看kafka是如何做的。
- 在Y轴上,按服务功能划分,kafka是通过topic来实现的。不同的业务使用不同的topic。
- 在Z轴上,做数据分区,kafka中每个topic都可以有一到多个partition,一个业务的数据(tpoic上的)可以分散存储到多个partition中。数据散列到多个分区是为了提高处理的并发度。在处理数据的时候,有一点需要注意:
- 无关的数据(数据之间没有关联关系)可以分散到不同的分区里,以追求最大的并发度。
- 有关联的数据,一定要按原有的顺序发送到同一个分区里,保证消息处理的顺序。 在kafka中,分区内部是有序的,分区和分区之间的数据是无序的。
- 在X轴上,为了保证数据不会丢失,每份数据都需要做备份,在实际开发中,创建patition的时候可以指定副本数量。一般有副本的话,可以做读写分离,例如MySQL。但做读写分离容易出现一致性问题,在kafka中,只能在主Patition上进行读写。
下图是kafka的结构图:
从图中可以看到,Topic A 有两个Partition,Partition 0和Partition 1。每个Partition都有一个对应的副本,分布在不同的Broker中。
kafka Broker的Partition保存了Producer发送过来的数据。数据才是重点,在kafka中,数据是可以重复利用的。在数据消费层面,有消费组的概念,不同的消费组维护各自的offset(消息的偏移量)。如下图所示:
以下图说明一下topic->partition->offset之间的关系。下图中的topic有三个分区,每个分区的偏移量都从0开始,不同分区之间的偏移量都是独立的,不会相互影响。