实时监控单个追加文件到 HDFS 案例分析
案例需求:实时监控 Hive 日志文件,即只要应用程序向这个文件里面写数据,Source 组件就可以获取到该信息,然后写入到 Channle,最后上传到 HDFS。
需求分析:该实训是,使用 Exec Source 接收外部数据源,HDFS 作为 Sink。Flume 使用 tail 命令从指定文件尾部读取,将每行作为一个 Event 发送到 Channel 中缓存,最后存入 HDFS。过程如下图所示:
Flume 配置讲解
1. Exec Source 配置讲解
Exec Source 在启动时运行给定的 Unix 命令,并期望该进程在标准输出上连续生成数据。如果进程因任何原因退出,则 Source 也会退出并且不会继续生成数据。这意味着诸如 cat [named pipe] 或 tail -F [file] 之类的命令会产生所需的结果,而 date 这种命令可能不会,因为前两个命令(tail 和 cat)能产生持续的数据流,而后者(date 这种命令)只会产生单个 Event 并退出。以下是必需的参数:
属性名称 默认值 描述
channels – 与 Source 绑定的 Channel,多个用空格分开
type – 组件类型名称,需要是 exec
command – 使用的系统命令,一般是 cat 或者 tail
2. HDFS Sink 配置讲解
HDFS Sink 将 Event 写入 Hadoop 分布式文件系统(也就是 HDFS)。它目前支持创建文本和序列文件,以及两种类型的压缩文件。
HDFS Sink 可以根据写入的时间、文件大小或 Event 数量定期滚动文件(关闭当前文件并创建新文件)。它还可以根据 Event 发生的时间戳或系统时间等属性对数据进行存储/分区。存储文件的 HDFS 目录路径可以使用格式转义序列,这些转义序列将被 HDFS Sink 进行动态地替换,以生成用于存储 Event 的目录或文件名。使用 HDFS Sink 时需要安装 Hadoop,以便 Flume 可以使用 Hadoop jar 与 HDFS 集群进行通信。请注意, 需要使用支持 sync() 调用的 Hadoop 版本。
以下是支持的转义序列:
转义序列 | 描述 |
---|---|
%{host} | Event header 中 key 为 host 的值。这个 host 可以是任意的 key,只要 header 中有就能读取,比如 %{aabc} 将读取 header 中 key 为 aabc 的值 |
%t | 毫秒值的时间戳(同 System.currentTimeMillis() 方法) |
%a | 星期的缩写(Mon、Tue 等) |
%A | 星期的全拼(Monday、 Tuesday 等) |
%b | 月份的缩写(Jan、 Feb 等) |
%B | 月份的全拼(January、February 等) |
%c | 日期和时间(Mon Feb 14 23:05:25 2022) |
%d | 月份中的某一天(00到31) |
%e | 没有填充的月份中的某一天(1到31) |
%D | 日期,与%m/%d/%y相同 ,例如:02/14/22 |
%H | 小时(00到23) |
%I | 小时(01到12) |
%j | 一年中的一天(001到366) |
%k | 小时(0到23),注意跟 %H的区别 |
%m | 月份(01到12) |
%n | 没有填充的月份(1到12) |
%M | 分钟(00到59) |
%p | am或者pm |
%s | unix时间戳,是秒值。比如 2022-02-14 18:15:49 的 unix 时间戳是:1644833749 |
%S | 秒(00到59) |
%y | 一年中的最后两位数(00到99),比如1998年的%y就是98 |
%Y | 年份(2010这种格式) |
%z | +hhmm,数字时区(比如:-0400) |
%[localhost] | Agent 实例所在主机的 hostname |
%[IP] | Agent 实例所在主机的 IP 地址 |
%[FQDN] | Agent 实例所在主机的规范 hostname |
注意,%[localhost]、%[IP] 和 %[FQDN] 这三个转义序列实际上都是用 Java 的 API 来获取的,在某些网络环境下可能会获取失败。
正在打开的文件会在名称末尾加上“.tmp”的后缀。文件关闭后,会自动删除此扩展名。这样容易排除目录中的那些已完成的文件。必需的参数已用粗体标明:
属性名称 | 默认值 | 描述 |
---|---|---|
channel | – | 与 Sink 绑定的 Channel |
type | – | 组件类型名称,需要是 hdfs |
hdfs.path | – | HDFS 目录路径(例如:hdfs://namenode/flume/hivedata/) |
hdfs.filePrefix | FlumeData | Flume 在 HDFS 文件夹下创建新文件的固定前缀 |
hdfs.fileSuffix | – | Flume 在 HDFS 文件夹下创建新文件的后缀(比如:.avro,注意这个“.”不会自动添加,需要显式配置) |
hdfs.inUsePrefix | – | Flume 正在写入的临时文件前缀,默认没有 |
hdfs.inUseSuffix | .tmp | Flume 正在写入的临时文件后缀 |
hdfs.emptyInUseSuffix | false | 如果设置为 false 上面的 hdfs.inUseSuffix 参数在写入文件时会生效,并且写入完成后会在目标文件上移除 hdfs.inUseSuffix 配置的后缀。如果设置为 true 则上面的 hdfs.inUseSuffix 参数会被忽略,写文件时不会带任何后缀 |
hdfs.rollInterval | 30 | 当前文件写入达到该值时间后触发滚动创建新文件(0表示不按照时间来分割文件),单位:秒 |
hdfs.rollSize | 1024 | 当前文件写入达到该大小后触发滚动创建新文件(0表示不根据文件大小来分割文件),单位:字节 |
hdfs.rollCount | 10 | 当前文件写入 Event 达到该数量后触发滚动创建新文件(0表示不根据 Event 数量来分割文件) |
hdfs.idleTimeout | 0 | 关闭非活动文件的超时时间(0表示禁用自动关闭文件),单位:秒 |
hdfs.batchSize | 100 | 在将文件刷新到 HDFS 之前写入文件的 Event 数 |
hdfs.codeC | – | 压缩编解码器。可选值:gzip 、 bzip2 、 lzo 、 lzop 、 snappy |
hdfs.fileType | SequenceFile | 文件格式。目前支持: SequenceFile 、 DataStream 、 CompressedStream 。 DataStream 不会压缩文件,不需要设置hdfs.codeC;CompressedStream 必须设置 hdfs.codeC 参数 |
hdfs.writeFormat | Writable | 文件写入格式。可选值: Text 、 Writable 。在使用 Flume 创建数据文件之前设置为 Text,否则 Apache Impala(孵化)或 Apache Hive 无法读取这些文件 |
hdfs.useLocalTimeStamp | false | 使用日期时间转义序列时是否使用本地时间戳(而不是使用 Event headers 中的时间戳) |
serializer | TEXT | Event 转为文件使用的序列化器。其他可选值有: avro_event 或其他 EventSerializer.Builderinterface 接口的实现类的全限定类名 |
serializer.* | 根据上面 serializer 配置的类型来根据需要添加序列化器的参数 |
3. Memory Channel 配置讲解
Memory Channel 是把 Event 队列存储到内存上,队列的最大数量就是 capacity 的设定值。它非常适合对吞吐量有较高要求的场景,但也是有代价的,当发生故障的时候会丢失当时内存中的所有 Event。必需的参数已用粗体标明:
属性名称 | 默认值 | 说明 |
---|---|---|
type | – | 组件类型,需要是 memory |
capacity | 100 | 存储在 Channel 中的最大 Event 数 |
transactionCapacity | 100 | Channel 将从 Source 接收或向 Sink 传递的每一个事务中的最大 Event 数(capacity>= transactionCapacity) |
配置Flume采集方案
1. 创建 Agent 配置文件(Exec Source + Memory Channel + HDFS Sink)
进入 /root/software/apache-flume-1.9.0-bin/conf 目录,使用 touch 命令创建一个名为 exec_hdfs.conf 的配置文件。
2. 编辑配置文件 exec_hdfs.conf
使用 vim 命令打开 exec_hdfs.conf 文件,在里面添加如下配置:
(1)配置 Flume Agent——ExecAgent
首先,我们需要为 ExecAgent 命名/列出组件,将数据源(Source)、缓冲通道(Channel)和接收器(Sink)分别命名为 execSource、 memoryChannel 和 HDFSSink。
(2)描述和配置 Exec Source
Exec Source 在启动时运行给定的 Unix 命令,并期望该进程在标准输出上连续生成数据。如果进程因任何原因退出,则 Source 也会退出并且不会继续生成数据。这意味着诸如 cat [named pipe] 或 tail -F [file] 之类的命令会产生所需的结果,而 date 这种命令可能不会,因为前两个命令(tail 和 cat)能产生持续的数据流,而后者(date 这种命令)只会产生单个 Event 并退出。
我们需要为 execSource 设置以下属性:
属性名称 | 描述 | 设置值 |
---|---|---|
channels | 与 Source 绑定的 Channel | memoryChannel |
type | 数据源的类型 | exec |
command | 所使用的系统命令,一般是 cat 或者 tail | tail -F /tmp/root/hive.log |
###(3)描述和配置 HDFS Sink
HDFS Sink 将 Event 写入 Hadoop 分布式文件系统(也就是 HDFS)。它目前支持创建文本和序列文件,以及两种类型的压缩文件。
HDFS Sink 可以根据写入的时间、文件大小或 Event 数量定期滚动文件(关闭当前文件并创建新文件)。它还可以根据 Event 发生的时间戳或系统时间等属性对数据进行存储/分区。存储文件的 HDFS 目录路径可以使用格式转义序列,这些转义序列将被 HDFS Sink 进行动态地替换,以生成用于存储 Event 的目录或文件名。使用 HDFS Sink 时需要安装 Hadoop,以便 Flume 可以使用 Hadoop jar 与 HDFS 集群进行通信。请注意, 需要使用支持 sync() 调用的 Hadoop 版本。
在此实训中,我们需要为 HDFSSink 设置以下属性。默认情况下,Flume 会每隔 30s、10 个 Event 事件或者是 1024 字节来转储写入的文件。这里我们设置成每隔 60s 或 5242880 字节(5M)来转储写入的文件。另外,将 Flume 在 HDFS 文件夹下创建的新文件的固定前缀设置为 hivelogs-:
属性名称 | 描述 | 设置值 |
---|---|---|
channel | 与 Sink 绑定的 Channel | memoryChannel |
type | 接收器的类型 | hdfs |
hdfs.path | HDFS 目录路径 | hdfs://localhost:9000/flumedata/hive/%Y-%m-%d |
hdfs.filePrefix | Flume 在 HDFS 文件夹下创建新文件的固定前缀,默认值为 FlumeData hivelogs- | |
hdfs.rollInterval | 滚动当前文件之前等待的秒数(0=从不基于时间间隔滚动),单位:秒,默认值:30 60 | |
hdfs.rollSize | 触发滚动的文件大小(0=永不基于文件大小滚动),单位:字节,默认值:1024 5242880(5M) | |
hdfs.rollCount | 在滚动之前写入文件的 Event 数(0=从不基于 Event 数滚动),默认值:10 0 | |
hdfs.fileType | 文件格式,目前支持: SequenceFile、DataStream 、CompressedStream。 其中,DataStream 不会压缩文件,不需要设置 hdfs.codeC,而 CompressedStream 必须设置 hdfs.codeC 参数。默认值:SequenceFile DataStream | |
hdfs.writeFormat | 文件写入格式。可选值:Text 和 Writable,默认值:Writable。在使用 Flume 创建数据文件之前设置为 Text,否则 Apache Impala 或 Apache Hive 无法读取这些文件 Text | |
hdfs.useLocalTimeStamp | 在替换转义序列时使用本地时间(而不是使用 Event header 中的时间戳),默认值:false true |
###(4)描述和配置 Memory Channel
Memory Channel 是把 Event 队列存储到内存上,队列的最大数量就是 capacity 的设定值。它非常适合对吞吐量有较高要求的场景,但也是有代价的,当发生故障的时候会丢失当时内存中的所有 Event。
我们需要为 memoryChannel 设置以下属性:
属性名称 | 描述 | 设置值 |
---|---|---|
type | 缓冲通道的类型 | memory |
capacity | 存储在 Channel 中的最大 Event 数,默认值100 | 1000 |
transactionCapacity | Channel 将从 Source 接收或向 Sink 传递的每一个事务中的最大 Event 数(capacity>= transactionCapacity),默认值100 | 100 |
## Name the components on this agent
# execSource为 ExecAgent的 Source的名称
ExecAgent.sources = execSource
# memoryChanne1为 ExecAgent的 Channel的名称
ExecAgent.channels = memoryChannel
# HDFSSink为ExecAgent的 Sink的 名称
ExecAgent.sinks = HDFSSink
## Describe/configure the source
# 与 Source绑定的 Channel
ExecAgent.sources.execSource.channels = memoryChannel
# 数据源的类型为 exec类型
ExecAgent.sources.execSource.type = exec
# 实时监控单个追加文件
ExecAgent.sources.execSource.command = tail -F /tmp/root/hive.log
## Describe the sink
#与 Sink绑定的 Channel
ExecAgent.sinks.HDFSSink.channel = memoryChannel
# 接收器的类型为 hdfs类型,输出目的地是HDFS
ExecAgent.sinks.HDFSSink.type = hdfs
# 数据存放在HDFS上的目录
ExecAgent.sinks.HDFSSink.hdfs.path = hdfs://localhost:9000/flumedata/hive/%Y-%m-%c
# 文件的固定前缀为 hivelogs-
ExecAgent.sinks.HDFSSink.hdfs.filePrefix = hivelogs-
# 按时间间隔滚动文件,默认30s,此处设置为 60s
ExecAgent.sinks.HDFSSink.hdfs.rollInterval = 60
# 按文件大小滚动文件,默认1024字节,此处设置为5242880字节 ( 5M)
ExecAgent.sinks.HDFsSink.hdfs.rollSize = 5242880
# 当Event个数达到该数量时,将临时文件滚动成目标文件,默认是10,0表示文件的滚动与Event数量无关
ExecAgent.sinks .HDFSSink.hdfs.ro11Count =0
# 文件格式,默认为SequenceFile,但里面的内容无法直接打开浏览,所以此处设置为DataStream
ExecAgent.sinks .HDFSSink.hdfs.fileType = DataStream
# 文件写入格式,默认为Writable,此处设置为Text
ExecAgent.sinks.HDFSSink .hdfs .writeFormat = Text