一般发送数据到Kafka,就是new一个producer,然后简单到send就好了,就可以在kafka里面看到数据了,可以使用命令行的消费模式,但是你在写测试代码的时候,想看看数据是否真的写到kafka服务器了的时候,就发现,额,好像数据没发送到kafka服务器上似的,代码也看似没问题哦。Java代码如下:
private void produceOnce(String toTopic) {
Properties conf = new Properties();
conf.setProperty(BOOTSTRAP_SERVERS_CONFIG, "192.168.1.191:9092");
conf.put(ACKS_CONFIG, "all");
conf.put(KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
conf.put(VALUE_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
KafkaProducer<String, String> producer = new KafkaProducer<>(conf);
List<String> list = Lists.newArrayList(
"aaaa","bbb"
);
for (String v : list) {
ProducerRecord<String, String> record = new ProducerRecord<>(toTopic, "k", v);
try {
//producer.send(record);
producer.send(record).get();
} catch (Exception e) {
System.out.println(e.toString());
}
}
}
注意,在使用producer发送数据的时候,有2行,一个是send(),一个send().get()。我把send给注释了,留下了带get的方法,在junit的测试方法中,使用简单的直接send,数据可能就发不到kafka去。带上get之后,就能发到kafka去。具体原因就跟这个kafka的producer的原理有关系了。
调用send方法,并不是说这个消息就会被发送到kafka服务器,他为了效率他只是把你这个消息 record暂时给发到一个队列去,等待kafka的线程来发送。可能这个线程还没好呢,junit方法的test方法已经走完了,jvm已经结束了,那个发送数据的kafka的线程也就gg了,但是get之后,他是需要等待发送的返回结果的,所以,在测试的时候,这个方法就能保证数据发到kafak服务器去了,而不是缓存在本地的队列中。
生产端ProducerRecord经过序列化器、分区器处理后,并不是直接发往broker端,而是发送到客户端的消息缓冲池(Accumulator) 中,最后交由Sender线程发往broker端。
缓冲池最大大小由参数buffer.memory控制,默认是32M,当生产消息的速度过快导致buffer满了的时候,将阻塞max.block.ms时间,超时抛异常,所以buffer的大小可以根据实际的业务情况进行适当调整。
发送到缓冲池中消息将会被分为一个一个的batch,分批次的发送到broker 端,批次大小由参数batch.size控制,默认16KB。这就意味着正常情况下消息会攒够16KB时才会批量发送到broker端,所以一般减小batch大小有利于降低消息延时,增加batch大小有利于提升吞吐量。
但是消息并不是必须要达到一个batch尺寸才会批量发送到服务端呢,Producer端提供了另一个重要参数linger.ms,用来控制batch最大的空闲时间,超过该时间的batch也会被发送到broker端。
整个流程大概分为如下几步
1、构建一个KafkaProducer对象,初始化一些用到的组件,比如缓存区,Sender线程等
2、如果配置了拦截器,可用对发送的消息进行可定制化的拦截或更改
3、对Key,value进行序列化
4、根据传入的参数,为消息选择合适的分区,具体怎么选,后面分析
5、将消息按照分区发送到RecordAccmulator暂存,消息按照每个分区进行汇总
6、后台Sender线程被触发后从RecordAccmulator里面获取消息然后构建成ClientRequest,怎么构建后面分析
7、将ClientRequest封装成NetWorkClient准备发送
8、NetWorkClient将请求放入KafkaChannel准备发送,然后执行网络IO,最后发送到kafka server
来源:oschina
链接:https://my.oschina.net/u/4387439/blog/4650830