kafka(四)拿代码说话

1、kafka生产者

三种发送方式:

       通过生产者的send方法进行发送,send方法会返回一个包含 RecordMetadata 的 Future 对象。RecordMetadata 中包含了目标主题,分区信和和消息的偏移量。

1.1 发送并忘记

       忽略send 方法的返回值,不做任何处理。大多数情况下,消息会正常到达,而且生产者会自动重试,但有时会丢失消息。

1.2 同步非阻塞发送

       获得send方法返回的 Future对象,在合适的时候调用 Future 的get 方法。

 

1.3 异步发送

   实现接口org.apache.kafka.clients.producer.Callback,然后将实现类的实例作为参数传递给 send 方法。

2、序列化机制:

       创建生产者对象必须指定序列化器,默认的序列化器在生产环境中不能满足所需要的场景,需要开发者自定义序列化器。需要实现org.apache.kafka.common.serialization.Serializer接口。

2.1 自定义序列化器常见问题:自定义的容易导致程序脆弱性。

kafka官方推荐使用Apache Avro,还有Protobuf。Avro会使用一个JSON文件作为schema来描述数据,Avro在读写时会用到这个schema,可以把这个schema内嵌在数据文件中,不管数据格式如何变动,消费者都知道如何处理数据。.。。缺点就是 内嵌的消息,自带格式,会导致消息的大小不必要的增加,消耗资源。可以使用schema注册表机制,将所有写入数据用到的schema保存在注册表中,然后消息中引用schema的标识符,读取数据的消费者程序使用这个标识符从注册表中拉取schema来反序列化。

注意:kafka本身不提供schema注册表,需要借助第三方插件。

3、cmd模拟生产者消费者:

生产者:

kafka-console-producer.bat --broker-list localhost:9092 --topic well

消费者:

kafka-console-consumer.bat --bootstrap-server localhost:9092 --topic well

kafka-console-consumer.bat --bootstrap-server localhost:9092 --topic well --from-beginning (从头开始消费)

4、Java程序

生产者(采取发送并忘记得方式) 

注意:

①这种方式最后能输出“发送成功。。。”也不一定能将消息发送到kafka

第三行的端口“properties.put("bootstrap.servers", "127.0.0.1:9092");”,在不修改server.properties前提下默认是9092,一但修改要保证端口与截图2一致。

public static void main(String[] args) {
		Properties properties = new Properties();
		properties.put("bootstrap.servers", "127.0.0.1:9092");
		properties.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
		properties.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
		KafkaProducer<String, String> producer = new KafkaProducer<String, String>(properties);
		try {
			ProducerRecord<String, String> record;
			try {
				record = new ProducerRecord<String, String>("well", "20200630", "kafka");
				producer.send(record);
				System.out.println("发送成功。。。");
			} catch (Exception e) {
				e.printStackTrace();
			}
		} finally {
			producer.close();
		}
	}

消费者 

public static void main(String[] args) {
		Properties properties = new Properties();
		properties.put("bootstrap.servers", "127.0.0.1:9092");
		properties.put("key.deserializer", StringDeserializer.class);
		properties.put("value.deserializer", StringDeserializer.class);
		properties.put("group.id", "kafka1");
		KafkaConsumer<String, String> consumer = new KafkaConsumer<String, String>(properties);
		try {
			consumer.subscribe(Collections.singletonList("well"));
			while (true) {
				ConsumerRecords<String, String> records = consumer.poll(500);
				for (ConsumerRecord<String, String> record : records) {
					System.out.println(
							record.topic() + record.partition() + record.offset() + record.key() + record.value());

				}
			}
		} finally {
			consumer.close();
		}
	}

5、更多发送配置

生产者有很多属性可以设置,大部分都有合理的默认值,无需调整。有些参数可能对内存使用,性能和可靠性方面有较大影响。可以参考org.apache.kafka.clients.producer包下的ProducerConfig类。

acks:

指定了必须要有多少个分区副本收到消息,生产者才会认为写入消息是成功的,这个参数对消息丢失的可能性有重大影响。

acks=0:生产者在写入消息之前不会等待任何来自服务器的响应,容易丢消息,但是吞吐量高。

acks=1:只要集群的首领节点收到消息,生产者会收到来自服务器的成功响应。如果消息无法到达首领节点(比如首领节点崩溃,新首领没有选举出来),生产者会收到一个错误响应,为了避免数据丢失,生产者会重发消息。不过,如果一个没有收到消息的节点成为新首领,消息还是会丢失。默认使用这个配置。

acks=all:只有当所有参与复制的节点都收到消息,生产者才会收到一个来自服务器的成功响应。延迟高。

buffer.memory

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

max.block.ms

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

retries

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

receive.buffer.bytes和send.buffer.bytes

指定TCP socket接受和发送数据包的缓存区大小。如果它们被设置为-1,则使用操作系统的默认值。如果生产者或消费者处在不同的数据中心,那么可以适当增大这些值,因为跨数据中心的网络一般都有比较高的延迟和比较低的带宽。缺省102400

batch.size

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

linger.ms

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

compression.type

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

client.id 

当向server发出请求时,这个字符串会发送给server。目的是能够追踪请求源头,以此来允许ip/port许可列表之外的一些应用可以发送信息。这项应用可以设置任意字符串,因为没有任何功能性的目的,除了记录和跟踪。

max.in.flight.requests.per.connection 

指定了生产者在接收到服务器响应之前可以发送多个消息,值越高,占用的内存越大,当然也可以提升吞吐量。发生错误时,可能会造成数据的发送顺序改变,默认是5 (修改)。

如果需要保证消息在一个分区上的严格顺序,这个值应该设为1。不过这样会严重影响生产者的吞吐量。

request.timeout.ms

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

metadata.fetch.timeout.ms

是指我们所获取的一些元数据的第一个时间数据。元数据包含:topic,host,partitions。此项配置是指当等待元数据fetch成功完成所需要的时间,否则会跑出异常给客户端

timeout.ms

此配置选项控制broker等待副本确认的最大时间。如果确认的请求数目在此时间内没有实现,则会返回一个错误。这个超时限制是以server端度量的,没有包含请求的网络延迟。这个参数和acks的配置相匹配。

max.request.size

控制生产者发送请求最大大小。假设这个值为1M,如果一个请求里只有一个消息,那这个消息不能大于1M,如果一次请求是一个批次,该批次包含了1000条消息,那么每个消息不能大于1KB。注意:broker具有自己对消息记录尺寸的覆盖,如果这个尺寸小于生产者的这个设置,会导致消息被拒绝。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值