本文将介绍,使用flume中的Kafka Channel消费kafka指定topic的数据到Hadoop的HDFS文件系统,以便后面的数据处理。
软件版本说明:
- HDFS-3.1.1.3.1
- kafka-2.12-2.8.2
- apache-flume-1.9.0
- jdk-1.8
一、Kafka Channel 介绍
Kafka提供了高可用性和复制机制,因此如果Flume实例或者 Kafka 的实例挂掉,能保证Event数据随时可用。 Kafka channel可以用于多种场景:
- 与source和sink一起:给所有Event提供一个可靠、高可用的channel。
- 与source、interceptor一起,但是没有sink:可以把所有Event写入到Kafka的topic中,来给其他的应用使用。
- 与sink一起,但是没有source:提供了一种低延迟、容错高的方式将Event发送的各种Sink上,比如:HDFS、HBase、Solr。
目前支持Kafka 0.10.1.0以上版本,最高已经在Kafka 2.0.1版本上完成了测试,这已经是Flume 1.9发行时候的最高的Kafka版本了。
配置参数说明如下:
- 通常与channel相关的配置值应用于channel配置级别,比如:a1.channel.k1.type =
- 与Kafka相关的配置值或Channel运行的以“kafka.”为前缀(这与CommonClient Configs类似),例如:a1.channels.k1.kafka.topic 和 a1.channels.k1.kafka.bootstrap.servers。 这与hdfs sink的运行方式没有什么不同
- 特定于生产者/消费者的属性以kafka.producer或kafka.consumer为前缀
- 可能的话,使用Kafka的参数名称,例如:bootstrap.servers 和 acks
当前Flume版本是向下兼容的,但是第二个表中列出了一些不推荐使用的属性,并且当它们出现在配置文件中时,会在启动时打印警告日志。
必需的参数已用 粗体 标明。
| 属性 | 默认值 | 解释 |
|---|---|---|
| type | – | 组件类型,这个是: org.apache.flume.channel.kafka.KafkaChannel |
| kafka.bootstrap.servers | – | channel使用的Kafka集群的实例列表,可以是实例的部分列表。但是更建议至少两个用于高可用支持。格式为hostname:port,多个用逗号分隔 |
| kafka.topic | flume-channel | channel使用的Kafka topic |
| kafka.consumer.group.id | flume | channel 用于向 Kafka 注册的消费者群组ID。 多个 channel 必须使用相同的 topic 和 group,以确保当一个Flume实例发生故障时,另一个实例可以获取数据。请注意,使用相同组ID的非channel消费者可能会导致数据丢失。 |
| parseAsFlumeEvent | true | 是否以avro基准的 Flume Event 格式在channel中存储Event。 如果是Flume的Source向channel的topic写入Event则应设置为true; 如果其他生产者也在向channel的topic写入Event则应设置为false。 通过使用 flume-ng-sdk 中的 org.apache.flume.source.avro.AvroFlumeEvent 可以在Kafka之外解析出Flume source的信息。 |
| pollTimeout | 500 | 消费者调用poll()方法时的超时时间(毫秒) kafka.apache.org/090/javadoc…) |
| defaultPartitionId | – | 指定channel中所有Event将要存储的分区ID,除非被 partitionIdHeader 参数的配置覆盖。 默认情况下,如果没有设置此参数,Event 会被Kafka生产者的分发程序分发,包括key(如果指定了的话),或者被 kafka.partitioner.class 指定的分发程序来分发。 |
| partitionIdHeader | – | 从Event header中读取要存储Event到目标Kafka的分区的属性名。 如果设置了,生产者会从Event header中获取次属性的值,并将消息发送到topic的指定分区。 如果该值表示的分区无效,则Event不会存入channel。如果该值有效,则会覆盖 defaultPartitionId 配置的分区ID。 |
| kafka.consumer.auto.offset.reset | latest | 当Kafka中没有初始偏移量或者当前偏移量已经不在当前服务器上时(比如数据已经被删除)该怎么办。 earliest:自动重置偏移量到最早的位置; latest:自动重置偏移量到最新的位置; none:如果没有为消费者的组找到任何先前的偏移量,则向消费者抛出异常; else:向消费者抛出异常。 |
| kafka.producer.security.protocol | PLAINTEXT | 设置使用哪种安全协议写入Kafka。可选值: SASL_PLAINTEXT 、 SASL_SSL 和 SSL 有关安全设置的其他信息,请参见下文。 |
| kafka.consumer.security.protocol | PLAINTEXT | 与上面的相同,只不过是用于消费者。 |
| more producer/consumer security props | 如果使用了 SASL_PLAINTEXT 、 SASL_SSL 或 SSL 等安全协议,参考 Kafka security 来为生产者、消费者增加安全相关的参数配置 |
配置范例:
a1.channels.channel1.type = org.apache.flume.channel.kafka.KafkaChannel
a1.channels.channel1.kafka.bootstrap.servers = node1:9092,node2:9092,node3:9092
a1.channels.channel1.kafka.topic = flume-channel-topic
a1.channels.channel1.kafka.consumer.group.id = g-flume-consumer
二、单节点Kafka的启动
在2.8版本之前,kafkaQ 都是强依赖zookeeper这个分布式服务协调管理工具的。在kafka2.8 版本开始尝试从服务架构中去掉zookeeper,到了3.0版本这个工作基本上完成,这是kafka的一个非常重要的里程碑。
这里我们采用不依赖于Zookeeper的启动方式。
1、将文件kafka_2.12-2.8.2.tgz上传到虚拟机CentOS 或者使用Cygwin64 Terminal,也可以是 Windows10之后的WSL安装的ubuntu上 进行解压
[root@node6 kafka_2.12-2.8.2]# pwd
/data/webservices/kafka_2.12-2.8.2
[root@node6 kafka_2.12-2.8.2]# ls
bin config libs LICENSE licenses logs NOTICE site-docs
2、按照下面的步骤进行启动
[root@node6 kafka_2.12-2.8.2]# cd /data/webservices/kafka_2.12-2.8.2
[root@node6 kafka_2.12-2.8.2]# bin/kafka-storage.sh random-uuid
EnxMvOncQSGY7VXnWlWcpw
# 格式化处理
[root@node6 kafka_2.12-2.8.2]# bin/kafka-storage.sh format -t EnxMvOncQSGY7VXnWlWcpw -c config/kraft/server.properties
# 前台方式启动(终端断了程序也会终止)
[root@node6 kafka_2.12-2.8.2]# bin/kafka-server-start.sh config/kraft/server.properties
# 也可以后台启动
[root@node6 kafka_2.12-2.8.2]# bin/kafka-server-start.sh -daemon config/kraft/server.properties
# 查看是否启动
[root@node6 kafka_2.12-2.8.2]# ps -aux|grep kafka
这样的话,kafka就成功启动了。接下来建立topic。
3、kafka topic创建
# 创建topic
[root@node6 kafka_2.12-2.8.2]# bin/kafka-topics.sh --create --topic test --partitions 3 --replication-factor 1 --bootstrap-server 192.168.0.86:9092
Created topic test.
# 列出topic
[root@node6 kafka_2.12-2.8.2]# bin/kafka-topics.sh --list --bootstrap-server 192.168.0.86:9092
test
可以看到topic创建成功了。
三、flume的安装配置
1、同样的将 apache-flume-1.9.0-bin.tar.gz解压进行安装。
[root@node6 apache-flume-1.9.0-bin]# pwd
/data/webservices/apache-flume-1.9.0-bin
[root@node6 apache-flume-1.9.0-bin]# ls
bin CHANGELOG conf DEVNOTES doap_Flume.rdf docs lib LICENSE NOTICE README.md RELEASE-NOTES tools
# 修改conf的flume-env.sh.template 为 flume-env.sh
[root@node6 conf]# cd /data/webservices/apache-flume-1.9.0-bin/conf
[root@node6 conf]# cp flume-env.sh.template flume-env.sh
# 配置下jdk 与 FLUME_CLASSPATH

2、配置agent文件
在目录conf下建立配置文件kafka-hdfs.conf, 内容如下:
# Flume将 kafka 中的数据转存到 HDFS 中
a1.channels = c1
a1.sinks = k1
# 定义 KafkaChannel
a1.channels.c1.type = org.apache.flume.channel.kafka.KafkaChannel
a1.channels.c1.parseAsFlumeEvent = false
a1.channels.c1.kafka.bootstrap.servers = 192.168.0.86:9092
a1.channels.c1.kafka.topic = test
a1.channels.c1.kafka.consumer.group.id = g1
# 定义 HDFS sink
a1.sinks.k1.channel = c1
a1.sinks.k1.type = hdfs
# 文件路径后面的%Y%m%d/%H 会自动建立
a1.sinks.k1.hdfs.path = hdfs://node6:8020/tmp/flume/%Y%m%d/%H
a1.sinks.k1.hdfs.useLocalTimeStamp = true
# HDFS中存储的文件前缀
a1.sinks.k1.hdfs.filePrefix = log
a1.sinks.k1.hdfs.fileType = DataStream
# 不按照条数生成文件
a1.sinks.k1.hdfs.rollCount = 0
# HDFS 上的文件达到128M 生成一个文件
a1.sinks.k1.hdfs.rollSize = 134217728
# HDFS 上的文件达到10分钟生成一个文件
a1.sinks.k1.hdfs.rollInterval = 600
参数都有注释,不懂的可以查阅官网进行深入学习。
3、启动flume agent
[root@node6 apache-flume-1.9.0-bin]# ./bin/flume-ng agent -c conf/ -f conf/kafka-hdfs.conf -n a1 -Dflume.root.logger=INFO,console
四、进行数据测试
1、启动kafka生产端
[root@node6 kafka_2.12-2.8.2]# bin/kafka-console-producer.sh --bootstrap-server 192.168.0.86:9092 --topic test
随便输入一些内容,按回车。
2、观察flume的输出
可以看到有问价生产。
3、在hdfs中查看
可以看到有对应的文件生产了。也可以查看下具体的内容验证下:
[root@node6 ~]# hdfs dfs -cat hdfs://node6:8020/tmp/flume/20221110/11/log.1668049426418.tmp
成功的实现了flume使用kafka channel,不配置sink消费 kafka topic数据到 HDFS文件系统。