大数据基础---Flume整合Kafka
一、背景
先说一下,为什么要使用 Flume + Kafka?
以实时流处理项目为例,由于采集的数据量可能存在峰值和峰谷,假设是一个电商项目,那么峰值通常出现在秒杀时,这时如果直接将 Flume 聚合后的数据输入到 Storm 等分布式计算框架中,可能就会超过集群的处理能力,这时采用 Kafka 就可以起到削峰的作用。Kafka 天生为大数据场景而设计,具有高吞吐的特性,能很好地抗住峰值数据的冲击。
二、整合流程
Flume 发送数据到 Kafka 上主要是通过 KafkaSink
来实现的,主要步骤如下:
1. 启动Zookeeper和Kafka
这里启动一个单节点的 Kafka 作为测试:
# 启动Zookeeper
zkServer.sh start
# 启动kafka
bin/kafka-server-start.sh config/server.properties
2. 创建主题
创建一个主题 flume-kafka
,之后 Flume 收集到的数据都会发到这个主题上:
# 创建主题
bin/kafka-topics.sh --create \
--zookeeper hadoop001:2181 \
--replication-factor 1 \
--partitions 1 --topic flume-kafka
# 查看创建的主题
bin/kafka-topics.sh --zookeeper hadoop001:2181 --list
3. 启动kafka消费者
启动一个消费者,监听我们刚才创建的 flume-kafka
主题:
# bin/kafka-console-consumer.sh --bootstrap-server hadoop001:9092 --topic flume-kafka
4. 配置Flume
新建配置文件 exec-memory-kafka.properties
,文件内容如下。这里我们监听一个名为 kafka.log
的文件,当文件内容有变化时,将新增加的内容发送到 Kafka 的 flume-kafka
主题上。
a1.sources = s1
a1.channels = c1
a1.sinks = k1
a1.sources.s1.type=exec
a1.sources.s1.command=tail -F /tmp/kafka.log
a1.sources.s1.channels=c1
#设置Kafka接收器
a1.sinks.k1.type= org.apache.flume.sink.kafka.KafkaSink
#设置Kafka地址
a1.sinks.k1.brokerList=hadoop001:9092
#设置发送到Kafka上的主题
a1.sinks.k1.topic=flume-kafka
#设置序列化方式
a1.sinks.k1.serializer.class=kafka.serializer.StringEncoder
a1.sinks.k1.channel=c1
a1.channels.c1.type=memory
a1.channels.c1.capacity=10000
a1.channels.c1.transactionCapacity=100
5. 启动Flume
flume-ng agent \
--conf conf \
--conf-file /usr/app/apache-flume-1.6.0-cdh5.15.2-bin/examples/exec-memory-kafka.properties \
--name a1 -Dflume.root.logger=INFO,console
6. 测试
向监听的 /tmp/kafka.log
文件中追加内容,查看 Kafka 消费者的输出:
可以看到 flume-kafka
主题的消费端已经收到了对应的消息:
三、Kafka Channel使用场景
- 配合Flume Source、Flume Sink使用,为Event的传输提供一种具有高可用的Channel
- 配合Flume Source和拦截器interceptor使用,无Sink,用于将Flume搜集的Event传输到Kafka集群指定Topic中,便于Kafka消息订阅者使用
- 配合Flume Sink使用,如HDFS Sink、HBaseSink等,无Source,用于提供一种低延迟、高容错的传输Event方式,直接通过Flume Agent将Kafka中的Event传输给Flume Sink
Flume Agent配置示例
此Flume Agent配置文件主要用于启动Agent监控指定日志文件的更新内容,并将其进行简单的过滤、分类和标记,最终输出到对应的Kafka Topic中。其中使用到的Flume组件有TailDir Source、2个自定义拦截器Interceptor、Channel Selector、2个Kafka Channel等
# 此Flume Agent配置文件用于将指定文件的更新内容按照类别使用自定义interceptors打上不同的键值对,并通过
# Channel Selector按照键值对传输给不同的Kafka Channel,最后输出到Kafka集群指定topic中
# TailDir Source -> interceptors -> Channel Selector -> Kafka Channel -> kafka Topic
# Agent
a1.sources = r1
a1.channels = c1 c2
# 不使用Sink(Kafka Channel可以不使用Sink),主要是将数据采集到Kafka中去
# Sources
# a1.sources.r1
a1.sources.r1.type = TAILDIR
# 设置Json文件存储路径(最好使用绝对路径)
# 用于记录文件inode/文件的绝对路径/每个文件的最后读取位置等信息
a1.sources.r1.positionFile = /opt/module/flume-1.8.0/.position/taildir_position.json
# 指定监控的文件组
a1.sources.r1.filegroups = f1
# 配置文件组中的文件
# 设置f1组的监控文件,注意:使用的是正则表达式,而不是Linux通配符
a1.sources.r1.filegroups.f1 = /tmp/logs/app.+
# 设置Event的Header中插入文件绝对路径键值对
a1.sources.r1.fileHeader = true
# Interceptors
# a1.sources.r1.interceptors
a1.sources.r1.interceptors = i1 i2
# 设置自定义的ETL Interceptor拦截器
a1.sources.r1.interceptors.i1.type = com.tomandersen.flume.interceptor.LogETLInterceptor$Builder
# 设置自定义的Log Type Interceptor拦截器
a1.sources.r1.interceptors.i2.type = com.tomandersen.flume.interceptor.LogTypeInterceptor$Builder
# Channel Selector
# a1.sources.r1.selector
a1.sources.r1.selector.type = multiplexing
# 设置Multiplexing Channel Selector根据日志类型发往不同的Channel
a1.sources.r1.selector.header = topic
# 将启动日志发往c1
a1.sources.r1.selector.mapping.topic_start = c1
# 将事件日志发往c2
a1.sources.r1.selector.mapping.topic_event = c2
# Channels
# a1.channels.c1
a1.channels.c1.type = org.apache.flume.channel.kafka.KafkaChannel
# 设置Kafka集群中的Broker
a1.channels.c1.kafka.bootstrap.servers = kafkaServer1:9092,kafkaServer2:9092,kafkaServer3:9092
# 设置a1.channels.c1所使用的Kafka的topic
a1.channels.c1.kafka.topic = topic_start
# 设置成不按照flume event格式解析数据,因为同一个Kafka topic可能有非flume Event类数据传入
a1.channels.c1.parseAsFlumeEvent = false
# # 设置注册的Kafka消费者组,此消费组应该设置成相同,保证同一个消费组中的用户两种数据都能读取
# a1.channels.c1.kafka.consumer.group.id = flume-consumer
# a1.channels.c2
a1.channels.c2.type = org.apache.flume.channel.kafka.KafkaChannel
# 设置Kafka集群中的Broker
a1.channels.c2.kafka.bootstrap.servers = kafkaServer1:9092,kafkaServer2:9092,kafkaServer3:9092
# 设置a1.channels.c1所使用的Kafka的topic
a1.channels.c2.kafka.topic = topic_event
# 设置成不按照flume event格式解析数据,因为同一个Kafka topic可能有非flume Event类数据传入
a1.channels.c2.parseAsFlumeEvent = false
# # 设置注册的Kafka消费者组,此消费组应该设置成相同,保证同一个消费组中的用户两种数据都能读取
# a1.channels.c2.kafka.consumer.group.id = flume-consumer
# Bind
a1.sources.r1.channels = c1 c2
本文来自博客园,作者:数据驱动,转载请注明原文链接:https://www.cnblogs.com/shun7man/p/13186400.html