Kafka生产者

生产者

创建生产者

// 创建以下三种必须的配置
private Properties kafkaProps = new Properties();
// 创建broker的地址清单,格式host:port,建议至少给两个,如果出现宕机,生产者可以继续连接
kafkaProps.put("bootstrap.servers","broker1:9092,broker2:9092");
// 指定序列化器
kafkaProps.put("key.serializer","org.apache.kafka.common.serialization.StringSerializer");
kafkaProps.put("value.serializer","org.apache.kafka.common.serialization.StringSerializer");
KafkaProducer<String, String> producer = new KafkaProducer<>(kafkaProps);

发送消息

发送消息的三种方式

  1. 发送并忘记【fire-and-forget】

    只发送,不关心是否正常到达,有时会丢失消息

  2. 同步发送

    使用send()方法发送消息,会返回Future对象,调get()方法等待,就可以知道消息是否会发送成功

  3. 异步发送

    使用send()方法发送并指定一个回调函数,都武器在返回响应时调用该函数

// 发送并忘记
ProducerRecord<Object, String> record = new ProducerRecord<>("CustomerCountry","Pecision Products","France");
try{
   producer.send(record);
}catch (Exception e){
   e.printStackTrace();
} 
// 同步发送消息
ProducerRecord<Object, String> record = new ProducerRecord<>("CustomerCountry","Pecision Products","France");
try{
   producer.send(record).get();
}catch (Exception e){
   e.printStackTrace();
} 
// 异步发送
private class DemoProducerCallback implements Callback{
    @Override
    public void onCompletion(RecordMetadata recordMetadata,Exception e){
    if (null != e){
       e.printStackTrace();
         }
     }
 }

ProducerRecord<Object, String> record = new ProducerRecord<>("CustomerCountry","Biomedical Materials","USA");
producer.send(record,new DemoProducerCallback());

生产者配置

  1. acks

    必须有多少的分区副本接受消息,才会认为消息写入为成功

    • acks=0 :生产者在成功写入消息前不会等待服务器的响应,如中间出现问题会导致消息丢失,但因无需等待,可达到较高的吞吐量
    • acks=1 :只要集群的首领节点收到消息,生产者就会收到一个来自服务器的成功响应。如果没有消息到达首领节点(首领节点死亡,正在选举),生产者会接受错误响应,并重发。如果没有收到消息的节点选举为首领,则消息丢失。吞吐量会取决于同步,异步发送
    • acks=all :当所有参与复制的节点收到全部消息时,生产者才会收到服务器的成功响应,这种模式是最安全的,但延迟也更高。
  2. buffer.memory

    设置生产者内存缓冲区的大小,生产者用它缓冲要发送到服务器的消息,若应用程序发送消息的速度大于发送到服务器的速度,则会导致send()方法阻塞,或者异常【取决于block.on.buffer.full(0.9.00版本为max.block.ms)配置,其表示在抛出异常时阻塞的时间】

  3. compression.type

    默认不压缩。其值可设置为:snappy【占用较少cpu,提供较好的性能和压缩比】、gzip【占用较高的cpu,更高的压缩比】、lz4。指定的是消息发送前的算法

  4. retries

    消费者重发消息的次数,重试之间会等待100ms【可通过retry.backoff.ms修改】

  5. bacth.size

    设置一个批次可使用内存的大小【字节数】,发送时并不是等填满才发送,所以设置过大不会造成消息延迟,只会占用大量内存,设置过小,会频繁发送,增加额外开销。

  6. linger.ms

    指定生产者在发送批次之前等待加入批次的时间。【默认只要有可用线程生产者就会把消息发送出去】

  7. client.id

    任意字符串即可,服务器用来识别消息来源,也可以用在日志和配额的指标当中

  8. max.in.flight.requests.per.connection

    生产者在收到服务器响应之前可发送的消息,值越高,占用内存越高,吞吐量越高

  9. timeout.ms request.timeout.ms metadata.fetch.timeout.ms

    timeout.ms生产者发送数据时等待服务器响应的时间 request.timeout.ms生产者获取元数据时等待服务器返回响应的时间 metadata.fetch.timeout.msbroker等待同步副本返回消息确认的时间 与acks相匹配

  10. max.block.ms

    指定调用send()方法或partitionsFor()方法获取元数据时生产者阻塞的时间,到达配置时间即抛出异常

  11. max.request.size

    控制生产者发送请求的大小

  12. receive.buffer.bytes send.buffer.bytes

    指定TCP socket接受和发送数据包的缓冲区大小。值为-1,则为操作系统默认配置。

序列化器

可使用序列化框架Avro Thrift Protobuf 等,或自定义序列化器

分区

创建ProducerRecord对象时,可指定key,也可不指定。key决定消息被写到主题哪个分区,也可做为附件信息

// 不设置key的创建方式,此时key为null
ProducerRecord<Object, String> record = new ProducerRecord<>("CustomerCountry","USA");
  • key 为null 且使用默认的分区器,分区器会使用轮询算法将消息均衡的分布到各个分区上。

  • key 不为null 且使用了默认的分区器,Kafka会使用自己的散列算法对key进行散列,进行散列会使用所有分区。

  • 只有在不改变主题分区数量的情况下,键与分区之间的映射才能保持不变,所以不要增加新分区

自定义分区器

public class BananaPartitioner implements Partitioner {
    @Override
    public int partition(String s, Object o, byte[] bytes, Object o1, byte[] bytes1, Cluster cluster) {
        return 0;
    }

    @Override
    public void close() {

    }

    @Override
    public void configure(Map<String, ?> map) {

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值