一、简介:
Flume是一个分布式,可靠可用性高的日志收集系统,能够采集,集合和传输数据,采用数据流模式。核心概念有事件与进程,事件由数据单元,消息头与消息体组成。进程由source,channel与sink组成。
Flume的优势在于它可以将数据发送到任何集中存储器上,其次当数据收集速度超过数据写入速度时,系统会自行做出调整,在数据生产者与数据收容器之间形成平衡。一共有三种级别的可靠性保障以及三种架构,分别为agent,collector与storage
二、数据流:
Flume的核心是数据流,将数据从数据源收集过来,再发送到目的地,为了保证发送数据一定成功,在数据真正到达目的地之前,会本地缓存数据,待数据到达目的地后,再删除缓存数据,数据的基本单位是事件,从外部数据源进来,再流到外部目的地。
2.1 source:
source是数据收集组件,负责将数据捕获后进行特殊的格式化,将数据封装到事件中,再将事件推送到channel,同时Flume提供了许多内置的source。Source的配置必须包括type,bind与port以及关联channel
2.2 channel:
channel是连接source和sink的组件,也可看做一个数据的缓冲区,它能够将数据暂存到内存中,也可以持久化到磁盘上。并且。它可以和任意数量的source和sink匹配,进行数据的并行连接并能够保持数据的一致性。
2.3 sink:
sink从channel中取出事件,再将数据发送到别处,可以向文件系统,数据库,hadoop存数据。当日志数据较少时,将数据存在文件系统,且设置一定的时间间隔保存数据;当日志数据较多时,将数据存到hadoop中,便于进行数据分析。Sink的配置必须包括type,bind与port以及关联channel。Flume提供了大量的内置的source,channel与sink,不同的类型也可以自由组合,组合方式基于用户的配置方式。
2.4 创建实例1:
创建一个名为a1的agent,分别定义它的三种成分,source监听本地主机44444端口的数据,channel缓冲数据到内存,sink表示写到日志文件,并传送到控制台的接收器,并将source与sink的channel关联起来
a1.sources = r1
a1.sinks = k1
a1.channels = c1
a1.sources.r1.type = netcat
a1.sources.r1.bind = localhost
a1.sources.r1.port = 44444
a1.sinks.k1.type = logger
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1
2.5 数据流模型:
2.6 多个数据流顺序连接:
为了跨多个代理传递数据流,前一个代理的sink和当前跳转的source必须是avro类型
2.7 数据整合:
大量的日志生成客户机将数据发送给几个客户代理,这些代理再将数据写入HDFS集群,即将多个agent的数据整合到一个agent,形成多路复用流
2.8多级流:
当syslog, java, nginx与 tomcat等混合在一起的日志流一起流入一个agent里时,系统会给每一种日志建立单独的传输通道
2.9 创建实例2:
一个source可以指向多个channel,而一个sink只能对应一个channel
<Agent>.sources = <Source>
<Agent>.sinks = <Sink>
<Agent>.channels = <Channel1> <Channel2>
<Agent>.sources.<Source>.channels = <Channel1> <Channel2> ...
<Agent>.sinks.<Sink>.channel = <Channel1>``
三、优势:
3.1 安全性:
HDFS接收器,HBase接收器,Thrift源,Thrift接收器与Kite Dataset接收器都支持身份验证。Flume验证将作为单个主体对kerberos KDC进行身份验证,这将由需要进行身份验证的不同组件使用,为Thrift源,Thrift接收器,HDFS接收器,HBase接收器和Dataset接收器配置的主体和keytab应该是相同的,否则组件将无法启动
3.2 流量可靠性:
Flume具有持久通道和非持久通道,持久通道即将数据保存到磁盘,而非持久通道即若机器出现故障则丢失数据,持久通道使用基于磁盘的存储,存储在此类通道中的数据将在机器重启持续存在。Flume中的通道充当各种跳跃的缓冲区,这些缓冲区具有固定容量,一旦容量已满,则较早节点受到压力,若压力传播到流量源,则Flume不可用并可能丢失数据。Flume可以在冗余拓扑中复制流,即提供非常容易的容错源,并且可以克服磁盘或机器故障,在拓扑中考虑可靠性的最佳方法是考虑各种故障情况及其结果
四、扇出流:
Flume支持将一个源分散到多个通道,扇出有两种模式,分别是复制和多路复用,在复制流中,数据被发送到每个通道;在多路复用流中,数据只被发送到限定通道的子集。若要扇出流,需要指定源的通道列表和扇出源的策略。即同一事件从一个source经不同channel发送到不同sink中
扇出的多路选择器具有进一步的一组属性来分叉流,这需要为通道制定一个事件属性的映射,系统检查事件头中的每个配置属性,若匹配值,将发送到相应通道,若不匹配。则发送到默认通道
五、常用器:
5.1 拦截器:
当我们需要对数据进行过滤时,除了对三个组件的代码部分进行修改外,还可以设置拦截器,拦截器只能设置在source与channel之间,拦截器为chain形式,当我们为source设置拦截器后,系统决定是否传递数据,若决定抛弃,则数据不会进入channel
1.Flume Interceptors:
使得能够在飞行中修改或者删除事件,通过在配置中指定拦截器构建器类名列表,指定拦截器的顺序是它们被调用的顺序,一个拦截器返回的事件列表将传递给链中的下一个拦截器
示例:
agent.sources.sources1.interceptors = i1 i2
agent.sources.sources1.interceptors.i1.type = host
agent.sources.sources1.interceptors.i1.useIP = false
agent.sources.sources1.interceptors.i1.hostHeader = agentHost
agent.sources.sources1.interceptors.i2.type = timestamp
2.Timestamp Interceptor:
将时间插入到事件标头中,以毫秒为单位处理事件,如果配置中已存在时间戳,此拦截器可以保留现有时间戳
示例:
a1.sources=r1
a1.channels=c1
a1.sources.r1.channels= c1
a1.sources.r1.type=seq
a1.sources.r1.interceptors=i1
a1.sources.r1.interceptors.i1.type=timestamp
3.Static Interceptor:
允许用户将具有静态值的静态头附加到所有事件,用户可能会链接到多个静态拦截器4.Morphline Interceptor通过配置文件来过滤事件,该文件定义了一系列转换命令,用于将记录从一个命令传送到另一个命令,可以忽略某些事件或通过基于正则表达式的模式匹配来更改或插入某些事件标头,但存在的限制为拦截器的形态线不能为每个输入事件生成多个输出记录
示例:
agent.sources.sources1.interceptors = i1
agent.sources.sources1.interceptors.i1.type = static
agent.sources.sources1.interceptors.i1.preserveExisting = true
agent.sources.sources1.interceptors.i1.key = static_key
agent.sources.sources1.interceptors.i1.value = static_value
4.Search and Replace Interceptor:
基于Java正则表达式提供简单的基于字符串的搜索和替换功能
5.Regex Filtering Interceptor:
通过将事件主体解释为文本并将文本与已配置的正则表达式匹配来有选择地过滤事件,提供的正则表达式可用于包括事件或排除事件
示例:
a1.sources.r1.interceptors = i1
a1.sources.r1.interceptors.i1.type =regex_filter
a1.sources.r1.interceptors.i1.regex =^[0-9]*$
a1.sources.r1.interceptors.i1.excludeEvents =true
6.Host Interceptor:
主机名拦截器。将运行Flume agent的主机名或者IP地址加入到events header中,key名字为:host(也可自定义)
示例:
agent.sources.sources1.interceptors = i1
agent.sources.sources1.interceptors.i1.type = host
agent.sources.sources1.interceptors.i1.useIP = false
agent.sources.sources1.interceptors.i1.hostHeader = agentHost
5.2 事件序列化器:
1.Body Text Serializer:
将事件的主体写入输出流,而不进行任何转换或者修改,事件标题将被忽略
示例:
a1.sinks=k1
a1.sinks.k1.type=file_roll
a1.sinks.k1.channel=c1
a1.sinks.k1.sink.directory=/var/log/flume
a1.sinks.k1.sink.serializer=text
a1.sinks.k1.sink.serializer.appendNewline=false
2.Flume Event”Avro Event Serializer:
将事件序列化为Avro容器文件,使用的模式与Avro RPC机制中用于Flume事件的模式相同
示例:
a1.sinks.k1.type=hdfs
a1.sinks.k1.channel=c1
a1.sinks.k1.hdfs.path=/flume/events/%y-%m-%d/%H%M/%S
a1.sinks.k1.serializer=avro_event
a1.sinks.k1.serializer.compressionCodec=snappy
3.Avro Event Serializer:
将Flume事件序列化为Avro容器文件,但记录模式是可配置的
示例:
a1.sinks.k1.type=hdfs
a1.sinks.k1.channel=c1
a1.sinks.k1.hdfs.path=/flume/events/%y-%m-%d/%H%M/%S
a1.sinks.k1.serializer=avro_event
a1.sinks.k1.serializer.compressionCodec=snappy
5.3 事件反序列化器:
事件反序列化器随Flume一起提供,LINE为每行文本输入生成一个事件,AVRO则读取AVRO容器里的文件,并为文件里的每一个AVRO记录生成一个事件,Blob Deserializer为每一个记录提供尔二进制大对象
5.4 通道选择器:
若未指定类型,则默认为Replicating Chnnel Selector,而Multiplexing Channel Selector主要实现的功能是完成依据指定的标准选择通道,完成一个多路的agent,最后一种即Custom Channel Selector是自己的接口实现,启动Flume代理时,自定义通道选择器的类及其依赖项必须包含在代理程序的类路径中
5.5 Flume Sink 处理器:
接受组允许用户将多个接收器分组到一个实体中,接收器处理器可用于在组内的所有接收器上提供负载平衡的功能,或在时间故障的情况下实现从一个接收器到另一个接收器的故障转移。默认接收处理器只接受一个接收器,用户不必为单个接收器创建处理器
1.Failover Sink Processor:
维护一个优先级的接收器列表,保证只要有一个可用的事件将被处理。原理是将故障接收器降级到池中,在池中为它们分配一个冷却期,在重试之前随顺序故障而增加,接收器成功发送事件后,将恢复到实时池中
2.Load balancing Sink Processor:
提供了在多个接收器上进行负载均衡流量的功能,它维护一个索引的活动接收器列表,必须在其上分配负载,调用时,此选择器使用其配置的选择机制选择下一个接收器并调用它,若所选接收器无法传递事件,则处理器继续尝试每一个可试的接收器,若所有接收器调用都失败,则选择器将故障传播到接收器运行器。最后,对于自定义接收处理器,目前Flume暂时是不支持的
六、Log4j追加:
将Log4j事件附加到flume代理的avro源,使用的客户端必须是在类路径中包含flume-ng-sdk,而负载均衡Log4j追加即将Log4j事件追加到flume agent的avro源列表,使用的客户端同上包含路径,支持循环和随机方案,用于执行负载平衡,并且还可以支持可配置的退避超时,以便从主机临时删除向下代理
七、报告:
1.JMX报告:
通过使用flume-env.sh在环境变量中指定JMX参数来启用JMX报告,
2.Ganglia报告:
是Flume将这些指标报告给元节点,要想启动Ganglia报告指标,则必须使用支持的Sink代理
3.JSON报告:
为了以JSON模式启用报告,可在可配置端口上托管Web服务器,最后是自定义报告,通过编写可执行报告的服务器向其他系统报告度量标准,任何报告都必须实现org.apache.flume.instrumentation.MotionService接口,这样的类可以轮询平台mbean服务器以轮询mbeans以获取指标
八、工具:
Flume非常灵活,允许大量可能的部署方案,若计划在 大量生产部署中使用Flume,那么最好考虑根据Flume拓扑来表达问题
1.文件通道完整性工具:
它验证文件通道中各个事件的完整性,并删除损坏的事件
2.事件验证工具:
可用于特定于应用程序的方式验证文件通道事件,该工具在每个事件应用用户提供程序验证登录,并删除未向逻辑确认的事件。事件验证器必须实现EventValidator接口,建议不要从实现中抛出任何异常,因为会被视为无效事件
九、常见组件:
1.HDFS Sink:
这个接收器将事件写入Hadoop分布式文件系统(HDFS)。它目前支持创建文本和序列文件。它支持两文件类型的压缩。可以根据数据的运行时间、大小或事件的数量周期性地滚动文件(关闭当前文件并创建新文件)。它还根据事件发生的时间戳或机器等属性对数据进行分段或分区。HDFS目录路径可能包含格式化转义序列,这些转义序列将被HDFS接收器替换为生成一个目录/文件名来存储事件。使用这个接收器需要安装hadoop,以便Flume可以使用hadoop jar与HDFS集群通信。注意,需要一个支持sync()调的Hadoop版本
实例:
a1.channels = c1
a1.sinks = k1
2.Avro Source:
主要的RPC Source,其高扩展性结合channel充当了缓冲器这一角色,能够处理重要的峰值数据。同时可以配置可以从已经配置好的Avro Sink接受压缩事件的功能。监听Avro端口并从外部Avro客户端流接收事件。当与另一个(前一跳)水槽代理上的内置Avro接收器配对时,它可以创建分层集合拓扑
实例:
a1.sources = r1
a1.channels = c1
a1.sources.r1.type = avro
a1.sources.r1.channels = c1
a1.sources.r1.bind = 0.0.0.0
a1.sources.r1.port = 4141
3.Thrift Source:
侦听Thrift端口,并从外部Thrift客户端接受事件流,当与上一个代理配置的Thrift Sink配对时,可以创建分层集合拓扑。可以通过启用身份验证将源设置为安全模式启动
实例:
a1.sources = r1
a1.channels = c1
a1.sources.r1.type = thrift
a1.sources.r1.channels = c1
a1.sources.r1.bind = 0.0.0.0
a1.sources.r1.port = 4141
4.Twitter 1% firehose Source:
此来源为高度实验性,通过API连接到实验源,不断下载推文,并将它们转换为AVRO格式,再将AVRO事件下载到Flume接收器端,需要消费者访问Twitter开发者账户的令牌和密匙
实例:
a1.sources = r1
a1.channels = c1
a1.sources.r1.type = org.apache.flume.source.twitter.TwitterSource
a1.sources.r1.channels = c1
a1.sources.r1.consumerKey = YOUR_TWITTER_CONSUMER_KEY
a1.sources.r1.consumerSecret = YOUR_TWITTER_CONSUMER_SECRET
a1.sources.r1.accessToken = YOUR_TWITTER_ACCESS_TOKEN
a1.sources.r1.accessTokenSecret = YOUR_TWITTER_ACCESS_TOKEN_SECRET
a1.sources.r1.maxBatchSize = 10
a1.sources.r1.maxBatchDurationMillis = 200
5.NetCat Tcp Source:
侦听给定端口,并将每行文本转换为事件,期望提供的数据是换行符分隔的文本,每行文本都转换为Flume事件,并通过连接的通道发送,同理也有Udp Source,此源也是侦听给定端口,并将每行文本转换为事件,并通过连接的通道发送
实例:
a1.sources = r1
a1.channels = c1
a1.sources.r1.type = netcat
a1.sources.r1.bind = 0.0.0.0
a1.sources.r1.port = 6666
a1.sources.r1.channels = c1
a1.sources = r1
a1.channels = c1
a1.sources.r1.type = netcatudp
a1.sources.r1.bind = 0.0.0.0
a1.sources.r1.port = 6666
a1.sources.r1.channels = c1
6.Sequence Generator Source:
一个简单的序列生成器,使用从0开始的计数器连续生成事件,每次递增1。主要用于测试,无法向通道发送事件时重试,唯一的事件数量应等于TotalEvents
实例:
a1.sources = r1
a1.channels = c1
a1.sources.r1.type = seq
a1.sources.r1.channels = c1
7.Syslog Source:
读取系统日志库,并生成Flime事件,UDP源将整个消息视为一个事件,而TCP源将为每一个由换行符分隔的字符串视为一个事件,所以有Syslog Tcp Source和Syslog Udp Source两种源,同时还有多端口的TCP源
实例:
a1.sources = r1
a1.channels = c1
a1.sources.r1.type = syslogtcp
a1.sources.r1.port = 5140
a1.sources.r1.host = localhost
a1.sources.r1.channels = c1
8.HTTP Source:
通过HTTP POST和GET接受Flume事件的源。GET应仅用于实验。HTTP请求由可插入的“处理程序”转换为水槽事件,该处理程序必须实现HTTPSourceHandler接口。该处理程序接受HttpServletRequest并返回水槽事件列表。从一个Http请求处理的所有事件都在一个事务中提交给通道,从而允许在诸如文件通道之类的通道上提高效率。如果处理程序抛出异常,则此源将返回HTTP状态400.如果通道已满,或者源无法将事件附加到通道,则源将返回HTTP 503 - 暂时不可用状态
实例:
a1.sources = r1
a1.channels = c1
a1.sources.r1.type = http
a1.sources.r1.port = 5140
a1.sources.r1.channels = c1
a1.sources.r1.handler = org.example.rest.RestHandler
a1.sources.r1.handler.nickname = random props
9.Logger Sink:
在INFO级别记录事件,通常用于测试或者调试,数据写入日志文件
实例:
a1.channels = c1
a1.sinks = k1
a1.sinks.k1.type = logger
a1.sinks.k1.channel = c1
10.Avro Sink:
数据被转换成Avro事件,并转入对应的RPC端口上,形成了Flume分层收集支持的一半,系统将从配置的主机名或端口中批量获取配置的批处理大小
实例:
a1.channels = c1
a1.sinks = k1
a1.sinks.k1.type = avro
a1.sinks.k1.channel = c1
a1.sinks.k1.hostname = 10.10.10.10
a1.sinks.k1.port = 4545
11.Thrift Sink:
同样形成了Flume分层收集支持的一半,数据被转换为Thrift事件。并发送到配置的RPC端口,事件将从配置的通道中获取批处理大小,可以通过启用身份验证,将其配置为以安全模式启动,若要与以安全模式启动的源通信,则接收器也应该以安全模式启动
实例:
a1.channels = c1
a1.sinks = k1
a1.sinks.k1.type = thrift
a1.sinks.k1.channel = c1
a1.sinks.k1.hostname = 10.10.10.10
a1.sinks.k1.port = 4545
12.HBaseSink:
此接收器将数据写入HBase。Hbase配置是从类路径中遇到的第一个hbase-site.xml中获取的。实现由配置指定的HbaseEventSerializer的类用于将事件转换为HBase put和/或增量。然后将这些放置和增量写入HBase。该接收器提供与HBase相同的一致性保证,HBase目前是行式原子性。如果Hbase无法写入某些事件,则接收器将重播该事务中的所有事件
实例:
a1.channels = c1
a1.sinks = k1
a1.sinks.k1.type = hbase
a1.sinks.k1.table = foo_table
a1.sinks.k1.columnFamily = bar_cf
a1.sinks.k1.serializer = org.apache.flume.sink.hbase.RegexHbaseEventSerializer
a1.sinks.k1.channel = c1
13.HTTP Sink:
从通道获取事件,并使用POST方法将这些事件发送到远程服务,事件内容作为POST正文发送,错误处理行为取决于目标服务器返回的HTP响应,就绪或者退避状态是可设置的,状态代码不可读的服务器返回任何错误格式的响应将导致退避信号,并且不会从该通道消耗事件
实例:
a1.channels = c1
a1.sinks = k1
a1.sinks.k1.type = http
a1.sinks.k1.channel = c1
a1.sinks.k1.endpoint = http://localhost:8080/someuri
a1.sinks.k1.connectTimeout = 2000
a1.sinks.k1.requestTimeout = 2000
a1.sinks.k1.acceptHeader = application/json
a1.sinks.k1.contentTypeHeader = application/json
a1.sinks.k1.defaultBackoff = true
a1.sinks.k1.defaultRollback = true
a1.sinks.k1.defaultIncrementMetrics = false
a1.sinks.k1.backoff.4XX = false
a1.sinks.k1.rollback.4XX = false
a1.sinks.k1.incrementMetrics.4XX = true
a1.sinks.k1.backoff.200 = false
a1.sinks.k1.rollback.200 = false
a1.sinks.k1.incrementMetrics.200 = true
14.Memory Channel:
事件存储在可配置最大大小的内存队列中,适用于需要较高吞吐量的系统,并且在代理发生故障时会选择性丢弃分阶段数据,需要配置通道的最大事件数,添加或删除事件的超时以及发送数据与通道中所有事件总大小之间的缓冲区百分比
实例:
a1.channels = c1
a1.channels.c1.type = memory
a1.channels.c1.capacity = 10000
a1.channels.c1.transactionCapacity = 10000
a1.channels.c1.byteCapacityBufferPercentage = 20
a1.channels.c1.byteCapacity = 800000
15.JDBC Channel:
事件存储在由数据库支持的持久存储中,并且支持嵌入式的Derby,这是一个持久的通道,适用于可恢复性很重要的流程
实例:
a1.channels = c1
a1.channels.c1.type = jdbc
16.Kafka Channel:
事件存储在Kafka群集中(必须单独安装)。Kafka提供高可用性和复制,因此如果代理或kafka代理崩溃,事件可立即用于其他接收器。可适用于多种场景,一是使用Flume源和接收器,为之提供了可靠且高度可用的通道;二是使用Flume源和拦截器,但没有接收器,允许将Flume事件写入Kafka主题,以提供其他程序使用;三是使用Flume接收器,但没有源,这是一种低延迟,容错的方式将事件从Kafka发送到其他接收器
实例:
a1.channels.channel1.type = org.apache.flume.channel.kafka.KafkaChannel
a1.channels.channel1.kafka.bootstrap.servers = kafka-1:9092,kafka-2:9092,kafka-3:9092
a1.channels.channel1.kafka.topic = channel1
a1.channels.channel1.kafka.consumer.group.id = flume-consumer
17.Spillable Memory Channel:
事件存储在内存中队列和磁盘上,队列充当主存储,磁盘充当溢出,磁盘存储使用嵌入的文件通道,当内存中队列已满时,其他传入事件将存储在文件通道中,非常适用于在正常操作期间需要高吞吐量存储器通道,但同时需要更大容量的文件通道以更好地容忍间歇性接收器中断或降低派出速率,但此通道是实验性的,并不适用于生产
实例:
a1.channels = c1
a1.channels.c1.type = SPILLABLEMEMORY
a1.channels.c1.memoryCapacity = 10000
a1.channels.c1.overflowCapacity = 1000000
a1.channels.c1.byteCapacity = 800000
a1.channels.c1.checkpointDir = /mnt/flume/checkpoint
a1.channels.c1.dataDirs = /mnt/flume/data