大数据-19 Flume Agent采集数据至HDFS集群 监听Hive日志 操作记录写入

72 阅读4分钟

点一下关注吧!!!非常感谢!!持续更新!!!

🚀 AI篇持续更新中!(长期更新)

目前2025年06月16日更新到: AI炼丹日志-29 - 字节跳动 DeerFlow 深度研究框斜体样式架 私有部署 测试上手 架构研究,持续打造实用AI工具指南!📐🤖

💻 Java篇正式开启!(300篇)

目前2025年06月23日更新到: Java-53 深入浅出 Tomcat 性能优化 JVM内存模型 垃圾回收GC Tomcat配置优化 MyBatis 已完结,Spring 已完结,Nginx已完结,Tomcat正在更新,深入浅出助你打牢基础!

📊 大数据板块已完成多项干货更新(300篇):

包括 Hadoop、Hive、Kafka、Flink、ClickHouse、Elasticsearch 等二十余项核心组件,覆盖离线+实时数仓全栈! 目前2025年06月13日更新到: 大数据-278 Spark MLib - 基础介绍 机器学习算法 梯度提升树 GBDT案例 详解

请添加图片描述

章节内容

上一节我们完成了内容:

  • Flume 启动测试
  • Flume Conf编写
  • Flume 测试发送和接收数据

背景介绍

这里是三台公网云服务器,每台 2C4G,搭建一个Hadoop的学习环境。

  • 2C4G 编号 h121
  • 2C4G 编号 h122
  • 2C2G 编号 h123

在这里插入图片描述

文档推荐

除了官方文档以外,这里有一个写的很好的中文文档: flume.liyifeng.org/

Apache Flume 是一个分布式、可靠、高可用的系统,专为从不同数据源收集数据并聚合、传输到集中式数据存储(如 HDFS、HBase)而设计。 Flume 特别适用于日志数据采集,常见于日志分析、实时监控、大数据平台等场景。

核心架构组件

  • Source:数据源,用于接收外部数据(如日志、HTTP 请求、Kafka 等)
  • Channel:缓存通道,临时存储数据(如内存、文件)以解耦 source 和 sink 的处理速度差异
  • Sink:数据目标,将 channel 中的数据写入目标系统(如 HDFS、HBase、Kafka、ElasticSearch)

这些组件共同构成一个 Agent(代理节点),一个 Flume 进程中可以包含多个这样的 Source-Channel-Sink 流程。

数据采集流程(以 HDFS 为目标)

Source 采集数据

常见的 Source 类型包括:

  • exec: 从一个 shell 命令中读取标准输出(如 tail -F log)
  • spooldir: 从一个目录读取文件(每个文件仅读取一次,适合离线数据)
  • netcat: 监听 TCP 端口,接收文本数据
  • http: 接收 HTTP 请求

示例:

agent.sources.source1.type = exec
agent.sources.source1.command = tail -F /var/log/nginx/access.log

Channel 中转缓冲

常用类型:

  • memory: 存储在内存中,速度快但易丢数据
  • file: 存储在磁盘文件中,稳定但稍慢
agent.channels.channel1.type = memory
agent.channels.channel1.capacity = 10000
agent.channels.channel1.transactionCapacity = 1000

Sink 将数据写入 HDFS

常见的配置项目如下:

agent.sinks.sink1.type = hdfs
agent.sinks.sink1.hdfs.path = hdfs://namenode:9000/flume/logs/%Y-%m-%d/
agent.sinks.sink1.hdfs.filePrefix = events
agent.sinks.sink1.hdfs.fileType = DataStream
agent.sinks.sink1.hdfs.writeFormat = Text
agent.sinks.sink1.hdfs.batchSize = 1000
agent.sinks.sink1.hdfs.rollInterval = 60      # 每60秒滚动一次新文件
agent.sinks.sink1.hdfs.rollSize = 134217728   # 文件达到128MB时滚动
agent.sinks.sink1.hdfs.rollCount = 0          # 记录条数触发滚动

完整示例

agent.sources = source1
agent.channels = channel1
agent.sinks = sink1

# Source
agent.sources.source1.type = exec
agent.sources.source1.command = tail -F /var/log/nginx/access.log
agent.sources.source1.channels = channel1

# Channel
agent.channels.channel1.type = memory
agent.channels.channel1.capacity = 10000
agent.channels.channel1.transactionCapacity = 1000

# Sink
agent.sinks.sink1.type = hdfs
agent.sinks.sink1.channel = channel1
agent.sinks.sink1.hdfs.path = hdfs://namenode:9000/flume/logs/%Y-%m-%d/
agent.sinks.sink1.hdfs.filePrefix = events
agent.sinks.sink1.hdfs.fileType = DataStream
agent.sinks.sink1.hdfs.writeFormat = Text
agent.sinks.sink1.hdfs.rollInterval = 60
agent.sinks.sink1.hdfs.rollSize = 134217728
agent.sinks.sink1.hdfs.rollCount = 0

保存为 flume.conf,使用以下命令启动:

flume-ng agent -n agent -c conf -f flume.conf -Dflume.root.logger=INFO,console

注意事项

数据丢失容错:

  • 推荐使用 file 类型的 channel 来保证在 agent 异常崩溃时不丢数据。
  • 配置 sink 的 hdfs.rollInterval 和 rollSize 以避免过大文件导致内存压力。

HDFS Sink 文件碎片问题:

  • 每次写入都会生成很多小文件(每个 roll 周期一个文件),可以定期使用 Hive/MapReduce 合并。

吞吐优化:

  • 增大 channel 的 capacity 和 transactionCapacity
  • 调整 sink 的 batchSize 参数

压缩写入 HDFS(推荐):

  • agent.sinks.sink1.hdfs.codeC = gzip

实践建议

  • 配合 Kafka 使用:Flume → Kafka → HDFS,更适用于大规模场景。
  • 支持多级代理(多级 Agent):可将多个 agent 收集的数据再聚合到中央 agent 并写入 HDFS。
  • 可嵌入 Spark 或 Hive:HDFS 中的数据可以直接被 Hive 查询或 Spark 消费。

环境准备

要将数据写入到 HDFS 中,我们需要一些支持库来完成。 (这些支持库基本都在Hadoop的支持库中,没有的话,大家可以到Maven仓库搜索下载补充一下)

cd $HADOOP_HOME/share/hadoop/httpfs/tomcat/webapps/webhdfs/WEB-INF/lib
  • commons-configuration-1.6.jar
  • commons-io-2.4.jar
  • hadoop-auth-2.9.0.jar
  • hadoop-common-2.9.0.jar
  • hadoop-hdfs-2.9.0.jar
  • htrace-core4-4.1.0-incubating.jar

你需要把这些Jar包都拷贝到 $FLUME_HOME/lib 文件夹下:

cd $FLUME_HOME/lib
ls

在这里插入图片描述

配置文件

cd 
vim flume-exec-hdfs.conf

编写如下的内容:

# Name the components on this agent
a2.sources = r2
a2.sinks = k2
a2.channels = c2

# Describe/configure the source
a2.sources.r2.type = exec
a2.sources.r2.command = tail -F /tmp/root/hive.log
# Use a channel which buffers events in memory
a2.channels.c2.type = memory
a2.channels.c2.capacity = 10000
a2.channels.c2.transactionCapacity = 500

# Describe the sink
a2.sinks.k2.type = hdfs
# 这里注意修改为服务器的IP!!!
# 注意是 HDFS 的,别写错了,具体看 Hadoop 的 core-site.xml fs.defaultFS
a2.sinks.k2.hdfs.path = hdfs://h121.wzk.icu:9000/flume/%Y%m%d/%H%M
# 上传文件的前缀
a2.sinks.k2.hdfs.filePrefix = logs-
# 是否使用本地时间戳
a2.sinks.k2.hdfs.useLocalTimeStamp = true
# 积攒500个Event才flush到HDFS一次
a2.sinks.k2.hdfs.batchSize = 500
# 设置文件类型,支持压缩。DataStream没启用压缩
a2.sinks.k2.hdfs.fileType = DataStream

# 1分钟滚动一次
a2.sinks.k2.hdfs.rollInterval = 60
# 128M滚动一次
a2.sinks.k2.hdfs.rollSize = 134217700
# 文件的滚动与Event数量无关
a2.sinks.k2.hdfs.rollCount = 0

# 最小冗余数
a2.sinks.k2.hdfs.minBlockReplicas = 1
# Bind the source and sink to the channel
a2.sources.r2.channels = c2
a2.sinks.k2.channel = c2

在这里插入图片描述

启动Agent

$FLUME_HOME/bin/flume-ng agent --name a2 \
--conf-file flume-exec-hdfs.conf \
-Dflume.root.logger=INFO,console

在这里插入图片描述 如果你启动一切顺利的话,你可以看到如下的内容: 在这里插入图片描述

测试效果

启动集群

start-dfs.sh
start-yarn.sh

启动Hive

hive -e "show databases;"

在这里插入图片描述

查看日志

可以看到 Flume 上有了输出 在这里插入图片描述

查看HDFS

观察HDFS,发现数据已经写入了: 在这里插入图片描述