Kafka 5:生产者发送配置

91 阅读5分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路

1.acks

acks=0: 生产者在写入消息之前不会等待任 何来自服务器的响应,容易丢消息,但是吞吐量高。 acks=1: 只要集群的首领节点收到消息,生产者会收到来自服务器的成功响应。如果消息无法到达首领节点(比如首领节点崩溃,新首领没有选举出 来),生产者会收到一个错误响应,为了避免数据丢失,生产者会重发消息。不过,如果一个没有收到消息的节点成为新首领,消息还是会丢失。默认 使用这个配置。 acks=all: 只有当所有参与复制的节点都收到消息,生产者才会收到一个来自服务器的成功响应。延迟高。

2.batch.size

当多个消息被发送同一个分区时,生产者会把它们放在同一个批次里。该参数指定了一个批次可以使用的内存大小,按照字节数计算。当批次内存 被填满后,批次里的所有消息会被发送出去。但是生产者不一定都会等到批次被填满才发送,半满甚至只包含一个消息的批次也有可能被发送。缺省 16384(16k) ,如果一条消息超过了批次的大小,会写不进去

3.linger.ms

指定了生产者在发送批次前等待更多消息加入批次的时间。它和 batch.size 以先到者为先。也就是说,一旦我们获得消息的数量够 batch.size 的数量 了,他将会立即发送而不顾这项设置,然而如果我们获得消息字节数比 batch.size 设置要小的多,我们需要“linger”特定的时间以获取更多的消息。这个设置默认为 0,即没有延迟,消息来了就直接发送,属于单条发送。设定 linger.ms=5,例如,将会减少请求数目,但是同时会增加 5ms 的延迟,但也会提升消息的吞吐量。

4.max.request.size

控制生产者发送请求最大大小。默认这个值为 1M,如果一个请求里只有一个消息,那这个消息不能大于 1M,如果一次请求是一个批次,该批次包 含了 1000 条消息,那么每个消息不能大于 1KB。注意:broker 具有自己对消息记录尺寸的覆盖,如果这个尺寸小于生产者的这个设置,会导致消息被拒 绝。这个参数和 Kafka 主机的 message.max.bytes 参数有关系。如果生产者发送的消息超过 message.max.bytes 设置的大小,就会被 Kafka 服务器拒绝。

5.buffer.memory

设置生产者内存缓冲区的大小(结合生产者发送消息的基本流程),生产者用它缓冲要发送到服务器的消息。如果数据产生速度大于向 broker 发送 的速度,导致生产者空间不足,producer 会阻塞或者抛出异常。缺省 33554432 (32M)

6.retries

发送失败时,指定生产者可以重发消息的次数(缺省 Integer.MAX_VALUE)。默认情况下,生产者在每次重试之间等待 100ms,可以通过参数 retry.backoff.ms 参数来改变这个时间间隔

7.request.timeout.ms

客户端将等待请求的响应的最大时间,如果在这个时间内没有收到响应,客户端将重发请求;超过重试次数将抛异常,默认 30 秒。

8.max.block.ms

指定了在调用 send()方法或者使用 partitionsFor()方法获取元数据时生产者的阻塞时间。当生产者的发送缓冲区已满,或者没有可用的元数据时,这些 方法就会阻塞。在阻塞时间达到 max.block.ms 时,生产者会抛出超时异常。缺省 60000ms

9.compression.type producer

用于压缩数据的压缩类型。默认是无压缩。正确的选项值是 none、gzip、snappy。压缩最好用于批量处理,批量处理消息越多,压缩性能越 好。snappy 占用 cpu 少,提供较好的性能和可观的压缩比,如果比较关注性能和网络带宽,用这个。如果带宽紧张,用 gzip,会占用较多的 cpu,但提供 更高的压缩比。

package org.example.ProducerConfig;

import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.example.config.BusiConst;

import java.util.Properties;

public class ConfigKafkaProducer {

    public static void main(String[] args) {
        //生产者三个属性必须指定(broker地址清单、key和value的序列化器)
        Properties properties = new Properties();
        properties.put("bootstrap.servers","192.168.42.111:9092");
        properties.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        properties.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        //更多发送配置(重要的)
        properties.put("acks","1"); //ack 0,1,all
        properties.put("batch.size",16384); // 一个批次可以使用的内存大小 缺省16384(16k)
        properties.put("linger.ms",Integer.MAX_VALUE); // 指定了生产者在发送批次前等待更多消息加入批次的时间,  缺省0  50ms
        properties.put("max.request.size",1 * 1024 * 1024); // 控制生产者发送请求最大大小,默认1M (这个参数和Kafka主机的message.max.bytes 参数有关系)

        //更多发送配置(非重要的)
        properties.put("buffer.memory",32 * 1024 * 1024L);//生产者内存缓冲区大小
        properties.put("retries",0); //重发消息次数
        properties.put("request.timeout.ms",30 * 1000);//客户端将等待请求的响应的最大时间 默认30秒
        properties.put("max.block.ms",60*1000);//最大阻塞时间,超过则抛出异常 缺省60000ms

        properties.put("compression.type","none"); // 于压缩数据的压缩类型。默认是无压缩 ,none、gzip、snappy

        KafkaProducer<String,String> producer = new KafkaProducer<String, String>(properties);
        try {
            ProducerRecord<String,String> record;
            try {
                //发送4条消息
                for(int i=0;i<4;i++){
                    record = new ProducerRecord<String,String>(BusiConst.HELLO_TOPIC, String.valueOf(i),"Fisher");
                    producer.send(record);
                    System.out.println(i+",message is sent");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } finally {
            producer.close();
        }
    }
}