深入理解Kafka-生产者

56 阅读4分钟

一个正常的生产逻辑需要具备的步骤

  • 配置生产者客户端参数以及相应的生产者实例
  • 构建待发送的消息
  • 发送消息
  • 关闭生产者实例

生产者消息 productRecord<K,V>

String topic;       // 主题
Integer partition;  //分区号
Header headers;     //消息头部   kafka0.11版本引入
K key;              //键
V value;            //值
long timestamp;     // 消息时间戳

必要的参数

在Kafka生产者客户端KafkaProducer中有3个参数是必填的

bootstrap.servers: kafka集群所需的broker地址清单

key.serializer: broker端接收的消息必须以字节数组的形式存在

value.serializer: broker端接收的消息必须以字节数组的形式存在

client.id: 用来设定生产者对应的客户端id(非必填,不设置kafka会自动生成)

消息的发送

创建生产者实例和构建消息之后,就可以发送消息了。发送消息主要有三种模式:发送即忘、同步、异步

发送即忘:在发生不可重试异常时,会造成消息的丢失,这种方式的性能最高,可靠性是最差的

可重试异常(网路异常、leader不可用、不知道主题和分区异常、没有充分复制异常等)、不可重试异常(数据太大异常)

配置Retries_config参数,重试次数。

同步发送的可靠性是最高的,要么消息被发送成功,要么发送异常,性能较差(一条消息发送完了,才发送吓一跳消息)

异步发送:使用callback方式,要么发送成功,要么抛出异常

序列化

生产者需要用序列化器把对象转换为字节数组才能通过网络发送给Kafka。

分区器

消息通过send方法发送到broker的过程中,有可能需要经过拦截器(Interceptor)、序列化器(serializer)、分分区器(Partitioner)的一些列作用之后才能被真正的发往broker。

如果ProducerRecord中指定了partition字段,那么就不需要分区器的作用。

拦截器

整体架构

整个生产者客户端是由两个线程协调运行的(主线程、sender线程)。

主线程:kafkaProducer创建消息,然后通过可能的拦截器、序列化器、分区器的作用之后缓存到消息累加器(消息收集器)中。

sender线程:负责从消息收集器中获取消息并将其发送到Kafka中。

RecordAccumulator缓存的大小可以通过生产者客户端参数buffer.memory设置(默认32MB),如果生产者发送消息的速度超过发送到服务器的速度,则会导致生产者空间不足,这时候KafkaProducer的send方法调用要么被阻塞,要么抛出异常,这个取决于max.block.ms的配置(默认是60秒)

消息在网络上都是以字节形式传输的,在发送之前需要创建一块内存区域来保存对应的消息。在Kafka生产者客户端中,通过java.io.ByteBuffer实现消息内存的创建和释放。频繁的创建和释放是比较消耗资源的,为了实现资源的高效利用,消息收集器(RecordAccumulator)内部有一个bufferPool,它主要用来实现ByteBuffer的复用。不过BufferPool只针对特定大小的ByteBuffer进行管理,而其他大小的ByteBuffer不会缓存进BuferPool中。这个大小由batch.size参数来指定,默认为16KB。

重要的生产者参数

大部分参数都是合理的默认值,一般都不需要修改它们。不过了解这些参数有利于程序的可用性和性能。

  • acks

这个参数用来指定分区中必须要由多少个副本收到这条消息,之后生产者才认为这条消息是成功写入的; acks = 1;只要分区leader副本写入成功 acks = 0;生产者发送消息之后不需要等待任何服务端的响应 acks = -1或者all;生产者在纤细发送之后,需要等待ISR中所有副本都成功写入

  • max.request.size

限制生产者客户端能发送的消息的最大值(默认1MB)

  • reties和retry.backoff.ms

配置生产者重试的次数,默认为0。 retry.backoff.ms默认值是100,它主要用来设置重试之间的时间间隔,避免无效的频繁重试。

  • compression.ype

指定压缩的方式,默认是none。可配置gzip、snappy、lz4;对消息进行压缩可以极大地减少网络传输量、降低网络IO,从而提高整体性能

  • connections.max.idle.ms

这个参数用来指定在多久后关闭限制的连接,默认9分钟

  • linger.ms

指定生产者发送ProducerBatch之后等待更多消息加入消息批次的时间。默认是0.

  • receive.buffer.bytes

这个参数设置Socket接收消息缓存区的大小,默认32KB

  • send.buffer.bytes

设置socket发送消息缓冲区大小,默认128KB

  • request.timeout.ms

配置producer等待请求响应的最长时间,默认30秒