本关任务:使用 Kafka 命令创建一个副本数量为1
、分区数量为3
的 Topic 。
为了完成本关任务,你需要掌握:1.如何使用 Kafka 的常用命令。
课程视频《Kafka简介》
类 JMS 消息队列,结合 JMS 中的两种模式,可以有多个消费者主动拉取数据,在 JMS 中只有点对点模式才有消费者主动拉取数据。
Kafka 是一个生产-消费模型。
Producer :消息生产者,就是向 Kafka Broker 发消息的客户端。
Consumer :消息消费者,向 Kafka Broker 取消息的客户端。
Topic :我们可以理解为一个队列。
Consumer Group (CG):这是 Kafka 用来实现一个 Topic 消息的广播(发给所有的 Consumer )和单播(发给任意一个 Consumer )的手段。一个 Topic 可以有多个CG。Topic 的消息会复制(不是真的复制,是概念上的)到所有的 CG ,但每个 Partion 只会把消息发给该 CG 中的一个 Consumer 。如果需要实现广播,只要每个 Consumer 有一个独立的 CG 就可以了。要实现单播只要所有的 Consumer 在同一个 CG。用CG 还可以将 Consumer 进行自由的分组而不需要多次发送消息到不同的 Topic。
Broker :一台 Kafka 服务器就是一个 Broker 。一个集群由多个Broker组成。一个 Broker 可以容纳多个 Topic。
Partition :为了实现扩展性,一个非常大的 Topic 可以分布到多个Broker(即服务器)上,一个 Topic 可以分为多个 Partition ,每个 Partition 是一个有序的队列。Partition 中的每条消息都会被分配一个有序的 Id( Offset )。Kafka 只保证按一个 Partition 中的顺序将消息发给 Consumer ,不保证一个 Topic 的整体(多个 Partition间)的顺序。
Offset :Kafka 的存储文件都是按照 Offset . index 来命名,用Offset 做名字的好处是方便查找。例如你想找位于2049
的位置,只要找到 2048 . index 的文件即可。当然 the first offset 就是 00000000000 . index。
Kafka 中发布订阅的对象是 Topic。我们可以为每类数据创建一个 Topic ,把向 Topic 发布消息的客户端称作 Producer ,从 Topic 订阅消息的客户端称作 Consumer 。Producers 和 Consumers 可以同时从多个 Topic 读写数据。一个 Kafka 集群由一个或多个 Broker 服务器组成,它负责持久化和备份具体的 Kafka 消息。
bin/kafka-topics.sh --list --zookeeper zk01:2181
./kafka-topics.sh --create --zookeeper zk01:2181 --replication-factor 1 --partitions 3 --topic first
说明:replication-factor
是指副本数量,partitions
是指分区数量
bin/kafka-topics.sh --delete --zookeeper zk01:2181 --topic test
需要 server.properties
中设置 delete.topic.enable = true
否则只是标记删除或者直接重启。kafka-console-producer.sh --broker-list kafka01:9092 --topic demo
bin/kafka-console-consumer.sh --zookeeper zk01:2181 --from-beginning --topic test1
kafka-run-class.sh kafka.tools.ConsumerOffsetChecker --zookeeper zk01:2181 --group testGroup
kafka-topics.sh --topic test --describe --zookeeper zk01:2181
说明 :此处的 zk01
是 Zookeeper 的 IP 地址, kafka01
是 Broker 的 IP 地址
根据提示,在右侧编辑器补充代码完成以下任务。
1
、分区数量为3
、名为 demo
的 Topicdemo
的 Topic 的详情信息注意:Broker 的 IP 为127.0.0.1,Zookeeper 的 IP 为127.0.0.1
扩展任务:
demo
的 Topic 进行数据生产demo
的 Topic进行消费说明:扩展任务没有进行评测,此任务目的是为了让用户体验下 Kafka 的数据生产与数据消费的两个环节,更好理解 Kafka
平台会对你的命令进行检验并运行,你只需要按照任务需求,补充右侧编辑器的代码,然后点击评测就ok了。 - -
特别注意:为了确保运行拥有一个正常的运行环境,请在评测之前,重置下运行环境
命令行代码
kafka-server-start.sh /opt/kafka_2.11-1.1.0/config/server.properties
shell
文件
#!/bin/bash
#1.创建一个副本数量为1、分区数量为3、名为 demo 的 Topic
kafka-topics.sh --create --zookeeper 127.0.0.1:2181 --replication-factor 1 --partitions 3 --topic demo
#2.查看所有Topic
kafka-topics.sh --list --zookeeper 127.0.0.1:2181
#3.查看名为demo的Topic的详情信息
kafka-topics.sh --topic demo --describe --zookeeper 127.0.0.1:2181
本关任务:编写一个 Kafka 的 Producer 进行数据生产。
为了完成本关任务,你需要掌握:1.如何使用 Kafka 的 Producer API 进行数据生产。
课程视频《使用Python生产消费kafka的数据》
Producer 采用默认分区方式将消息散列的发送到各个分区当中。
创建配置文件对象 Properties props = new Properties();
设置连接 Kakfa 的基本参数,如下:
props.put("bootstrap.servers", "kafka-01:9092,kafka-02:9092,kafka-03:9092");
props.put("acks", "1");
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
创建 Kafka 生产者对象Producer
发送消息producer.send(new ProducerRecord
名称 | 说明 | 默认值 | 有效值 | 重要性 |
---|---|---|---|---|
bootstrap.servers | kafka集群的broker-list,如: hadoop01:9092,hadoop02:9092 | 无 | 必选 | |
key.serializer | key的序列化器 | ByteArraySerializer StringSerializer | 必选 | |
value.serializer | value的序列化器 | ByteArraySerializer StringSerializer | 必选 | |
acks | 确保生产者可靠性设置,有三个选项: acks=0:不等待成功返回 acks=1:等Leader写成功返回 acks=all:等Leader和所有ISR中的Follower写成功返回,all也可以用-1代替 | -1 | 0,1,-1,all | 建议必选 |
buffer.memory | Producer总体内存大小 | 33554432 | 不要超过物理内存,根据实际情况调整 | 建议必选 |
batch.size | 每个partition的未发送消息大小 | 16384 | 根据实际情况调整 | 建议必选 |
根据提示,在右侧编辑器补充代码,使用 Kafka Producer API 对名为 demo
的 Topic 进行数据生产。
平台会对你的命令进行检验并运行,你只需要按照任务需求,补充右侧编辑器的代码,然后点击评测就ok了。 - -
用 conf/server.properties
,如果用 config/server.properties
的话需要把 log.dirs
和 num.partitions
这两个配置改了
cd $KAFKA_HOME/
vim config/server.properties
# 使用 :/log.dirs 找到位置,或者直接 :$ 在最后一行加
log.dirs=/export/servers/logs/kafka/
num.partitions=2
命令行执行代码
# kafka 依赖 zookeeper,所以需要先启动 zookeeper 服务
cd $ZOOKEEPER_HOME/
bin/zkServer.sh start conf/zoo.cfg
# 启动 Kafka 服务
cd $KAFKA_HOME/
bin/kafka-server-start.sh -daemon conf/server.properties
Java
代码
package net.educoder;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;
import java.util.Properties;
/**
* kafka producer 简单模式
*/
public class App {
public static void main(String[] args) {
/**
* 1.创建配置文件对象,一般采用 Properties
*/
/**----------------begin-----------------------*/
Properties props = new Properties();
/**-----------------end-------------------------*/
/**
* 2.设置kafka的一些参数
* bootstrap.servers --> kafka的连接地址 127.0.0.1:9092
* key、value的序列化类 -->org.apache.kafka.common.serialization.StringSerializer
* acks:1,-1,0
*/
/**-----------------begin-----------------------*/
props.put("bootstrap.servers", "127.0.0.1:9092");
props.put("acks", "1");
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
/**-----------------end-------------------------*/
/**
* 3.构建kafkaProducer对象
*/
/**-----------------begin-----------------------*/
Producer<String, String> producer = new KafkaProducer<>(props);
/**-----------------end-------------------------*/
for (int i = 0; i < 100; i++) {
ProducerRecord<String, String> record = new ProducerRecord<>("demo", i + "", i + "");
/**
* 4.发送消息
*/
/**-----------------begin-----------------------*/
producer.send(record);
/**-----------------end-------------------------*/
}
producer.close();
}
}
本关任务:编写一个 Kafka 消费者并设置自动提交偏移量进行数据消费。
为了完成本关任务,你需要掌握:1.如何编写 Kafka 消费者,2.如何使用自动提交偏移量。
创建配置文件对象 Properties props = new Properties();
设置连接 Kakfa 的基本参数,如下:
//设置kafka集群的地址
props.put("bootstrap.servers", 127.0.0.1:9092");
//设置消费者组,组名字自定义,组名字相同的消费者在一个组
props.put("group.id", "g1");
//开启offset自动提交
props.put("enable.auto.commit", "true");
//自动提交时间间隔
props.put("auto.commit.interval.ms", "1000");
//序列化器
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
创建 Kafka 消费者对象 KafkaConsumer
订阅主题 Topic consumer.subscribe(Arrays.asList("demo"));
消费 Topic 的数据
while (true) {
ConsumerRecords<String, String> records = consumer.poll(100);
for (ConsumerRecord<String, String> record : records)
System.out.printf("offset = %d, key = %s, value = %s%n", record.offset(), record.key(), record.value());
}
消费者拉取数据之后自动提交偏移量,不关心后续对消息的处理是否正确。
使用 Kafka Consumer API 对名为 demo
的 Topic
进行消费,并设置自动提交偏移量。
平台会对你的命令进行检验并运行,你只需要按照任务需求,补充右侧编辑器的代码,然后点击评测就 ok 了。 - -
package net.educoder;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import java.util.Arrays;
import java.util.Properties;
public class App {
public static void main(String[] args) {
Properties props = new Properties();
/**--------------begin----------------*/
//1.设置kafka集群的地址
props.put("bootstrap.servers", "127.0.0.1:9092");
//2.设置消费者组,组名字自定义,组名字相同的消费者在一个组
props.put("group.id", "g1");
//3.开启offset自动提交
props.put("enable.auto.commit", "true");
//4.自动提交时间间隔
props.put("auto.commit.interval.ms", "1000");
//5.序列化器
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
/**---------------end---------------*/
/**--------------begin----------------*/
//6.创建kafka消费者
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
//7.订阅kafka的topic
consumer.subscribe(Arrays.asList("demo"));
/**---------------end---------------*/
int i = 1;
while (true) {
/**----------------------begin--------------------------------*/
//8.poll消息数据,返回的变量为crs
ConsumerRecords<String, String> crs = consumer.poll(100);
for (ConsumerRecord<String, String> cr : crs) {
System.out.println("consume data:" + i);
i++;
}
/**----------------------end--------------------------------*/
if (i > 10) {
return;
}
}
}
}
本关任务:编写一个 Kafka 消费者并使用手动提交偏移量进行数据消费。
为了完成本关任务,你需要掌握:1.如何编写 Kafka 消费者,2.如何手动提交偏移量。
异步模式下,提交失败也不会尝试提交。消费者线程不会被阻塞,因为异步操作,可能在提交偏移量操作结果未返回时就开始下一次拉取操作。
同步模式下,提交失败时一直尝试提交,直到遇到无法重试才结束。同步方式下,消费者线程在拉取消息时会被阻塞,直到偏移量提交操作成功或者在提交过程中发生错误。
注意:实现手动提交前需要在创建消费者时关闭自动提交,设置enable.auto.commit=false
根据提示,在右侧编辑器补充代码,使用 Kafka Producer API 对名为 demo
的 Topic 进行数据生产
平台会对你的命令进行检验并运行,你只需要按照任务需求,补充右侧编辑器的代码,然后点击评测就ok了。 - -
命令行代码
# kafka 依赖 zookeeper,所以需要先启动 zookeeper 服务
cd $ZOOKEEPER_HOME/
bin/zkServer.sh start conf/zoo.cfg
# 启动 Kafka 服务
cd $KAFKA_HOME/
bin/kafka-server-start.sh -daemon conf/server.properties
Java
代码
package net.educoder;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
public class App {
public static void main(String[] args){
Properties props = new Properties();
/**-----------------begin------------------------*/
//1.设置kafka集群的地址
props.put("bootstrap.servers", "127.0.0.1:9092");
//2.设置消费者组,组名字自定义,组名字相同的消费者在一个组
props.put("group.id", "g1");
//3.关闭offset自动提交
props.put("enable.auto.commit", "false");
//4.序列化器
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
/**-----------------end------------------------*/
/**-----------------begin------------------------*/
//5.实例化一个消费者
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
//6.消费者订阅主题,订阅名为demo的主题
consumer.subscribe(Arrays.asList("demo"));
/**-----------------end------------------------*/
final int minBatchSize = 10;
List<ConsumerRecord<String, String>> buffer = new ArrayList<>();
while (true) {
ConsumerRecords<String, String> records = consumer.poll(100);
for (ConsumerRecord<String, String> record : records) {
buffer.add(record);
}
if (buffer.size() >= minBatchSize) {
for (ConsumerRecord bf : buffer) {
System.out.printf("offset = %d, key = %s, value = %s%n", bf.offset(), bf.key(), bf.value());
}
/**-----------------begin------------------------*/
//7.手动提交偏移量
consumer.commitSync();
/**-----------------end------------------------*/
buffer.clear();
return;
}
}
}
}