kafka是目前市场上比较流行的消息框架。本篇文章尽力去诠释kafka模型背后的设计原理,从而更加深刻的理解kafka,在使用过程中尽可能少的入坑。

三个角色

producer:生产者。负责发送消息到kafka集群

broker:kafka集群。负责保存消息

consumer:消费者。负责消费kafka集群的消息

kafka消费者组的消费者数量怎么修改 kafka的消费者和partition_xcode

模型

topic:一个topic即一个逻辑上的主题,生产者可以生产消息到该主题,消费者则从该主题下消费消息。对于生产者和消费者而言,并不需要关心某个topic是怎么存的,存在哪台机器这些物理信息。

partition:partition是物理上的,每个topic可以有多个partition。这里引出一个问题,对于外界而言,一个topic已经足够,为什么还要设计partition这个模型

这是因为,利用partition可以做水平扩张,负载均衡。假设一个topic消息量巨大,单机支撑这个topic就会出现IO瓶颈,如果要想法去掉这个瓶颈,最简单能想到的就是将一个topic分散在多台机器,用多台机器来分散IO。所以partition的目的就是将同一个topic分散到不同机器上,从而实现水平扩展的利器。

kafka消费者组的消费者数量怎么修改 kafka的消费者和partition_kafka消费者组的消费者数量怎么修改_02

借用知乎上的一个例子:

kafka正是借用生活中的例子来设计的topic和partition。其中,不同的topic就是不同的高速公路,partition就是某条高速公路上面的车道,如果车流量大,则拓宽车道,反之,减少车道;而消费者就好比收费站,收费站越多,则通过速度越快。

kafka消费者组的消费者数量怎么修改 kafka的消费者和partition_kafka_03

consumer group:consumer group实际上就是一组consumer的集合。它的出现是基于两个需求。一,在应用消费kafka消息时,希望不会重复消费。二,有时应用需要并行消费。对于这两个看似矛盾的需求,kafka通过引入consumer group来解决了。

先看第一,如果kafka不能解决重复投递,而由每个应用去解决,则每个应用自己去实现幂等,显然是一种重复造轮子的行为。对于第二,有时数据既需要传递给离线计算又需要给在线计算。kafka规定了,同一个consumer group内部,只能有一个consumer消费某条消息;而不同的consumer group,可以同时消费某条消息。简单说,如果同一个应用有100台机器,这100台机器属于同一个consumer group,则同一条消息在100台机器中只有一台能得到。而另一个应用如果也需要同时消费同一个topic的消息,则新建一个consumer group并消费同一个topic消息。

partition和consumer group之间的关系:partition的设计初衷是通过增加partition让consumer能够并发消费,但是kafka的设计是在同一个partition上不允许并发,因此,如果consumer group中的consumer线程数量比partition多,则有的线程将得不到消息;反之,如果consumer线程数量比partition少,则有的线程将会收到多个消息,多个partition间的消息并不能保证顺序,只有同一个partition上的数据是有序的。


消息顺序

如果topic中仅分配了一个partition,kafka能够保证消息的顺序投递,并且由于同一个consumer group只有一个consumer,在消费时也能保证消息的顺序,实际上就是串行的处理消息。而如果想要保证消息的处理顺序又想要并行化的进行消息投递处理,就不得不自行在consumer端处理。当然,还有个办法,即因为可以保证局部partition消息的顺序性,只要将需要保持顺序的消息通过特定的hash编码放到特定的partition中,则该组partition消息即可保证顺序访问。


消息队列需要解决的几个难题

1. 消息的顺序性


2. 消息的重复性


3. 事务消息


(待续)