Kafka—— Java API
- 本文Kafka版本:1.0.x
一、Maven依赖
-
Maven依赖查询地址
- https://mvnrepository.com/artifact/org.apache.kafka
- http://kafka.apache.org/10/documentation.html#api
-
Producer API
<dependency> <groupId>org.apache.kafka</groupId> <artifactId>kafka-clients</artifactId> <version>1.0.2</version> </dependency>
-
Consumer API
<dependency> <groupId>org.apache.kafka</groupId> <artifactId>kafka-clients</artifactId> <version>1.0.2</version> </dependency>
-
Streams API
<dependency> <groupId>org.apache.kafka</groupId> <artifactId>kafka-streams</artifactId> <version>1.0.2</version> </dependency>
二、Java API
- API官方文档
http://kafka.apache.org/10/javadoc/index.html?org/apache/kafka/
- Producer code
/**
* @ClassName: KafkaProducerDemo
* @author: AidenBrett
* @Description: 构建一个kafka的生产者,往topic中生产数据
*/
public class KafkaProducerDemo {
public static void main(String[] args) {
//构建存放对象的Properties
Properties props = new Properties();
//指定kafka servers的地址
props.put("bootstrap.servers", "node01:9092,node02:9092,node03:9092");
/**
* 异步发送数据的模式
* 0:将数据发送给主副本分区,直接发送,不管kafka是否收到,不断的持续发送数据
* 1:将数据发送给主副本分区,等到主副本分区收到并返回1确认,再发送下一条数据
* all:将数据发送给主副本分区,等到分区的所有副本都存储该数据,并返回-1,再发送下一条数据
*/
props.put("acks", "all");
//如果发送失败,重试的次数
props.put("retries", 3);
//在满足业务要求的情况下,优先将数据缓存起来,批量发送,减少资源浪费提高效率
//每一批发送的数据量
props.put("batch.size", 16384);
//每次发送的时间间隔
props.put("linger.ms", 1);
//缓存大小
props.put("buffer.memory", 33554432);
/**
* Kafka中数据的生产以及消费的数据都是可以以key value形式存在的
* 第一种形态:只发送数据,数据作为value,如果没有key,key为空。即使key为空,也要序列化
* 第二种形态:以key value形式发送,key:1-hash分区,2-添加标记属性配置
* 生产者要将数据写入硬盘序列化
* 下面两个参数是指定key和value序列化的类
*/
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
//构建生产者对象,并加载配置
Producer<String, String> producer = new KafkaProducer<>(props);
//定义topic的名称
String topic = "topic";
//生产数据
for (int i = 0; i < 10; i++) {
producer.send(new ProducerRecord<String, String>(topic, "AidenBrett" + i));
}
//关闭连接
producer.close();
}
}
- Consumer code
/**
* @ClassName: KafkaConsumerDemo
* @author: AidenBrett
* @Description: Kafka消费者API,订阅topic,消费topic数据
*/
public class KafkaConsumerDemo {
public static void main(String[] args) {
//构建存放对象的Properties
Properties props = new Properties();
//指定kafka servers的地址
props.put("bootstrap.servers", "node01:9092,node02:9092,node03:9092");
//指定当前消费者属于哪个组
props.put("group.id", "bigdata");
//自动提交offset,kafka会自动记录当前消费者消费到哪条记录
props.put("enable.auto.commit", "true");
//自动提交offset的时间间隔
props.put("auto.commit.interval.ms", "1000");
//对key和value进行反序列化
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
//实例化一个消费者对象
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
//订阅主题
consumer.subscribe(Arrays.asList("topic"));
//拉去数据
while (true) {
//拉取数据,并指定拉取时间间隔,100ms拉取一次
ConsumerRecords<String, String> records = consumer.poll(100);
//将拉取到的所有数据进行迭代
for (ConsumerRecord<String, String> record : records) {
//获取该数据的分区
int partition = record.partition();
//获取该数据在分区中的偏移量
long offset = record.offset();
//获取key
String key = record.key();
//获取value
String value = record.value();
System.out.println(partition + "\t" + offset + "\t" + key + "\t" + value);
}
}
}
}
- 自定义分区
/**
* @ClassName: UserDefinePartition
* @author: AidenBrett
* @Description: 自定义分区
*/
public class UserDefinePartition implements Partitioner {
//返回分区编号
@Override
public int partition(String topic, Object o, byte[] bytes, Object o1, byte[] bytes1, Cluster cluster) {
//获取当前的topic总共的分区个数
Integer partNumber = cluster.partitionCountForTopic(topic);
//随机分区
Random random = new Random();
int i = random.nextInt(partNumber);
return i;
}
//关闭资源
@Override
public void close() {
}
//传递配置文件
@Override
public void configure(Map<String, ?> map) {
}
}