参考:http://flume.apache.org/FlumeUserGuide.html
一、概述
Apache Flume是一个分布式的、可靠的、可用的系统,用于从许多不同的数据源高效的收集大容量的日志数据,聚合并传输到一个集中的数据存储。
Apache Flume并不局限于日志数据的聚合。由于数据源是可定制的,Flume可用于传输多种事件数据,包括但不限于网络通信数据、社交媒体数据、邮件信息等。
Apache Flume是Apache软件基金会的*项目。
Flume目前有两个系列,0.9.x和1.x,其中0.9.x也称为flume-og(Flume original generation),1.x也称为flume-ng(Flume next generation)。
学习笔记基于flume 1.6.0,即flume-ng(当初看到这个词,还以为是nginx的一个插件呢)。
二、架构
2.1 数据流
一个Flume事件定义如下:一个有有效载荷和可选字符串类型属性的数据单元。一个Flume代理是一个JVM进程,来主持元素从外部来源流到下一站的整个事件。
Flume source消费的事件通常来源于外部源,如web服务。外部源以一种flume source认识的格式传输事件,如Avro、Thrift等。当flume source收到一个事件,会将其保存到一个或多个channel中,channel是一个被动的存储——会保存事件直到被flume sink消费。sink将事件从channel中移除,并放到一个外部存储(如HDFS),或转发到下一个flume代理的source。事件在source和sink上是异步执行的。
2.2 复合流
Flume允许多种流的组合方式,比如多个代理相连,扇入扇出流,容错(备用路由)等。
2.3 可靠性
每个代理的事件是保存在channel上的。事件通过流被传递到下一个代理或目标存储(如HDFS)。事件仅当被保存到了下一个channel或目标存储,才会从当前channel中移除。这就是单hop消息传递语义中Flume流的端对端的可靠性。
Flume使用事务机制来保证事件传输的可靠性。source和sink被封装在一个事务中,事件保存在channel中或由channel提供。这保证了事件点对点传输的可靠性。对于多hop的流,前一个hop的sink和下一个hop的source都有自己的事务,以保证数据可以安全存储在下一个hop的channel中。
2.4 恢复性
事件保存在channel中,其负责失败恢复。Flume支持基于本地文件系统的持久文件channel,同时还有可以将事件保存到内存队列的内存channel中。这种方式更快,但是代理死掉的时候,仍在内存channel中的事件就无法恢复了。
三、配置
3.1 设置并启动一个agent
每个组件(source、sink、channel)都是独立配置的,有名字、类型和特有的属性信息。这些信息都写在一个java风格的配置文件中,如下面这个例子:
# example.conf: A single-node Flume configuration
# Name the components on this agent
a1.sources = r1
a1.sinks = k1
a1.channels = c1
# Describe/configure the source
a1.sources.r1.type = netcat
a1.sources.r1.bind = localhost
a1.sources.r1.port = 44444
# Describe the sink
a1.sinks.k1.type = logger
# Use a channel which buffers events in memory
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100
# Bind the source and sink to the channel
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1
配置定义了一个名为a1的代理。a1有一个监听44444端口的source,一个在内存中缓存事件数据的channel,一个在屏幕输出事件数据的sink。配置文件首先定义了各个组件,然后描述了组件的类型和对应的配置参数,最后将source和sink与channel关联起来。一个配置文件中可以配置多个代理,在启动Flume的时候需要告诉使用哪些代理。
配置完毕后,可以用下面的命令启动:
$ bin/flume-ng agent --conf conf --conf-file example.conf --name a1 -Dflume.root.logger=INFO,console
如果是完全部署,可能需要指定配置目录:--conf=<conf-dir>。<conf-dir>目录可能包含一个shell脚本flume-env.sh以及log4j.properties配置文件。在本示例中传递了一个java选项,将日志打在屏幕上,且没有使用自定义的环境配置脚本。
打开另一个终端,使用telnet可以向Flume发送事件:
$ telnet localhost 44444
在之前运行的Flume终端上会将事件输出出来,如下:
3.2 基于zookeeper的配置
Flume支持通过zookeeper配置,不过还是一个实验性的功能。配置文件需要先上传到zookeeper,然后进行配置,如:
- /flume
|- /a1 [Agent config file]
|- /a2 [Agent config file]
配置完成后,就可以用下面的命令来启动:
$ bin/flume-ng agent –conf conf -z zkhost:2181,zkhost1:2181 -p /flume –name a1 -Dflume.root.logger=INFO,console看到这个,我就在想,怎么把配置文件上传到zookeeper上去,搜了半天,发现solr有个工具可以上传,不过没有去尝试,感兴趣的同学可以看看,附上链接: https://cwiki.apache.org/confluence/display/solr/Using+ZooKeeper+to+Manage+Configuration+Files
3.3 第三方插件
Flume是完全基于插件的体系结构,并且可以自动加载放在plugins.d目录中的插件。
plugins.d目录下每个插件可以有三个目录,含义如下:
- lib - 插件的jar包
- libext - 插件的依赖jar包
- native - 本地依赖,如.so文件
四、数据获取
Flume支持多种数据获取的方式。
4.1 RPC
可通过内置的avro客户端,使用avro RPC机制,将文件发送到Flume Avro source:
$ bin/flume-ng avro-client -H localhost -p 44444-F /tmp/log
使用这种方式,需要将source的类型改为avro,以上面的配置文件为例,需要修改的信息如下:
a1.sources.r1.type = avro然后和上面一样,启动flume代理,再执行本小节的命令。
假设/tmp/log文件中的内容为hello flume,运行结果截图如下:
代理输出:
4.2 命令行
有一个exec source,可以消费命令行的执行结果。每行以\r或\n或两者的组合结束。注意:Flume不支持将tail命令的结果作为source,不过可以包装后使用。
4.3 网络流
Flume支持以下机制,从流行的日志系统读取数据:
- Avro
- Thrift
- Syslog
- Netcat
五、多agent的组合
5.1 配置多agent的流
为了使数据可以在多个代理或hop传输,前一个代理的sink和当前hop的source需要是avro类型,如图所示。
5.2 合并
在日志收集中比较常见的场景是大量产生日志的客户端将数据发送到少量的代理,代理连接着存储子系统,如图所示。
在Flume中,可以通过配置第一组代理的sink为avro类型,并指向唯一的一个source为avro类型的代理来实现。这个代理将收到的数据合并,然后通过channel交由sink,到达最终的目的地。
5.3. 流的复用
Flume支持将事件分发到一个或多个目的地。可以通过定义channel到多个不同的sink来实现。
上图展示了代理foo的source扇出到三个不同的channel中。扇出的方式可以是复制,也可以是复用。当为复制时,每个事件都传输到三个channel中。当为复用时,事件被传输到事件属性满足预设值的channel中(通常是一个子集)。
这次学习就到这里,关于各种source、sink、channel、interceptor这里就不再介绍了。
后面计划根据代码来学习Flume的这种设计机制,并分析其中几种source、sink与channel。