ctrl+H
new 它的实现类
ctrl+r替换
格式化ctrl+alt+l

ctrl+f
ctrl+alt+v

替换
&lt "
&lt <
&gt >

Kafka生产者Java API

创建生产者

不带回调函数的

public class CustomProducer {
public static void main(String[] args) throws InterruptedException {
Properties properties = new Properties();
//kafka地址
properties.put("bootstrap.servers", "hadoop101:9092, hadoop102:9092, hadoop103:9092");
//acks=-1
properties.put("acks", "all");
properties.put("retries", 0);
//基于大小的批处理
properties.put(ProducerConfig.BATCH_SIZE_CONFIG, 16384);
//基于时间的批处理
properties.put("linger.ms", 1);
//客户端缓存大小
properties.put("buffer.memory", 33554432);
//k v序列化
properties.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
properties.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
Producer<String, String> producer = new KafkaProducer<String, String>(properties); for (int i = 0; i < 9; i++){
producer.send(new ProducerRecord<String, String>("first","" + i, "Hello" + i ));
}
//Thread.sleep(1000);
producer.close(); //忘记close关了,它就是基于批处理的条件( 基于大小的批处理; 基于时间的批处理,看是否达到,没有达到就不会send;) } }

 new producer<String, String>( "主题", 分区int, " key“, "value" )

带回调函数

带回调函数的producer, 每发一条消息调用一次回调函数
不管有没有发送成功

public class CustomProducerCompletion {
public static void main(String[] args) {
Properties properties = new Properties();
properties.put("bootstrap.servers", "hadoop101:9092, hadoop102:9092, hadoop103:9092");
properties.put("acks", "all");
properties.put("retries", 2);
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");
//自定义分区 ProducerConfig.PARTITIONER_CLASS_CONFIG
//properties.put("partitioner.class", "com.atguigu.kafka.producer.CustomPartitioner");
//拦截器
properties.put(ProducerConfig.INTERCEPTOR_CLASSES_CONFIG,
Arrays.asList("com.atguigu.kafka.interceptor.TimeStampInterceptor","com.atguigu.kafka.interceptor.CountInterceptor")); KafkaProducer<String, String> kafkaProducer = new KafkaProducer<String, String>(properties);
for (int i = 0; i < 9; i++){
kafkaProducer.send(new ProducerRecord<String, String>("first", "1", "Hi" + i), new Callback() {
public void onCompletion(RecordMetadata recordMetadata, Exception e) {
if (recordMetadata != null){
System.out.println("Topic:" + recordMetadata.topic() + "\t" +
"Partition:" + recordMetadata.partition() + "\t" + "offset:" + recordMetadata.offset()
);
}
}
});
}
kafkaProducer.close(); }
}

自定义分区

指定分区重写key的规则

public class CustomPartitioner implements Partitioner {
public int partition(String topic, Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster) {
return 0; //控制分区
} public void close() { } /**
* 可以添加属性
* @param config
*/
public void configure(Map<String, ?> config) { }
}

Kafka消费者Java API

高级API

不需手动管理offset

poll 超时时间
subscribe订阅主题
可同时消费多个主题
数组-Arrays.asList->集合

1) 高级API优点

高级API 写起来简单

不需要自行去管理offset,系统通过zookeeper自行管理。

不需要管理分区,副本等情况,系统自动管理。

消费者断线会自动根据上一次记录在zookeeper中的offset去接着获取数据;可以使用group来区分对同一个topic 的不同程序访问分离开来(不同的group记录不同的offset,这样不同程序读取同一个topic才不会因为offset互相影响)

2)高级API缺点

不能自行控制offset(对于某些特殊需求来说)

不能细化控制如分区、副本、zk等

//高级API
public class CustomConsumer {
public static void main(String[] args) {
Properties properties = new Properties();
//定义kafka集群地址
properties.put("bootstrap.servers", "hadoop101:9092, hadoop102:9092, hadoop103:9092");
//消费者组id
properties.put(ConsumerConfig.GROUP_ID_CONFIG, "kris");
//是否自动提交偏移量:(kafka集群管理)
properties.put("enable.auto.commit", "true");
//间隔多长时间提交一次offset
properties.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, "1000");
//key,value的反序列化
properties.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
properties.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer"); KafkaConsumer<String, String> kafkaConsumer = new KafkaConsumer<String, String>(properties);
kafkaConsumer.subscribe(Arrays.asList("first")); //订阅主题
while (true){
ConsumerRecords<String, String> records = kafkaConsumer.poll(100); //定义Consumer, poll拉数据
for (ConsumerRecord<String, String> record : records) {
System.out.println("Topic:" + record.topic() + "\t" +
"Partition:" + record.partition() + "\t" + "Offset:" +record.offset()
+ "\t" + "key:" + record.key() + "\t" + "value:" + record.value());
}
}
}
}

低级API

leader
  offset
  保存offset
消息

public class LowLevelConsumer {
public static void main(String[] args) {
//1.集群
ArrayList<String> list = new ArrayList<>();
list.add("hadoop101");
list.add("hadoop102");
list.add("hadoop103");
//2.主题
String topic = "first";
//3.分区
int partition = 2;
//4.offset
long offset = 10; //5.获取leader
String leader = getLeader(list, topic, partition);
//6.连接leader获取数据
getData(leader, topic, partition, offset); } private static void getData(String leader, String topic, int partition, long offset) {
//1.创建SimpleConsumer
SimpleConsumer consumer = new SimpleConsumer(leader, 9092, 2000, 1024 * 1024 * 2, "getData");
//2.发送请求
//3.构建请求对象FetchRequestBuilder
FetchRequestBuilder builder = new FetchRequestBuilder();
FetchRequestBuilder requestBuilder = builder.addFetch(topic, partition, offset, 1024 * 1024);
FetchRequest fetchRequest = requestBuilder.build();
//4.获取响应
FetchResponse fetchResponse = consumer.fetch(fetchRequest);
//5.解析响应
ByteBufferMessageSet messageAndOffsets = fetchResponse.messageSet(topic, partition);
//6.遍历
for (MessageAndOffset messageAndOffset : messageAndOffsets) {
long message_offset = messageAndOffset.offset();
Message message = messageAndOffset.message();
//7.解析message
ByteBuffer byteBuffer = message.payload(); //payload是有效负载
byte[] bytes = new byte[byteBuffer.limit()];
byteBuffer.get(bytes);
//8.获取数据
System.out.println("offset:" + message_offset + "\t" + "value:" + new String(bytes)); } } private static String getLeader(ArrayList<String> list, String topic, int partition) {
//1.循环发送请求,获取leader
for (String host : list) {
//2.创建SimpleConsumer对象
SimpleConsumer consumer = new SimpleConsumer(
host,
9092,
2000,
1024*1024,
"getLeader"
);
//3.发送获取leader请求
//4.构造请求TopicMetadataRequest
TopicMetadataRequest request = new TopicMetadataRequest(Arrays.asList(topic));
//5.获取响应TopicMetadataResponse
TopicMetadataResponse response = consumer.send(request);
//6.解析响应
List<TopicMetadata> topicsMetadata = response.topicsMetadata();
//7.遍历topicsMetadata
for (TopicMetadata topicMetadata : topicsMetadata) {
List<PartitionMetadata> partitionsMetadata = topicMetadata.partitionsMetadata();
//8.遍历partitionsMetadata
for (PartitionMetadata partitionMetadata : partitionsMetadata) {
//9.判断
if (partitionMetadata.partitionId() == partition){
BrokerEndPoint endPoint = partitionMetadata.leader();
return endPoint.host(); }
} } } return null;
}
}

Kafka producer拦截器

flume-事件
flume的拦截器链:
kafka-消息

每发送一条数据调用一次onSend方法
接收数据调用回调函数之前调用onAcknoeledgement

https://blog.csdn.net/stark_summer/article/details/50144591

Kafka与Flume比较

在企业中必须要清楚流式数据采集框架flume和kafka的定位是什么:

flume:cloudera公司研发:

适合多个生产者;

适合下游数据消费者不多的情况;

适合数据安全性要求不高的操作;

适合与Hadoop生态圈对接的操作。

kafka:linkedin公司研发:

适合数据下游消费众多的情况;

适合数据安全性要求较高的操作,支持replication。

因此我们常用的一种模型是:

线上数据 --> flume --> kafka --> flume(根据情景增删该流程) --> HDFS

vim flume-kafka.conf
# define
a1.sources = r1
a1.sinks = k1
a1.channels = c1 # source
a1.sources.r1.type = exec
a1.sources.r1.command = tail -F -c +0 /opt/module/datas/flume.log
a1.sources.r1.shell = /bin/bash -c # sink
a1.sinks.k1.type = org.apache.flume.sink.kafka.KafkaSink
a1.sinks.k1.kafka.bootstrap.servers = hadoop101:9092,hadoop102:9092,hadoop103:9092
a1.sinks.k1.kafka.topic = first
a1.sinks.k1.kafka.flumeBatchSize = 20
a1.sinks.k1.kafka.producer.acks = 1
a1.sinks.k1.kafka.producer.linger.ms = 1 # channel
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100 # bind
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1

tail -F动态实时  -c 0从0行开始监控

[kris@hadoop101 flume]$ bin/flume-ng agent -c conf/ -n a1 -f job/flume-kafka.conf 

[kris@hadoop101 datas]$ cat > flume.log
Hello [kris@hadoop101 kafka]$ bin/kafka-console-consumer.sh --bootstrap-server hadoop101: --topic first
Hello

Kafka-API的更多相关文章

  1. Kafka实战系列--Kafka API使用体验

    前言: kafka是linkedin开源的消息队列, 淘宝的metaq就是基于kafka而研发. 而消息队列作为一个分布式组件, 在服务解耦/异步化, 扮演非常重要的角色. 本系列主要研究kafka的 ...

  2. Kafka API操作

    Kafka API实战 环境准备 在eclipse中创建一个java工程 在工程的根目录创建一个lib文件夹 解压kafka安装包,将安装包libs目录下的jar包拷贝到工程的lib目录下,并buil ...

  3. kafka api的基本使用

    kafka API kafka Consumer提供两套Java API:高级Consumer API.和低级Consumer API. 高级Consumer API 优点: 高级API写起来简单,易 ...

  4. 一文详解Kafka API

    摘要:Kafka的API有Producer API,Consumer API还有自定义Interceptor (自定义拦截器),以及处理的流使用的Streams API和构建连接器的Kafka Con ...

  5. Kafka API: TopicMetadata

    Jusfr 原创,转载请注明来自博客园 TopicMetadataRequest/TopicMetadataResponse 前文简单说过"Kafka是自描述的",是指其broke ...

  6. 5.kafka API consumer

    1.kafka consumer流程1.1.在启动时或者协调节点故障转移时,消费者发送ConsumerMetadataRequest给bootstrap brokers列表中的任意一个brokers. ...

  7. 4.kafka API producer

    1.Producer流程首先构建待发送的消息对象ProducerRecord,然后调用KafkaProducer.send方法进行发送.KafkaProducer接收到消息后首先对其进行序列化,然后结 ...

  8. Kafka API实战

    第4章 KafkaAPI实战 1)启动zk和kafka集群,在kafka集群中打开一个消费者 [hadoop102 kafka]$ bin/kafka-console-consumer.sh \ -- ...

  9. Kafka API使用

  10. 9.Kafka API使用

随机推荐

  1. [MySQL]多表关联查询技巧

    示例表A: author_id author_name 1 Kimmy 2 Abel 3 Bill 4 Berton 示例表B: book_id author_id start_date end_da ...

  2. input错误提示,点击提交,提示有未填项,屏幕滑到input未填项的位置

    function errorInfo(parm) { //获取文本框值 var $val = parm.val(); if ($val==""||undefined||null){ ...

  3. 【进阶3-4期】深度解析bind原理、使用场景及模拟实现(转)

    这是我在公众号(高级前端进阶)看到的文章,现在做笔记  https://github.com/yygmind/blog/issues/23 bind() bind() 方法会创建一个新函数,当这个新函 ...

  4. Vue1.0到2.0变化

    一.生命周期 二.代码片段 在vue1.0中可以在template编写时出现: <template> <div>第一行</div> <div>第二行&l ...

  5. kindedit编辑器和xxs攻击防护(BeautifulSoup)的简单使用

    一.kindedit编辑器 就是上面这样的编辑输入文本的一个编辑器 这也是一个插件.那么怎么用呢? 1.下载:百度kindedit 2.引入: <script src="/static ...

  6. LeetCode(122):卖股票的最佳时机 II

    Easy! 题目描述: 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你可以尽可能地完成更多的交易(多次买卖一支股票). 注意:你不能同时参 ...

  7. cf965C 二分+推方程

    #include<bits/stdc++.h> using namespace std; #define ll long long ll n,k,M,D,anss; ll calc(ll ...

  8. 线性空间和异或空间(线性基)bzoj4004贪心+高斯消元优秀模板

    线性空间:是由一组基底构成的所有可以组成的向量空间 对于一个n*m的矩阵,高斯消元后的i个主元可以构成i维的线性空间,i就是矩阵的秩 并且这i个主元线性无关 /* 每个向量有权值,求最小权极大线性无关 ...

  9. centos--git搭建之Gogs安装

    1.下载git yum intall -y git 2. 创建git用户(必须新创建git用户, 用root用户会导致无法下载) #创建git用户 sudo adduser git #给git用户设置 ...

  10. java基础应用循环的应用

    1.1 [经典面试题]: &&(短路与)与&(非短路与)的区别: 表达式1 && 表达式2 表达式1如果为false,表达式2不执行,整个表达式结果为false ...