kafka-9 producer核心参数

生产者代码

/**
 * 需求:开发kafka生产者代码
 */
public class KafkaProducerStudyDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //准备配置属性
        Properties props = new Properties();
        //kafka集群地址
        props.put("bootstrap.servers", "node01:9092,node02:9092,node03:9092");
        //acks它代表消息确认机制   // 1 0 -1 all
        props.put("acks", "all");
        //重试的次数
        props.put("retries", 0);
        //批处理数据的大小,每次写入多少数据到topic
        props.put("batch.size", 16384);
        //可以延长多久发送数据
        props.put("linger.ms", 1);
        //缓冲区的大小
        props.put("buffer.memory", 33554432);
        props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");

        //添加自定义分区函数
        //props.put("partitioner.class","com.partitioner.MyPartitioner");

        Producer<String, String> producer = new KafkaProducer<String, String>(props);
        for (int i = 0; i < 100; i++) {

            // 这是异步发送的模式
            producer.send(new ProducerRecord<String, String>("test", Integer.toString(i), "hello-kafka-"+i), new Callback() {
                public void onCompletion(RecordMetadata metadata, Exception exception) {
                    if(exception == null) {
                        // 消息发送成功
                        System.out.println("消息发送成功");
                    } else {
                        // 消息发送失败,需要重新发送
                    }
                }

            });

            // 这是同步发送的模式
            //producer.send(record).get();
            // 你要一直等待人家后续一系列的步骤都做完,发送消息之后
            // 有了消息的回应返回给你,你这个方法才会退出来
        }
        producer.close();
    }

}

常见异常处理

常见的异常如下

  • LeaderNotAvailableException:这个就是如果某台机器挂了,此时leader副本不可用,会导致你写入失败,要等待其他follower副本切换为leader副本之后,才能继续写入,此时可以重试发送即可。如果说你平时重启kafka的broker进程,肯定会导致leader切换,一定会导致你写入报错,是LeaderNotAvailableException

  • NotControllerException:这个也是同理,如果说Controller所在Broker挂了,那么此时会有问题,需要等待Controller重新选举,此时也是一样就是重试即可

  • NetworkException:网络异常,重试即可。会根据retries的值进行数次重试,超过设置的重试次数后后抛给异常处理

    • retries:重新发送数据的次数

      • 默认为0,表示不重试
    • retry.backoff.ms:两次重试之间的时间间隔

      • 默认为100ms

提升消息吞吐量

  • buffer.memory:设置发送消息的缓冲区,默认值是33554432,就是32MB

如果发送消息出去的速度小于写入消息进去的速度,就会导致缓冲区写满,此时生产消息就会阻塞住,所以说这里就应该多做一些压测,尽可能保证说这块缓冲区不会被写满导致生产行为被阻塞住

  • compression.type

    • producer用于压缩数据的压缩类型。默认是none表示无压缩。可以指定gzip、snappy
    • 压缩最好用于批量处理,批量处理消息越多,压缩性能越好。
  • batch.size

    • producer将试图批处理消息记录,以减少请求次数。这将改善client与server之间的性能。
    • 默认是16384Bytes,即16kB,也就是一个batch满了16kB就发送出去

如果batch太小,会导致频繁网络请求,吞吐量下降;如果batch太大,会导致一条消息需要等待很久才能被发送出去,而且会让内存缓冲区有很大压力,过多数据缓冲在内存里。

  • linger.ms

    • 这个值默认是0,就是消息必须立即被发送

一般设置一个100毫秒之类的,这样的话就是说,这个消息被发送出去后进入一个batch,如果100毫秒内,这个batch满了16kB,自然就会发送出去。
但是如果100毫秒内,batch没满,那么也必须把消息发送出去了,不能让消息的发送延迟时间太长,也避免给内存造成过大的一个压力。

请求超时

  • max.request.size
    • 这个参数用来控制发送出去的消息的大小,默认是1048576字节,也就1mb
    • 这个一般太小了,很多消息可能都会超过1mb的大小,所以需要自己优化调整,把他设置更大一些(一般设置成10M)
  • request.timeout.ms
    • 这个就是说发送一个请求出去之后,他有一个超时的时间限制,默认是30秒
    • 如果30秒都收不到响应,那么就会认为异常,会抛出一个TimeoutException来让我们进行处理

ACK参数

acks参数,其实是控制发送出去的消息的持久化机制的。

很多时候看的是整体的趋势,比如当日数万用过访问趋势,丢失部分数据关系不大 ACK=0 或者1

关乎钱的金融之类,不允许丢失数据,ACK =-1或者ALL

  • acks=0

    • 生产者只管发数据到batch中,不管消息是否写入成功到broker中,直接发送下一条数据导batch中。数据丢失的风险最高,但吞吐量最大

一般用不在意数据部分丢失的时候使用。如做实时报表,折线图,饼图,丢失一些离散的数据点并不影响整体数据走势和最终呈现出的图标

  • acks=1

    • 只要leader写入成功,就认为消息成功了.
  • 默认给这个值比较合适
  • 还是可能会导致数据丢失的,如果刚写入leader,leader就挂了,此时数据必然丢了,其他的follower没收到数据副本,变成leader.
  • acks=all 或者 acks=-1

    • 这个leader写入成功以后,必须等待其他ISR中的副本都写入成功,才可以返回响应说这条消息写入成功了,此时你会收到一个回调通知.

这种方式数据最安全,但是性能最差。

  • 如果要想保证数据不丢失,得如下设置
  1. min.insync.replicas = 2
    ISR里必须有2个副本,一个leader和一个follower,最最起码的一个,不能只有一个leader存活,连一个follower都没有了。

  2. acks = -1
    每次写成功一定是leader和follower都成功才可以算做成功,这样leader挂了,follower上是一定有这条数据,不会丢失。

  3. retries = Integer.MAX_VALUE
    无限重试,如果上述两个条件不满足,写入一直失败,就会无限次重试,保证说数据必须成功的发送给两个副本,如果做不到,就不停的重试。
    除非是面向金融级的场景,面向企业大客户,或者是广告计费,跟钱的计算相关的场景下,才会通过严格配置保证数据绝对不丢失

重试乱序

  • max.in.flight.requests.per.connection
    • 每个网络连接已经发送但还没有收到服务端响应的请求个数最大值

消息重试是可能导致消息的乱序的,因为可能排在你后面的消息都发送出去了,你现在收到回调失败了才在重试,此时消息就会乱序,所以可以使用“max.in.flight.requests.per.connection”参数设置为1,这样可以保证producer必须把一个请求发送的数据发送成功了再发送后面的请求。避免数据出现乱序

示例:
设连接数为2,准备发送数据为:hive hbase spark
在这里插入图片描述

此时消费者端接收到的数据的顺序:hive spark hbase

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值