目录
本文仅用于学习记录总结所用,配置方面有大量参考官方文档,以方便查阅,不喜勿喷。
Flume可以说是配置型框架,通过简单的配置实现数据的收集和发送,比较简单,所以建议大家学习Flume还是学会看官方文档。
一、Flume简介
Flume是一个分布式的,可靠的,高可用的海量日志采集,聚合和传输的系统。它也是Hadoop生态圈中的关键组件之一。
Flume通过可扩展,插件化,组合式,高可用,高容错的设计模式,为用户提供了高效准确的轻量化大数据采集工具。
Flume可以通过简单的配置,收集不同数据源的海量数据,并将数据准确,高效的传入到不同中心存储里面。目前Flume可以对接主流的大数据框架有,Hadoop,Kafka,Spark等。
在使用Flume的过程中,通过配置文件就可以实现整个数据收集过程的负载均衡和故障转移,整个流程不需要修改Flume的任何代码。Flume具有的这些优良的特性,得益于它优秀的架构设计。
Apache 官方的简介
Apache Flume是一个分布式,可靠且可用的系统,用于有效地收集,聚合大量日志数据并将其从许多不同的源移动到集中式数据存储中。
Apache Flume的使用不仅限于日志数据聚合。由于数据源是可定制的,因此Flume可用于传输大量事件数据,包括但不限于网络流量数据,社交媒体生成的数据,电子邮件消息以及几乎所有可能的数据源。
Apache Flume是Apache Software Foundation的顶级项目。
二、Flume架构
Flume事件定义为具有字节有效负载和可选字符串属性集的数据流单位。Flume是使用Java开发的,它的代理是一个(JVM)进程,承载了组件,Event通过这些组件从外部源流到下一个目标(hop)。
2.1 Flume基本组件
Event:数据消息的基本单位,有header(键值对)和body(字节数组)组成。
Agent:Flume 运行的核心是 Agent。Flume以agent为最小的独立运行单位。一个agent就是一个JVM。它是一个完整的数据收集工具,含有三个核心组件,分别是source、 channel、 sink。通过这些组件, Event 可以从一个地方流向另一个地方
一个Agent包括Source、Channel和Sink,还有一些可选的组件(稍后会介绍),如下图所示。
组件 1 --> Source : 从外部来源读取Event,并写入到Channel当中。
组件 2 --> Channel : Event临时存储组件,Source写入后,Event将会一直保存,直到被Sink成功消费。
组件 3 --> Sink :从Channel读取Event,并写入目的地。
其实在Agent里面我们还可以配置三个可选的组件,分别是Interceptor(拦截器),Selector(选择器),SinkProcessor(event处理器)。
可选组件 1 --> Interceptor(拦截器):可以处理Event中的header信息,可以在Header中添加消息处理的时间戳,还可以添加主机名称,还有一些静态值,也可以根据正则表达式对Event进行过滤,选择那些Event可以继续向后进行传输,也可以决定哪些Event被删除,停止向后传输。Interceptor可以配置多个,多个Interceptor可以顺序执行
可选组件 2 --> Selector(多路复用选择器):Interceptor处理完Event之后会传输给Selector(选择器)。选择器的作用是选择哪种方式把Event写入到Channel当中。
可选组件 3 --> SinkProcessor(event处理器):当Sink从Channel中消费消息之前,可以选择SinkProcessor(event处理器),根据配置可以选择使用故障转移处理器或者负载均衡处理器。然后进Sink消费消息。
2.2 Flume常见数据流模型
2.2.1 基本数据流模型
Flume启动一个Agent,通过Source从外部数据源(如Web服务器)对数据消息(Event)进行采集,然后放在Channel当中临时存储,由Sink从Channel里面进行消费消息,写入到HDFS里面进行持久化存储。
2.2.2 多Agent的复杂流
日志收集中的一种非常常见的情况是,大量的日志生成,客户端将数据发送到连接存储子系统的几个消费者代理。例如,从数百台Web服务器收集的日志发送到许多写入HDFS群集的代理。其中用到的主要架构是多级的Flume流:如下图所示
下面我们举个例子来说明生产中常见的使用场景:
说明:收集多个节点的服务器数据,然后进行汇总,汇总之后再进行持久化存储。(如下图所示)
有三个WebServer服务器分别产生数据,针对这三台服务器分别启动三个Agent,Agent1,Agent2,Agent3对应三个WebServer,每个Agent负责收集对应服务器产生的数据消息(Event),收集完之后,这三个Agent再Sink阶段,都把数据发送到了Agent4,Agent4的作用是负责收集其他三个Agent输出的数据,并把收集到的所有数据写入到HDFS当中。
这里我们看出,Agent不仅可以和外部的数据源和外部的存储机制进行连接,在多个Agent之间也是可以进行连接的,可以根据不同的使用场景对Agent进行灵活的组合。
2.2.3 多路复用流
Flume还支持将Event流复用到一个或多个目的地。这是通过定义一种流多路复用器来实现的,该流多路复用器可以将Event复制或选择性地路由到一个或多个通道。
这个数据流是将不同类型的数据流写入到不同的Channel当中,然后不通的Channel对应的Sink将收集到的数据消息(Event)输出到不同的目的地。
三、Source,Channel,Sink 详解
3.1 Source
对接各种外部数据源,将收集到的Event发送到Channel中,一个Source可以向多个Channel发送Event,Flume内置非常丰富的Source,同时用户可以自定义Source。
篇幅原因,这里只介绍集中常见的Source,其他的可以区官网自行查看。
3.1.1 Avro Source
flume可以多级代理,然后代理与代理之间用Avro去连接。也就是Avro Source可以和上一个Agent进行连接。
Avro Source监听Avro端口接收从外部Avro客户端发送来的数据流。如果与上一层Agent的 Avro Sink 配合使用就组成了一个分层的拓扑结构。 必需的参数已用 粗体 标明。
属性 | 默认值 | 解释 |
---|---|---|
channels | – | 与Source绑定的channel,多个用空格分开 |
type | – | 组件类型,这个是: avro |
bind | – | 监听的服务器名hostname或者ip |
port | – | 监听的端口 |
threads | – | 生成的最大工作线程数量 |
selector.type | 可选值:replicating 或 multiplexing ,分别表示: 复制、多路复用 |
|
selector.* | channel选择器的相关属性,具体属性根据设定的 selector.type 值不同而不同 | |
interceptors | – | 该source所使用的拦截器,多个用空格分开 |
interceptors.* | 拦截器的相关属性 | |
compression-type | none | 可选值: none 或 deflate 。这个类型必须跟Avro Source相匹配 |
ssl | false | 设置为 true 可启用SSL加密,如果为true必须指定下面的 keystore 和 keystore-password 。 |
keystore | – | SSL加密使用的Java keystore文件路径 |
keystore-password | – | Java keystore的密码 |
keystore-type | JKS | Java keystore的类型. 可选值有 JKS 、 PKCS12 。 |
exclude-protocols | SSLv3 | 指定不支持的协议,多个用空格分开,SSLv3不管是否配置都会被强制排除 |
ipFilter | false | 设置为true可启用ip过滤(netty方式的avro) |
ipFilterRules | – | netty ipFilter的配置(参考下面的ipFilterRules详细介绍和例子) |
官网配置举例参考:http://flume.apache.org/releases/content/1.9.0/FlumeUserGuide.html#avro-source
中文翻译版参考:https://flume.liyifeng.org/#avro-source
3.1.2 Thrift Source
ThriftSource 与Avro Source 基本一致。只要把source的类型改成thrift即可,例如a1.sources.r1.type = thrift 。
监听Thrift 端口,从外部的Thrift客户端接收数据流。如果从上一层的Flume Agent的 Thrift Sink 串联后就创建了一个多层级的Flume架构(同 Avro Source 一样,只不过是协议不同而已)。Thrift Source可以通过配置让它以安全模式(kerberos authentication)运行,具体的配置看下表。 必需的参数已用 粗体 标明。
属性 | 默认值 | 解释 |
---|---|---|
channels | – | 与Source绑定的channel,多个用空格分开 |
type | – | 组件类型,这个是: thrift |
bind | – | 监听的 hostname 或 IP 地址 |
port | – | 监听的端口 |
threads | – | 生成的最大工作线程数量 |
selector.type | 可选值:replicating 或 multiplexing ,分别表示: 复制、多路复用 |
|
selector.* | channel选择器的相关属性,具体属性根据设定的 selector.type 值不同而不同 | |
interceptors | – | 该source所使用的拦截器,多个用空格分开 |
interceptors.* | 拦截器的相关属性 | |
ssl | false | 设置为true可启用SSL加密,如果为true必须指定下面的keystore和keystore-password。 |
keystore | – | SSL加密使用的Java keystore文件路径 |
keystore-password | – | Java keystore的密码 |
keystore-type | JKS | Java keystore的类型. 可选值有 JKS 、 PKCS12 |
exclude-protocols | SSLv3 | 排除支持的协议,多个用空格分开,SSLv3不管是否配置都会被强制排除 |
kerberos | false | 设置为 true ,开启kerberos 身份验证。在kerberos模式下,成功进行身份验证需要 agent-principal 和 agent-keytab 。 安全模式下的Thrift仅接受来自已启用kerberos且已成功通过kerberos KDC验证的Thrift客户端的连接。 |
agent-principal | – | 指定Thrift Source使用的kerberos主体用于从kerberos KDC进行身份验证。 |
agent-keytab | —- | Thrift Source与Agent主体结合使用的keytab文件位置,用于对kerberos KDC进行身份验证。 |
官网配置举例参考:http://flume.apache.org/releases/content/1.9.0/FlumeUserGuide.html#thrift-source
中文翻译版参考:https://flume.liyifeng.org/#thrift-source
3.1.3 Exec Source
执行Unix命令,获取标准输出,例如:tail -f 。
这个source在启动时运行给定的Unix命令,并期望该进程在标准输出上连续生成数据(stderr 信息会被丢弃,除非属性 logStdErr 设置为 true )。 如果进程因任何原因退出, 则source也会退出并且不会继续生成数据。 综上来看cat [named pipe]或tail -F [file]这两个命令符合要求可以产生所需的结果,而date这种命令可能不会,因为前两个命令(tail 和 cat)能产生持续的数据流,而后者(date这种命令)只会产生单个Event并退出。
提示:
cat [named pipe]和tail -F [file]都能持续地输出内容,那些不能持续输出内容的命令不可以。这里注意一下cat命令后面接的参数是命名管道(named pipe)不是文件。
必需的参数已用 粗体 标明。
属性 | 默认值 | 解释 |
---|---|---|
channels | – | 与Source绑定的channel,多个用空格分开 |
type | – | 组件类型,这个是: exec |
command | – | 所使用的系统命令,一般是cat 或者tail |
shell | – | 设置用于运行命令的shell。 例如 / bin / sh -c。 仅适用于依赖shell功能的命令,如通配符、后退标记、管道等。 |
restartThrottle | 10000 | 尝试重新启动之前等待的时间(毫秒) |
restart | false | 如果执行命令线程挂掉,是否重启 |
logStdErr | false | 是否会记录命令的stderr内容 |
batchSize | 20 | 读取并向channel发送数据时单次发送的最大数量 |
batchTimeout | 3000 | 向下游推送数据时,单次批量发送Event的最大等待时间(毫秒),如果等待了batchTimeout毫秒后未达到一次批量发送数量,则仍然执行发送操作。 |
selector.type | replicating | 可选值:replicating 或 multiplexing ,分别表示: 复制、多路复用 |
selector.* | channel选择器的相关属性,具体属性根据设定的 selector.type 值不同而不同 | |
interceptors | – | 该source所使用的拦截器,多个用空格分开 |
interceptors.* | 拦截器相关的属性配置 |
警告
ExecSource相比于其他异步source的问题在于,如果无法将Event放入Channel中,ExecSource无法保证客户端知道它。在这种情况下数据会丢失。例如,最常见的用法是用tail -F [file]这种,应用程序负责向磁盘写入日志文件, Flume 会用tail命令从日志文件尾部读取,将每行作为一个Event发送。这里有一个明显的问题:如果channel满了然后无法继续发送Event,会发生什么?由于种种原因,Flume无法向输出日志文件的应用程序指示它需要保留日志或某些Event尚未发送。 总之你需要知道:当使用ExecSource等单向异步接口时,您的应用程序永远无法保证数据已经被成功接收!作为此警告的延伸,此source传递Event时没有交付保证。为了获得更强的可靠性保证,请考虑使用 Spooling Directory Source, Taildir Source 或通过SDK直接与Flume集成。
官网配置举例参考:http://flume.apache.org/releases/content/1.9.0/FlumeUserGuide.html#exec-source
中文翻译版参考:https://flume.liyifeng.org/#exec-source
3.1.4 JMS Source
从JMS源获取数据。
JMS Source是一个可以从JMS的队列或者topic中读取消息的组件。按理说JMS Source作为一个JMS的应用应该是能够与任意的JMS消息队列无缝衔接工作的,可事实上目前仅在ActiveMQ上做了测试。 JMS Source支持配置batch size、message selector、user/pass和Event数据的转换器(converter)。 注意所使用的JMS队列的jar包需要在Flume实例的classpath中,建议放在专门的插件目录plugins.d下面,或者启动时候用-classpath指定,或者编辑flume-env.sh文件的FLUME_CLASSPATH来设置。
必需的参数已用 粗体 标明。
属性 | 默认值 | 解释 |
---|---|---|
channels | – | 与Source绑定的channel,多个用空格分开 |
type | – | 组件类型,这个是: jms |
initialContextFactory | – | 初始上下文工厂类,比如: org.apache.activemq.jndi.ActiveMQInitialContextFactory |
connectionFactory | – | 连接工厂应显示为的JNDI名称 |
providerURL | – | JMS 的连接URL |
destinationName | – | 目的地名称 |
destinationType | – | 目的地类型, queue 或 topic |
messageSelector | – | 创建消费者时使用的消息选择器 |
userName | – | 连接JMS队列时的用户名 |
passwordFile | – | 连接JMS队列时的密码文件,注意是文件名不是密码的明文 |
batchSize | 100 | 消费JMS消息时单次发送的Event数量 |
converter.type | DEFAULT | 用来转换JMS消息为Event的转换器类,参考下面参数。 |
converter.* | – | 转换器相关的属性 |
converter.charset | UTF-8 | 转换器把JMS的文本消息转换为byte arrays时候使用的编码,默认转换器的专属参数 |
createDurableSubscription | false | 是否创建持久化订阅。 持久化订阅只能在 destinationType = topic 时使用。 如果为 true ,则必须配置 clientId 和 durableSubscriptionName。 |
clientId | – | 连接创建后立即给JMS客户端设置标识符。持久化订阅必配参数。 |
durableSubscriptionName | – | 用于标识持久订阅的名称。持久化订阅必配参数。 |
官网配置举例参考:http://flume.apache.org/releases/content/1.9.0/FlumeUserGuide.html#jms-source
中文翻译版参考:https://flume.liyifeng.org/#jms-source
3.1.5 Spooling Directory Source
监听目录下的新增文件。
这个Source允许你把要收集的文件放入磁盘上的某个指定目录。它会将监视这个目录中产生的新文件,并在新文件出现时从新文件中解析数据出来。数据解析逻辑是可配置的。在新文件被完全读入Channel之后会重命名该文件以示完成(也可以配置成读完后立即删除)。
与Exec Source不同,Spooling Directory Source是可靠的,即使Flume重新启动或被kill,也不会丢失数据。同时作为这种可靠性的代价,指定目录中的文件必须是不可变的、唯一命名的。Flume会自动检测避免这种情况发生,如果发现问题,则会抛出异常:
-
如果文件在写入完成后又被再次写入新内容,Flume将向其日志文件(这是指Flume自己logs目录下的日志文件)打印错误并停止处理。
-
如果在以后重新使用以前的文件名,Flume将向其日志文件打印错误并停止处理。
为了避免上述问题,生成新文件的时候文件名加上时间戳是个不错的办法。
尽管有这个Source的可靠性保证,但是仍然存在这样的情况,某些下游故障发生时会出现重复Event的情况。这与其他Flume组件提供的保证是一致的。
属性名 | 默认值 | 解释 |
---|---|---|
channels | – | 与Source绑定的channel,多个用空格分开 |
type | – | 组件类型,这个是: spooldir . |
spoolDir | – | Flume Source监控的文件夹目录,该目录下的文件会被Flume收集 |
fileSuffix | .COMPLETED | 被Flume收集完成的文件被重命名的后缀。1.txt被Flume收集完成后会重命名为1.txt.COMPLETED |
deletePolicy | never | 是否删除已完成收集的文件,可选值: never 或 immediate |
fileHeader | false | 是否添加文件的绝对路径名(绝对路径+文件名)到header中。 |
fileHeaderKey | file | 添加绝对路径名到header里面所使用的key(配合上面的fileHeader一起使用) |
basenameHeader | false | 是否添加文件名(只是文件名,不包括路径)到header 中 |
basenameHeaderKey | basename | 添加文件名到header里面所使用的key(配合上面的basenameHeader一起使用) |
includePattern | ^.*$ | 指定会被收集的文件名正则表达式,它跟下面的ignorePattern不冲突,可以一起使用。如果一个文件名同时被这两个正则匹配到,则会被忽略,换句话说ignorePattern的优先级更高 |
ignorePattern | ^$ | 指定要忽略的文件名称正则表达式。它可以跟 includePattern 一起使用,如果一个文件被 ignorePattern 和 includ |