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
随机推荐
- 如何配置selinux
参考命令: 一.开启/关闭selinux getenforce:查看selinux运行状态 setenforce 0 :关闭selinux setenforce 1 :开启selinux 系统 ...
- c++ 归并排序
c++ 归并排序 输入输出格式 输入格式: 第11行为一个正整数NN,第22行包含NN个空格隔开的正整数a_ia i ,为你需要进行排序的数,数据保证了A_iA i 不超过1000000000 ...
- 深度总结eMMC发展史 ICMAX值得更好地期待
随着大数据.云计算.物联网等产业的发展,信息存储安全一旦受到威胁,将危害到政军.石油.化工.核能.金融等所有行业的安全.存储芯片又被称为电子产品的“粮食”,占产品成本的二成左右,尽管中国是全球最大的手 ...
- mysql语句优化原则
有时候发现数据量大的时候查询起来效率就比较慢了,学习一下mysql语句优化的原则,自己在正常写sql的时候还没注意到这些,先记录下来,慢慢一点一点的学,加油! 这几篇博客写的都可以: https:// ...
- 剖析Unreal Engine超真实人类的渲染技术Part 3 - 毛发渲染及其它
目录 四.毛发渲染 4.1 毛发的构造及渲染技术 4.1.1 毛发的构造 4.1.2 Marschner毛发渲染模型 4.1.3 毛发的间接光照 4.2 毛发的底层实现 4.3 毛发的材质解析 4.3 ...
- Excel公式中问题-记住不要忽略空格!
总结一下之前犯得愚蠢的小问题: 程序:每日报表:从DB下载数据填充到excel,包括3个sheet,sheet1:总结<模板,公式填充,数据源为sheet2,sheet3>;sheet2: ...
- python基本用法
PYTHONPATH PYTHONPATH是python moudle的搜索路径.即import xxx会从$PYTHONPATH寻找xxx. 中文编码问题 #coding=utf-8 查看导入的包的 ...
- vim /home/yuanyc/.bashrc export LC_ALL=zh_CN.UTF-8
vim /home/yuanyc/.bashrc export LC_ALL=zh_CN.UTF-8
- nginx 的信号量
参考文章:https://blog.51cto.com/5660061/2380428 nginx 中的信号量: TERM,INT 快速的结束应用程序 ,等同于 kill -9 pid QUIT 优 ...
- 个人永久性免费-Excel催化剂功能第85波-灵活便捷的批量发送短信功能(使用腾讯云接口)
微信时代的今天,短信一样不可缺席,大系统都有集成短信接口.若只是临时用一下,若能够直接在Excel上加工好内容就可以直接发送,这些假设在此篇批量群发短信功能中都为大家带来完美答案. 业务场景 不多说, ...