一、实验目的
1.了解 Kafka 的各个组件的功能
2.掌握 Kafka 的安装部署
3.了解 Kafka Java API 的使用
4.理解 Kafka Java API 中的 Producer API 与 Consumer API
二、实验要求
1. Kafka 安装部署。 Kafka 安装依赖 Scala、ZooKeeper,所以需要先安装
Scala 与 ZooKeeper。然后在已安装好 Scala 和 ZooKeeper 的环境基础上,安装
部署 Kafka。
2.使用 Kafka Java API。 使用简单 Java API 来模拟 Kafka 的 producer 和
consumer,其中 producer 是通过一个 while 循环生成内容,然后将内容传递给
Kafka,consumer 从 Kafka 中读取内容,并在 Console 界面中输出。
3.(选做)在自己的电脑中安装部署好 Kafka 环境。
三、实验过程及结果记录
(一)Kafka 安装部署
1.首先在 Linux 本地,新建/data/kafka1 目录,用于存放实验所需文件。
1. mkdir -p /data/kafka1
切换目录到/data/kafka1 下,使用 wget 命令,下载所需安装包 scala-
2.10.4.tgz,kafka_2.10-0.8.2.2.tgz 以及 zookeeper-3.4.5-
cdh5.4.5.tar.gz。
1. cd /data/kafka1
2. wget http://172.16.103.12:60000/allfiles/kafka1/scala-
2.10.4.tgz
3. wget http://172.16.103.12:60000/allfiles/kafka1/kafka_2.10-
0.8.2.2.tgz
4. wget http://172.16.103.12:60000/allfiles/kafka1/zookeeper-
3.4.5-cdh5.4.5.tar.gz
2.安装 Scala。
切换到/data/kafka1 目录下,将 Scala 安装包 scala-2.10.4.tgz 解压到/apps
目录下,并将解压后的目录,重命名为 scala。
1. cd /data/kafka1
2. tar -xzvf /data/kafka1/scala-2.10.4.tgz -C /apps/
3. cd /apps
4. mv /apps/scala-2.10.4/ /apps/scala
使用 vim 打开用户环境变量。
1. sudo vim ~/.bashrc
将以下 Scala 的路径信息,追加到用户环境变量中。1. #scala
2. export SCALA_HOME=/apps/scala
3. export PATH=$SCALA_HOME/bin:$PATH
执行 source 命令,使环境变量生效。
1. source ~/.bashrc
3.切换到/data/kafka1 目录下,将 kafka 的压缩包 kafka_2.10-0.8.2.2.tgz
解压到/apps 目录下,并将解压缩后的目录,重命名为 kafka。
1. cd /data/kafka1
2. tar -xzvf /data/kafka1/kafka_2.10-0.8.2.2.tgz -C /apps/
3. cd /apps
4. mv /apps/kafka_2.10-0.8.2.2/ /apps/kafka
使用 vim 打开用户环境变量。
1. sudo vim ~/.bashrc
将以下 Kafka 的路径信息,追加到用户环境变量中。
1. #kafka
2. export KAFKA_HOME=/apps/kafka
3. export PATH=$KAFKA_HOME/bin:$PATH
执行 source 命令,使环境变量生效。
1. source ~/.bashrc
4.由于 Kafka 的部分数据需要存储到 ZooKeeper 中,所以必须额外安装
ZooKeeper,或使用 Kafka 安装包自带的 ZooKeeper 程序。
首先来演示使用外置的 ZooKeeper 程序。
将/data/kafka1 目录下 zookeeper-3.4.5-cdh5.4.5.tar.gz,解压缩到/apps
目录下,并将解压缩的目录,重命名为 zookeeper。
1. cd /data/kafka1
2. tar -xzvf /data/kafka1/zookeeper-3.4.5-cdh5.4.5.tar.gz -C
/apps/ 3. cd /apps
4. mv /apps/zookeeper-3.4.5-cdh5.4.5/ /apps/zookeeper
使用 vim 打开用户环境变量。
1. sudo vim ~/.bashrc
将以下 Zookeeper 的路径信息,追加到用户环境变量中。
1. #zookeeper
2. export ZOOKEEPER_HOME=/apps/zookeeper
3. export PATH=$ZOOKEEPER_HOME/bin:$PATH
执行 source 命令,使环境变量生效。
1. source ~/.bashrc
修改 ZooKeeper 的配置文件,将 ZooKeeper 配置为单机模式。
切换到 ZooKeeper 的配置文件所在目录/apps/zookeeper/conf 下,将
zoo_sample.cfg 重命名为 zoo.cfg
1. cd /apps/zookeeper/conf/
2. mv /apps/zookeeper/conf/zoo_sample.cfg
/apps/zookeeper/conf/zoo.cfg
使用 vim 打开 zoo.cfg 文件,并修改 dataDir 项内容
1. vim zoo.cfg
由:
1. dataDir=/tmp/zookeeper
改为:
1. dataDir=/data/tmp/zookeeper-outkafka/data
这里的/data/tmp/zookeeper-outkafka/data 目录需要提前创建。
1. mkdir -p /data/tmp/zookeeper-outkafka/data 启动 ZooKeeper,并查看 ZooKeeper 的运行状态。
1. cd /apps/zookeeper/bin
2. ./zkServer.sh start
3. ./zkServer.sh status
关闭 ZooKeeper。
1. cd /apps/zookeeper/bin
2. ./zkServer.sh stop
5.使用 Kafka 内置的 ZooKeeper,切换目录到/apps/kafka/config 目录下。
1. cd /apps/kafka/config
这里放置着与 ZooKeeper 的配置文件 zoo.cfg 功能相似的配置文件
zookeeper.properties,使用 vim 打开 zookeeper.properties 配置文件。
1. vim zookeeper.properties
将 dataDir 目录修改为/data/tmp/zookeeper-inkafka/data 目录。
1. dataDir=/data/tmp/zookeeper-inkafka/data
这里的/data/tmp/zookeeper-inkafka/data 目录,须提前创建。
1. mkdir -p /data/tmp/zookeeper-inkafka/data
下面启动 ZooKeeper 服务,切换目录到/apps/kafka 目录下,在 kafka 的 bin
目录下放有 ZooKeeper 的启动脚本,按 Ctrl+c 退出。
1. cd /apps/kafka
2. bin/zookeeper-server-start.sh config/zookeeper.properties &
末尾的&符号,会将 zookeeper-server-start.sh 放到后台执行。输入 jps
1. jps
查看 ZooKeeper 的进程 QuorumPeerMain1. zhangyu@8461bfd6a537:/apps/kafka$ jps
2. 375 Jps
3. 293 QuorumPeerMain
4. zhangyu@8461bfd6a537:/apps/kafka$
下面关闭 ZooKeeper 进程
1. cd /apps/kafka
2. bin/zookeeper-server-stop.sh stop
6.以上两种 ZooKeeper 的使用方式,可以根据自己需要进行选择。后续课程,
我们会默认使用外置的 ZooKeeper,对 Kafka 数据进行管理。
至此 Kafka 已安装完毕。
接下来对 Kafka 进行测试,检测是否可以正常运行。
7.切换到/apps/zookeeper 目录下,启动 ZooKeeper 服务。
1. cd /apps/zookeeper
2. bin/zkServer.sh start
8.切换到/apps/kafka/config 目录下,这里放置了 Kafka 的相关的配置文件。
使用 vim 打开 Kafka 服务的配置文件 server.properties。
1. cd /apps/kafka/config
2. vim server.properties
server.properties 文件中的配置项包括:服务器基本配置,socket 服务设
置,log 日志的配置,log 刷新策略,log 保留策略,ZooKeeper 配置。
服务器基本配置,主要包括当前节点的编号。
ZooKeeper 配置中,包括 ZooKeeper 服务的 IP 和端口号等。
我们修改 zookeeper.connect 项的值为:
1. zookeeper.connect=localhost:2181
这里的 IP 和端口,是 ZooKeeper 发送接收消息使用的端口。IP 必须为
ZooKeeper 服务的 IP,我们设置为 localhost,端口必须和
/apps/zookeeper/conf 下 zoo.cfg 中的 clientPort 端口一致。9.切换目录到/apps/kafka 目录下,启动 Kafka 服务。启动 Kafka 服务时,会
读取 Kafka 配置文件目录下的 server.properties 文件。
1. cd /apps/kafka
2. bin/kafka-server-start.sh config/server.properties &
这样启动了 Kafka 的 server,并在后端运行。
10.另外开启一个窗口,调用/apps/kafka/bin 目录下 kafka-topic.sh 脚本创
建一个 topic。
1. cd /apps/kafka
2. bin/kafka-topics.sh \
3. --create \
4. --zookeeper localhost:2181 \
5. --replication-factor 1 \
6. --topic sayaword \
7. --partitions 1
kafka-topic.sh 命令后,需要添加一些参数,比如 ZooKeeper 的配置,主题名
称等。
下面查看 Kafka 中,都有哪些 topic
1. bin/kafka-topics.sh --list --zookeeper localhost:2181
11.调用/apps/kafka/bin 目录下 kafka-console-producer.sh,来生产一些消
息,producer 也就是生产者。
1. bin/kafka-console-producer.sh --broker-list localhost:9092 --
topic sayaword
这里的 localhost 为 Kafka 的 IP,9092 为 broker 节点的端口。用户可以在
console 界面上,输入信息,交给 producer 进行处理,并发给 consumer。
12.再令开启一个窗口,调用 bin 目录下 kafka-console-consumer.sh,启动
consumer,consumer 作为消费者,用来消费数据。
1. cd /apps/kafka 2. bin/kafka-console-consumer.sh --zookeeper localhost:2181 --
topic sayaword --from-beginning
kafka-console-consumer.sh 依然需要加一些参数,比如 ZooKeeper 的 IP 及端
口、主题名称、读取数据位置等。
13.在执行 kafka-console-producer.sh 命令的界面中,随便输入几行文字,按
回车。可以看到在 consumer 端,会将同样的内容,输出出来。
producer 端:
consumer 端:
14.退出测试。
在 kafka-console-consumer.sh、kafka-console-producer.sh 及 kafka
server-start.sh 在命令行界面,执行 Ctrl + c,分别退出 consumer,
producer 及 server。
切换目录到/apps/zookeeper/bin 目录下,停止 ZooKeeper。
1. cd /apps/zookeeper/bin
2. ./zkServer.sh stop
至此,Kafka 的安装与测试都已完毕!
(二)Kafka Java API
1.在/data 目录下创建/kafka3 文件夹。
1. mkdir /data/kafka3
2.在 Linux 中切换到/data/kafka3 目录下,用 wget 命令从
http://172.16.103.12:60000/allfiles/kafka3/kafkalib.tar.gz 网址上下载
文本文件 kafkalib.tar.gz。
1. cd /data/kafka3
2. wget http://172.16.103.12:60000/allfiles/kafka3/kafkalib.tar.gz 3.下载完成后将压缩包解压到当前目录。
1. tar zxvf kafkalib.tar.gz
4..打开 Eclipse,新建一个 Java 项目,命名为 kafka3。5.右键点击项目名,新建一个 package,名为 my.kafka。6.添加项目依赖的 jar 包。
右键项目,新建一个文件夹,命名为 kafkalib,用于存放项目所需的 jar 包。将/data/kafka3 目录下 kafkalib 文件夹中的所有 jar 包,拷贝到 Eclipse 中
kafka3 项目下的 kafkalib 文件夹中。选中 kafkalib 文件夹中所有 jar 包,并添加到 Build Path 中。
7.启动 ZooKeeper。切换到/apps/zookeeper/bin 目录下,执行 ZooKeeper 的启
动脚本。
1. cd /apps/zookeeper/bin
2. ./zkServer.sh start 查看 ZooKeeper 的运行状态。
1. ./zkServer.sh status
8.切换目录到/apps/kafka 目录下,启动 kafka 的 server。
1. cd /apps/kafka
2. bin/kafka-server-start.sh config/server.properties &
9.另起一窗口,切换到/apps/kafka 下,在 kafka 中创建 topic,命名为
testkafkaapi。
1. cd /apps/kafka
2. bin/kafka-topics.sh \
3. --create \
4. --zookeeper localhost:2181 \
5. --replication-factor 1 \
6. --topic testkafkaapi \
7. --partitions 1
查看 topic
1. bin/kafka-topics.sh --list --zookeeper localhost:2181
10.创建 kafka 的 producer,用于生产数据。在 kafka3 项目 my.kafka 包下,
创建 Class,命名为 MyProducer。编写 MyProducer 类的代码。
1. package my.kafka;
2. import java.util.Properties;
3. import kafka.javaapi.producer.Producer;
4. import kafka.producer.KeyedMessage;
5. import kafka.producer.ProducerConfig;
6. public class MyProducer {
7. private final Producer<String, String> producer;
8. public final static String TOPIC = "testkafkaapi";
9. public MyProducer() { 10. Properties props = new Properties();
11. // 此处配置的是 kafka 的端口
12. props.put("metadata.broker.list", "localhost:9092");
13. // 配置 value 的序列化类
14. props.put("serializer.class",
"kafka.serializer.StringEncoder");
15. // 配置 key 的序列化类
16. props.put("key.serializer.class",
"kafka.serializer.StringEncoder");
17. // request.required.acks
18. // 0, which means that the producer never waits for an
acknowledgement
19. // from the broker (the same behavior as 0.7). This
option provides the
20. // lowest latency but the weakest durability guarantees
(some data will
21. // be lost when a server fails).
22. // 1, which means that the producer gets an
acknowledgement after the
23. // leader replica has received the data. This option
provides better
24. // durability as the client waits until the server
acknowledges the
25. // request as successful (only messages that were
written to the
26. // now-dead leader but not yet replicated will be
lost).
27. // -1, which means that the producer gets an
acknowledgement after all
28. // in-sync replicas have received the data. This option
provides the
29. // best durability, we guarantee that no messages will
be lost as long
30. // as at least one in sync replica remains.
31. props.put("request.required.acks", "-1");
32. producer = new Producer<String, String>(new
ProducerConfig(props));
33. } 34. void produce() {
35. int messageNo = 1000;
36. final int COUNT = 10000;
37. while (messageNo < COUNT) {
38. String key = String.valueOf(messageNo);
39. String data = "hello,kafka message:" + key;
40. producer.send(new KeyedMessage<String,
String>(TOPIC, key, data));
41. System.out.println(data);
42. messageNo++;
43. }
44. }
45.
46. public static void main(String[] args) {
47. new MyProducer().produce();
48. }
49. }
producer 端的代码:首先定义一个 topic 的名称,然后创建一个 properties
实例,用来设置 produce 的参数。接着创建一个 producer 的实例并将参数配置
props 作为参数上传进去。在 produce 方法中定义一个 key 与 data,创建
KeyedMessage 实例,并将 key,data 和 topic 作为参数上传进去,然后把
KeyedMessage 实例上传给 producer。在主函数中直接调用 MyProduce 的
produce()方法,用来实现消息的上传。
11.创建 kafka 的 consumer。用于消费数据。在 kafka3 项目,my.kafka 包下,
创建 Class,命名为 MyConsumer。编写 MyConsumer 类的代码
1. package my.kafka;
2. import java.util.HashMap;
3. import java.util.List;
4. import java.util.Map;
5. import java.util.Properties;
6. import kafka.consumer.ConsumerConfig;
7. import kafka.consumer.ConsumerIterator; 8. import kafka.consumer.KafkaStream;
9. import kafka.javaapi.consumer.ConsumerConnector;
10.import kafka.serializer.StringDecoder;
11.import kafka.utils.VerifiableProperties;
12.public class MyConsumer {
13. private final ConsumerConnector consumer;
14.
15. private MyConsumer() {
16. Properties props = new Properties();
17. //zookeeper 配置
18. props.put("zookeeper.connect", "localhost:2181");
19. //group 代表一个消费组
20. props.put("group.id", "mygroup");
21. //zk 连接超时
22. props.put("zookeeper.session.timeout.ms", "4000");
23. props.put("zookeeper.sync.time.ms", "200");
24. props.put("auto.commit.interval.ms", "1000");
25. props.put("auto.offset.reset", "smallest");
26. //序列化类
27. props.put("serializer.class",
"kafka.serializer.StringEncoder");
28. ConsumerConfig config = new ConsumerConfig(props);
29. consumer =
kafka.consumer.Consumer.createJavaConsumerConnector(config);
30. }
31.
32. void consume() {
33. Map<String, Integer> topicCountMap = new
HashMap<String, Integer>();
34. topicCountMap.put(MyProducer.TOPIC, new Integer(1));
35.
36. StringDecoder keyDecoder = new StringDecoder(new
VerifiableProperties());
37. StringDecoder valueDecoder = new StringDecoder(new
VerifiableProperties());
38.
39. Map<String, List<KafkaStream<String, String>>>
consumerMap =consumer.createMessageStreams(topicCountMap,keyDecoder,valueDec
oder);
40. KafkaStream<String, String> stream =
consumerMap.get(MyProducer.TOPIC).get(0);
41. ConsumerIterator<String, String> it =
stream.iterator();
42. while (it.hasNext())
43. System.out.println(it.next().message());
44. }
45.
46. public static void main(String[] args) {
47. new MyConsumer().consume();
48. }
49.}
在 MyConsumer 端分为两部分:MyConsumer()方法和 consume()方法。在
MyConsumer()方法中创建 properties 实例在里面配置 consumer 的性能,然后
创建一个接收消息的 consumer 实例并将 properties 实例作为参数传递进去。
在 cousume()方法中调用 consumer 类的 createMessageStreams()方法用来接受
从 kafka 中传递来的消息,然后通过迭代遍历将消息输出到控制台上。
12.执行程序
在 Eclipse 的 MyProducer 类中右键并点击==>Run As==>Jave Application 选
项。
进入下面窗口,点击 OK。13.然后在 MyConsumer 类中:单击右键==>Run As==>Jave Application 选项。
然后可以看到 console 界面的输出结果。
Consumer
四、实验结果分析
更改了环境变量并且配置了Kafka,使用简单 Java API 来模拟 Kafka 的 producer 和
consumer,其中 producer 是通过一个 while 循环生成内容,然后将内容传递给
Kafka,consumer 从 Kafka 中读取内容,并在 Console 界面中输出。