Kafka学习(四)-------- Kafka核心之Producer
通过https://www.cnblogs.com/tree1123/p/11243668.html 已经对consumer有了一定的了解。producer比consumer要简单一些。
一、旧版本producer
0.9.0.0版本以前,是由scala编写的旧版本producer。
入口类:kafka.producer.Producer
代码示例:
Properties properties = new Properties();
properties.put("metadata.broker.list", "kafka01:9092,kafka02:9092");
properties.put("serializer.class", "kafka.serializer.StringEncoder");
properties.put("request.requird.acks", "1");
ProducerConfig config = new ProducerConfig(properties);
Producer<String, String> producer = new Producer<String, String>(config);
KeyedMessage<String,String> msg = new KeyedMessage<String,String>("topic","hello");
Producer.send(msg);
旧版本是同步机制,等待响应。吞吐性很差。在0.9.0.0版本以后,正式下架了。
旧版本的方法:
send 发送
close 关闭
sync 异步发送 有丢失消息的可能性
二、新版本producer
旧版本producer由scala编写,0.9.0.0版本以后,新版本producer由java编写。
新版本主要入口类是:org.apache.kafka.clients.producer.KafkaProducer
常用方法:
send 实现消息发送主逻辑
close 关闭producer
metrics 获取producer的实时监控指标数据 比如发送消息的速率
Kafka producer要比consumer设计简单一些,主要就是向某个topic的某个分区发送一条消息。partitioner决定向哪个分区发送消息。用户指定key,默认的分区器会根据key的哈希值来选择分区,如果没有指定key就以轮询的方式选择分区。也可以自定义分区策略。
确定分区后,producer寻找到分区的leader,也就是该leader所在的broker,然后发送消息,leader会进行副本同步ISR。
producer会启两个线程,主线程封装ProducerRecord类,序列化后发给partitioner,然后发送到内存缓冲区。
另一个I/O线程,提取消息分batch统一发送给对应的broker。
示例代码:
Properties properties = new Properties();
properties.put("bootstrap.servers", "kafka01:9092,kafka02:9092");
properties.put("acks", "all");
properties.put("retries", 0);
properties.put("batch.size", 16384);
properties.put("linger.ms", 1);
properties.put("buffer.memory", 33554432);
properties.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
properties.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
KafkaProducer<String, String> kafkaProducer = new KafkaProducer<String, String>(properties);
for (int i = 1; i <= 600; i++) {
kafkaProducer.send(new ProducerRecord<String, String>("z_test_20190430", "testkafka0613"+i));
System.out.println("testkafka"+i);
}
kafkaProducer.close();
1、构造Properties对象,bootstrap.servers key.serializer value.serializer是必须指定的。
2、使用Properties构造KafkaProducer对象。
3、构造ProducerRecord 指定topic 分区 key value。
4、KafkaProducer的send方法发送。
5、关闭KafkaProducer。
Properties主要参数:
bootstrap.servers 和consumer一样,指定部分broker即可。而且broker端如果没有配ip地址,要写成主机名。
key.serializer value.serializer 序列化参数 一定要全类名 没有key也必须设置。
acks 三个值
0: producer完全不管broker的处理结果 回调也就没有用了 并不能保证消息成功发送 但是这种吞吐量最高
all或者-1: leader broker会等消息写入 并且ISR都写入后 才会响应,这种只要ISR有副本存活就肯定不会丢失,但吞 吐量最低。
1: 默认的值 leader broker自己写入后就响应,不会等待ISR其他的副本写入,只要leader broker存活就不会丢失,即保证了不丢失,也保证了吞吐量。
buffer.memory 缓冲区大小 字节 默认是33554432 就是发送消息的内存缓冲区大小 过小的话会影响吞吐量
compression.type 设置是否压缩消息 默认值是none 压缩后可以降低IO开销提高吞吐,但是会增大CPU开销。
支持三种: GZIP Snappy LZ4 性能 LZ4 > Snappy > GZIP
retries 发送消息重试的次数 默认0 不重试 重试可能造成重复发送 可能造成乱序
retry.backoff.ms 设置重试间隔 默认100毫秒
batch.size 调优重要的参数 batch小 吞吐量也会小 batch大 内存压力会大 默认值是16384 16KB
linger.ms 发送延时 默认是0 0的话不用等batch满就发送 延时的话可以提高吞吐 看具体情况进行调整
max.request.size producer能够发送最大消息的大小 默认1048576字节 如果消息很大 需要修改它
request.timeout.ms 发送请求后broker在规定时间返回 默认30秒 超过就是超时了。
Send方法
fire and forget 就是上边的示例
Properties properties = new Properties();
properties.put("bootstrap.servers", "kafka01:9092,kafka02:9092");
properties.put("acks", "all");
properties.put("retries", 0);
properties.put("batch.size", 16384);
properties.put("linger.ms", 1);
properties.put("buffer.memory", 33554432);
properties.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
properties.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
KafkaProducer<String, String> kafkaProducer = new KafkaProducer<String, String>(properties);
for (int i = 1; i <= 600; i++) {
kafkaProducer.send(new ProducerRecord<String, String>("z_test_20190430", "testkafka0613"+i));
System.out.println("testkafka"+i);
}
kafkaProducer.close();
异步回调 不阻塞
Properties properties = new Properties();
properties.put("bootstrap.servers", "kafka01:9092,kafka02:9092");
properties.put("acks", "all");
properties.put("retries", 0);
properties.put("batch.size", 16384);
properties.put("linger.ms", 1);
properties.put("buffer.memory", 33554432);
properties.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
properties.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
KafkaProducer<String, String> kafkaProducer = new KafkaProducer<String, String>(properties);
for (int i = 1; i <= 600; i++) {
kafkaProducer.send(new ProducerRecord<String, String>("z_test_20190430", "testkafka0613"+i),new Callback(){
public void onCompletion(RecordMetadata metadata, Exception e) {
if(e != null) {
e.printStackTrace();
} else {
System.out.println("The offset of the record we just sent is: " + metadata.offset());
}
}
});
System.out.println("testkafka"+i);
}
kafkaProducer.close();
同步发送 无限等待返回
producer.send(record).get()
重试机制
如果需要自定义重试机制,就要在回调里对不同异常区别对待,常见的几种如下:
可重试异常
LeaderNotAvailableException :分区的Leader副本不可用,这可能是换届选举导致的瞬时的异常,重试几次就可以恢复
NotControllerException:Controller主要是用来选择分区副本和每一个分区leader的副本信息,主要负责统一管理分区信息等,也可能是选举所致。
NetWorkerException :瞬时网络故障异常所致。
不可重试异常
SerializationException:序列化失败异常
RecordToolLargeException:消息尺寸过大导致。
示例代码:
producer.send(myRecord,
new Callback() {
public void onCompletion(RecordMetadata metadata, Exception e) {
if(e ==null){
//正常处理逻辑
System.out.println("The offset of the record we just sent is: " + metadata.offset());
}else{
if(e instanceof RetriableException) {
//处理可重试异常
......
} else {
//处理不可重试异常
......
}
}
}
});
分区机制
partitioner决定向哪个分区发送消息。用户指定key,默认的分区器会根据key的哈希值来选择分区,如果没有指定key就以轮询的方式选择分区。也可以自定义分区策略。
对于有key的消息,java版本的producer自带的partitioner会根据murmur2算法计算消息key的哈希值。然后对总分区数求模得到消息要被发送到的目标分区号。
自定义分区策略:
创建一个类,实现org.apache.kafka.clients.producer.Partitioner接口
主要分区逻辑在Partitioner.partition中实现:通过topic key value 一同确定分区
在构造KafkaProducer得Properties中设置partitioner.class 为自定义类 注意是全类名
序列化机制
常用的serializer
ByteArraySerializer.class
ByteBufferSerializer.class
BytesSerializer.class
DoubleSerializer.class
IntegerSerializer.class
LongSerializer.class
StringSerializer.class
但是其他一些复杂的就需要自定义序列化:
1、定义数据格式
2、创建自定义序列化类,实现org.apache.kafka.common.serialization.Serializer接口
3、在KafkaProducer的Properties中设置key.serializer value.serializer为自定义类
以上均为单线程的情况,但producer是线程安全的,单线程适合分区较少的情况,分区较多可以多线程但对内存损耗较大。
我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan
Kafka学习(四)-------- Kafka核心之Producer的更多相关文章
- kafka学习(三)-kafka集群搭建
kafka集群搭建 下面简单的介绍一下kafka的集群搭建,单个kafka的安装更简单,下面以集群搭建为例子. 我们设置并部署有三个节点的 kafka 集合体,必须在每个节点上遵循下面的步骤来启动 k ...
- kafka学习(四)-Topic & Partition
topic中partition存储分布 Topic在逻辑上可以被认为是一个queue.每条消费都必须指定它的topic,可以简单理解为必须指明把这条消息放进哪个queue里.为了使得 Kafka的吞吐 ...
- kafka学习(四)
集群成员关系 kafka使用Zookeeper 来维护集群成员的信息.每个broker都有一个唯一标识符,这个标识符可以在配置里指定,也可以自动生成.在broker启动的时候,它通过创建临时节点把自己 ...
- Kafka学习之四 Kafka常用命令
Kafka常用命令 以下是kafka常用命令行总结: 1.查看topic的详细信息 ./kafka-topics.sh -zookeeper 127.0.0.1:2181 -describe -top ...
- Kafka学习(学习过程记录)
Apache kafka 这,仅是我学习过程中记录的笔记.确定了一个待研究的主题,对这个主题进行全方面的剖析.笔记是用来方便我回顾与学习的,欢迎大家与我进行交流沟通,共同成长.不止是技术. Kafka ...
- KafKa——学习笔记
学习时间:2020年02月03日10:03:41 官网地址 http://kafka.apache.org/intro.html kafka:消息队列介绍: 近两年发展速度很快.从1.0.0版本发布就 ...
- Kafka学习(二)
作者:程序员cxuan链接:https://www.zhihu.com/question/53331259/answer/1262483551来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非 ...
- Kafka 学习翻译 - 介绍
Kafka是一个分布式的流式平台.可以从几个方面理解: 1. 三个重要的能力: 能够实现流式的发布和订阅数据,类似于消息队列或者企业级的消息分发系统. 能够在提供一定容错性和持久性能力的基础上存储数据 ...
- kafka 学习(二--前言)
kafka 现在在企业应用和互联网项目中的应用越来越多了,本篇文章就从 kafka 的基础开始带你一展 kafka 的宏图 1. 什么是 Kafka Kafka 是一个分布式流式平台,它有三个关键能力 ...
- kafka 学习资料
kafka 学习资料 kafka 学习资料 网址 kafka 中文教程 http://orchome.com/kafka/index
随机推荐
- python 基础学习笔记(3)--列表与元组
**本次笔记主要内容为 列表,元组主要的功能和特性** **1.列表**: 学习过c语言的同学应该知道,c语言有数组这一功能,就是将数据类型相同的元素放在一起.由于python的变量没有数据类型,也就 ...
- 深扒那些艺术的CSS
概览 使用单个div做css绘图,会充分利用到: before.after伪元素 使用border-radius.border来控制图形的形状. 使用叠加的box-shadow来创建多个相同的形状(可 ...
- 并发编程-concurrent指南-交换机Exchanger
java.util.concurrent包中的Exchanger类可用于两个线程之间交换信息.可简单地将Exchanger对象理解为一个包含两个格子的容器,通过exchanger方法可以向两个格子中填 ...
- JS高级程序设计第3章--精简版
前言:纯手打!!!按照自己思路重写!!!这次是二刷了,想暑假做一次完整的笔记,但用本子来写笔记的话太贵了,可能哪天还丢了..所以还是博客好== 第三章:基本概念(语法.数据类型.流控制语句.函数) 3 ...
- 【POJ - 2676】Sudoku(数独 dfs+回溯)
-->Sudoku 直接中文 Descriptions: Sudoku对数独非常感兴趣,今天他在书上看到了几道数独题: 给定一个由3*3的方块分割而成的9*9的表格(如图),其中一些表格填有1- ...
- Lockey的沙雕低错集锦(未完待续~自己提升用)
(嘿嘿 (^~ ^)) 1. bitset<2100>a[2100] a[x]|=(1<<x) (1<=x<=2100) 使用时忘了x的范围,额,应 ...
- MFC开发--截图工具
近期学习了MFC的相关知识,MFC(Microsoft Foundation Classes)是微软公司提供的一个类库,可以这样简单理解,就是对于Win32的封装(MFC对windows API函数的 ...
- 比赛:小奔的矩形solution
分析: 交叉相乘,然后除以最大公因数(为了减少爆常数的可能性std做了两次,数据很大),得到的两个数相加减二就是答案 代码: var p,q,n,m,a,b,i:int64; begin readln ...
- EF简介及CRUD简单DEMO
一.实体框架(Entity FrameWork)简介 • 简称EF • 与Asp.Net MVC关系与ADO.NET关系 • ADO.NET Entity FrameWork是微软以ADO.NET为基 ...
- matlab考试重点详解
此帖是根据期末考试复习重点补充完成, 由于使用word编辑引用图片和链接略有不便, 所以开此贴供复习及学习使用.侵删 复习要点 第一章 Matlab的基本概念,名称的来源,基本功能,帮助的使用方法 1 ...