安装

开始安装第一个Agent

Flume Agent的配置是在一个本地的配置文件中。这是一个遵循Java properties文件格式的文本文件。一个或多个Agent配置可放在同一个配置文件里。配置文件包含Agent的source,sink和channel的各个属性以及他们的数据流连接。

第一步:配置各个组件

每个组件(source,sink或者channel)都有一个name,type和一系列的基于其type或实例的属性。例如,一个avro source需要有个hostname(或者ip地址)一个端口号来接收数据。一个内存channel有最大队列长度的属性(capacity),一个HDFS sink需要知晓文件系统的URI地址创建文件,文件访问频率(hdfs.rollInterval)等等。所有的这些组件属性都需要在Flume配置文件中设置。

第二步:连接各个组件

Agent需要知道加载什么组件,以及这些组件在流中的连接顺序。通过列出在Agent中的source,sink和channel名称,定义每个sink和source的channel来完成。

提示

本来上面这段原文中描述了一个例子,可是并不直观,不如直接看下面hello world里面的配置例子。

第三步:启动Agent

bin目录下的flume-ng是Flume的启动脚本,启动时需要指定Agent的名字、配置文件的目录和配置文件的名称。

比如这样:

  1. $ bin/flume-ng agent -n $agent_name -c conf -f conf/flume-conf.properties.template

到此,Agent就会运行flume-conf.properties.template里面配置的source和sink了。

一个简单的Hello World

这里给出了一个配置文件的例子,部署一个单节点的Flume,这个配置是让你自己生成Event数据然后Flume会把它们输出到控制台上。

提示

下面的配置文件中,source使用的是 NetCat TCP Source,这个Source在后面会有专门的一节来介绍,简单说就是监听本机上某个端口上接收到的TCP协议的消息,收到的每行内容都会解析封装成一个Event,然后发送到channel;sink使用的是 Logger Sink,这个sink可以把Event输出到控制台;channel使用的是Memory Channel,是一个用内存作为Event缓冲的channel。Flume内置了多种多样的source、sink和channel,后面 配置 章节会逐一介绍。

  1. # example.conf: 一个单节点的 Flume 实例配置
  2.  
  3. # 配置Agent a1各个组件的名称
  4. a1.sources = r1 #Agent a1 的source有一个,叫做r1
  5. a1.sinks = k1 #Agent a1 的sink也有一个,叫做k1
  6. a1.channels = c1 #Agent a1 的channel有一个,叫做c1
  7.  
  8. # 配置Agent a1的source r1的属性
  9. a1.sources.r1.type = netcat #使用的是NetCat TCP Source,这个的是别名,Flume内置的一些组件都是有别名的,没有别名填全限定类名
  10. a1.sources.r1.bind = localhost #NetCat TCP Source监听的hostname,这个是本机
  11. a1.sources.r1.port = 44444 #监听的端口
  12.  
  13. # 配置Agent a1的sink k1的属性
  14. a1.sinks.k1.type = logger # sink使用的是Logger Sink,这个配的也是别名
  15.  
  16. # 配置Agent a1的channel c1的属性,channel是用来缓冲Event数据的
  17. a1.channels.c1.type = memory #channel的类型是内存channel,顾名思义这个channel是使用内存来缓冲数据
  18. a1.channels.c1.capacity = 1000
  19. a1.channels.c1.transactionCapacity = 100
  20.  
  21. # 把source和sink绑定到channel上
  22. a1.sources.r1.channels = c1 #与source r1绑定的channel有一个,叫做c1
  23. a1.sinks.k1.channel = c1 #与sink k1绑定的channel有一个,叫做c1

配置文件里面的注释已经写的很明白了,这个配置文件定义了一个Agent叫做a1,a1有一个source监听本机44444端口上接收到的数据、一个缓冲数据的channel还有一个把Event数据输出到控制台的sink。这个配置文件给各个组件命名,并且设置了它们的类型和其他属性。通常一个配置文件里面可能有多个Agent,当启动Flume时候通常会传一个Agent名字来做为程序运行的标记。

用下面的命令加载这个配置文件启动Flume:

  1. $ bin/flume-ng agent --conf conf --conf-file example.conf --name a1 -Dflume.root.logger=INFO,console

请注意,在完整的部署中通常会包含 –conf=<conf-dir>这个参数,<conf-dir>目录里面包含了flume-env.sh和一个log4j properties文件,在这个例子里面,我们强制Flume把日志输出到了控制台,运行的时候没有任何自定义的环境脚本。

测试一下我们的这个例子吧,打开一个新的终端窗口,用telnet命令连接本机的44444端口,然后输入Hello world!后按回车,这时收到服务器的响应[OK](这是 NetCat TCP Source 默认给返回的),说明一行数据已经成功发送。

  1. $ telnet localhost 44444
  2. Trying 127.0.0.1...
  3. Connected to localhost.localdomain (127.0.0.1).
  4. Escape character is '^]'.
  5. Hello world! <ENTER>
  6. OK

Flume的终端里面会以log的形式输出这个收到的Event内容。

  1. 12/06/19 15:32:19 INFO source.NetcatSource: Source starting
  2. 12/06/19 15:32:19 INFO source.NetcatSource: Created serverSocket:sun.nio.ch.ServerSocketChannelImpl[/127.0.0.1:44444]
  3. 12/06/19 15:32:34 INFO sink.LoggerSink: Event: { headers:{} body: 48 65 6C 6C 6F 20 77 6F 72 6C 64 21 0D Hello world!. }

恭喜你!到此你已经成功配置并运行了一个Flume Agent,接下来的章节我们会介绍更多关于Agent的配置。

在配置文件里面自定义环境变量

Flume可以替换配置文件中的环境变量,例如:

  1. a1.sources = r1
  2. a1.sources.r1.type = netcat
  3. a1.sources.r1.bind = 0.0.0.0
  4. a1.sources.r1.port = ${NC_PORT}
  5. a1.sources.r1.channels = c1

警告

注意了,目前只允许在value里面使用环境变量(也就是说只能在等号右边用,左边不行)

启动Agent时候加上 propertiesImplementation = org.apache.flume.node.EnvVarResolverProperties 就可以了。

例如:

  1. $ NC_PORT=44444 bin/flume-ng agent --conf conf --conf-file example.conf --name a1 -Dflume.root.logger=INFO,console -DpropertiesImplementation=org.apache.flume.node.EnvVarResolverProperties

警告

上面仅仅是个例子,环境变量可以用其他方式配置,比如在conf/flume-env.sh里面设置。

输出原始数据到日志

通常情况下在生产环境下记录数据流中的原始数据到日志是不可取的行为,因为可能泄露敏感信息或者是安全相关的配置,比如秘钥之类的。默认情况下Flume不会向日志中输出这些信息,如果Flume出了异常,Flume会尝试提供调试错误的线索。

有一个办法能把原始的数据流都输出到日志,就是配置一个额外的内存Channel( Memory Channel ) 和 Logger Sink ,Logger Sink可以输出所有的Event数据到Flume的日志,然而这个方法并不是适用所有情况。

为了记录Event和配置相关的数据,必须设置一些java系统属性在log4j配置文件中。

为了记录配置相关的日志,可以通过-Dorg.apache.flume.log.printconfig=true来开启,可以在启动脚本或者flume-env.sh的JAVA_OPTS来配置这个属性。

通过设置-Dorg.apache.flume.log.rawdata=true来开启记录原始日志,对于大多数组件log4j的日志级别需要设置到DEBUG或者TRACE才能保证日志能输出到Flume的日志里面。

下面这个是开启记录Event原始数据,并且设置logj的日志级别为DEBUG的输出到console的脚本

  1. $ bin/flume-ng agent --conf conf --conf-file example.conf --name a1 -Dflume.root.logger=DEBUG,console -Dorg.apache.flume.log.printconfig=true -Dorg.apache.flume.log.rawdata=true

基于Zookeeper的配置

Flume支持使用Zookeeper配置Agent。这是个实验性的功能。配置文件需要上传到zookeeper中,在一个可配置前缀下。配置文件存储在Zookeeper节点数据里。下面是a1 和 a2 Agent在Zookeeper节点树的配置情况。

  1. - /flume
  2. |- /a1 [Agent config file]
  3. |- /a2 [Agent config file]

上传好了配置文件后,可以使用下面的脚本参数进行启动:

  1. $ bin/flume-ng agent --conf conf -z zkhost:2181,zkhost1:2181 -p /flume --name a1 -Dflume.root.logger=INFO,console

参数名

默认值

描述

z



Zookeeper的连接,hostname:port格式 ,多个用逗号分开

p

/flume

Zookeeper中存储Agent配置的目录

安装第三方插件

Flume有完整的插件架构。尽管Flume已经提供了很多现成的source、channel、sink、serializer可用。

然而通过把自定义组件的jar包添加到flume-env.sh文件的FLUME_CLASSPATH 变量中使用自定义的组件也是常有的事。现在Flume支持在一个特定的文件夹自动获取组件,这个文件夹就是pluguins.d。这样使得插件的包管理、调试、错误定位更加容易方便,尤其是依赖包的冲突处理。

plugins.d文件夹

plugins.d 文件夹的所在位置是 $FLUME_HOME/plugins.d ,在启动时 flume-ng 会启动脚本检查这个文件夹把符合格式的插件添加到系统中。

插件的目录结构

每个插件(也就是 plugins.d 下的子文件夹)都可以有三个子文件夹:

  • lib - 插件自己的jar包

  • libext - 插件依赖的其他所有jar包

  • native - 依赖的一些本地库文件,比如 .so 文件

下面是两个插件的目录结构例子:

  1. plugins.d/
  2. plugins.d/custom-source-1/
  3. plugins.d/custom-source-1/lib/my-source.jar
  4. plugins.d/custom-source-1/libext/spring-core-2.5.6.jar
  5. plugins.d/custom-source-2/
  6. plugins.d/custom-source-2/lib/custom.jar
  7. plugins.d/custom-source-2/native/gettext.so

数据获取方式

Flume支持多种从外部获取数据的方式。

RPC

Flume发行版中包含的Avro客户端可以使用avro RPC机制将给定文件发送到Flume Avro Source:

  1. $ bin/flume-ng avro-client -H localhost -p 41414 -F /usr/logs/log.10

上面的命令会将/usr/logs/log.10的内容发送到监听该端口的Flume Source。

执行命令

Flume提供了一个 Exec Source ,通过执行系统命令来获得持续的数据流,按照\r或者\n或者\r\n(\n\r)来划分数据行,然后把每行解析成为一个Event。

网络流

Flume支持以下比较流行的日志类型读取:

  • Avro

  • Thrift

  • Syslog

  • Netcat

提示

个人认为除了前面的rpc、系统命令、网络流,还有一类很重要的Source就是从文件获取数据,比如 Spooling Directory SourceTaildir Source ,可以用它们来监控应用服务产生的日志并进行收集。

多Agent的复杂流

提示

这一小节介绍了几种典型的Flume的多Agent以及一个Agent中多路输出等部署方式。

两个Agent通过Avro RPC组成了一个多agent流

这个例子里面为了能让数据流在多个Agent之间传输,前一个Agent的sink必须和后一个Agent的source都需要设置为avro类型并且指向相同的hostname(或者IP)和端口。

组合

日志收集场景中比较常见的是数百个日志生产者发送数据到几个日志消费者Agent上,然后消费者Agent负责把数据发送到存储系统。例如从数百个web服务器收集的日志发送到十几个Agent上,然后由十几个Agent写入到HDFS集群。

使用Avro RPC来将所有Event合并到一起的一个扇入流例子

可以通过使用 Avro Sink 配置多个第一层 Agent(Agent1、Agent2、Agent3),所有第一层Agent的Sink都指向下一级同一个Agent(Agent4)的 Avro Source上(同样你也可以使用 thrift 协议的 Source 和 Sink 来代替)。Agent4 上的 Source 将 Event 合并到一个 channel 中,该channel中的Event最终由HDFS Sink 消费发送到最终目的地。

提示

细心的你应该能够发现,这个图中Agent4的Sink画错了,不应该是Avro Sink,应该是HDFS Sink。

多路复用流

Flume支持多路复用数据流到一个或多个目的地。这是通过使用一个流的[多路复用器](multiplexer )来实现的,它可以 复制 或者 选择 数据流到一个或多个channel上。

提示

很容易理解, 复制 就是每个channel的数据都是完全一样的,每一个channel上都有完整的数据流集合。 选择 就是通过自定义一个分配机制,把数据流拆分到多个channel上。

A fan-out flow using a (multiplexing) channel selector

上图的例子展示了从Agent foo扇出流到多个channel中。这种扇出的机制可以是复制或者选择。当配置为复制的时候,每个Event都被发送到3个channel上。当配置为选择的时候,当Event的某个属性与配置的值相匹配时会被发送到对应的channel。

例如Event的属性txnType是customer时,Event被发送到channel1和channel3,如果txnType的值是vendor时,Event被发送到channel2,其他值一律发送到channel3,这种规则是可以通过配置来实现的。

提示

好了做一个总结吧,本章内容是这个文档最重要的一章,让你知道Flume都有哪些组件、配置方式、启动方式、使用第三方插件、以及一些实际使用中的复杂流的部署方案等等。下一章开始逐个介绍每一个组件。