Kafka接口使用
Kafka有四个核心API,它们分别是
- Producer API,它允许应用程序向一个或多个topics上发送消息记录
- Consumer API,允许应用程序订阅一个或多个topics并处理为其生成的记录流
- Streams API,它允许应用程序作为流处理器,从一个或多个主题中消费输入流并为其生成输出流,有效的将输入流转换为输出流。
- Connector API,它允许构建和运行将Kafka主题连接到现有应用程序或数据系统的可用生产者和消费者。例如,关系数据库的连接器可能会捕获对表的所有更改
作为一个消息系统,Kafka遵循了传统的方式,选择由Producer向broker push消息并由Consumer从broker pull消息。push模式很难适应消费速率不同的消费者,因为消息发送速率是由broker决定的。push模式的目标是尽可能以最快速度传递消息,但是这样很容易造成Consumer来不及处理消息,典型的表现就是拒绝服务以及网络拥塞。而pull模式则可以根据Consumer的消费能力以适当的速率消费消息。对于Kafka而言,pull模式更合适。pull模式可简化broker的设计,Consumer可自主控制消费消息的速率,同时Consumer可以自己控制消费方式——即可批量消费也可逐条消费,同时还能选择不同的提交方式从而实现不同的传输语义。
批量提交
我们知道,批量处理是一种非常有效的提升系统吞吐量的方法。在Kafka内部,消息都是以“批”为单位处理的。一批消息从发送端到接收端,是如何在Kafka中流转的呢?
Producer端
在Kafka的客户端SDK(软件开发工具包)中,Kafka的Producer只提供了单条发送的send()方法,并没有提供任何批量发送的接口。原因是,Kafka根本就没有提供单条发送的功能,是的,你没有看错,虽然它提供的API每次只能发送一条消息,但实际上,Kafka的客户端SDK在实现消息发送逻辑的时候,采用了异步批量发送的机制。
当你调用send()方法发送一条消息之后,无论你是同步发送还是异步发送,Kafka都不会立即就把这条消息发送出去。它会先把这条消息,存放在内存中缓存起来,然后选择合适的时机把缓存中的所有消息组成一批,一次性发给Broker。简单地说,就是攒一波一起发。在Kafka的服务端,也就是Broker这一端,又是如何处理这一批一批的消息呢?
Broker端
在服务端,Kafka不会把一批消息再还原成多条消息,再一条一条地处理,这样太慢了。Kafka这块儿处理的非常聪明,每批消息都会被当做一个“批消息”来处理。也就是说,在Broker整个处理流程中,无论是写入磁盘、从磁盘读出来、还是复制到其他副本这些流程中,批消息都不会被解开,一直是作为一条“批消息”来进行处理的。
消费端
在消费时,消息同样是以批为单位进行传递的,Consumer从Broker拉到一批消息后,在客户端把批消息解开,再一条一条交给用户代码处理。比如说,你在客户端发送30条消息,在业务程序看来,是发送了30条消息,而对于Kafka的Broker来说,它其实就是处理了1条包含30条消息的“批消息”而已。显然处理1次请求要比处理30次请求要快得多。
构建批消息和解开批消息分别在发送端和消费端的客户端完成,不仅减轻了Broker的压力,最重要的是减少了Broker处理请求的次数,提升了总体的处理能力。这就是Kafka用批量消息提升性能的方法。