一、Flume简介
1、背景
Flume 初始的发行版本目前被统称为 Flume OG(original generation),属于 cloudera。但随着 Flume 功能的扩展,Flume OG 代码工程臃肿、核心组件设计不合理、核心配置不标准等缺点暴露出来,为了解决这些问题,2011 年 10 月 22 号,cloudera 完成了 Flume-728,对 Flume 进行了里程碑式的改动:重构核心组件、核心配置以及代码架构,重构后的版本统称为 Flume NG(next generation);纳入apache下也是促使其改动的一大原因,cloudera Flume 改名为 Apache Flume。
2、特点
flume是一个分布式、高可靠、高可用的服务,能够有效的收集、聚合、移动大量的日志数据。
1、它有一个简单、灵活的基于流的数据流结构。
2、具有故障转移机制和负载均衡机制。
3、使用了一个简单的可扩展的数据模型(source、channel、sink)。
4、声明式配置,可以动态更新配置 (配置修改后,不用重启服务即可生效)
flume-ng处理数据有两种方式:avro-client、agent。
avro-client:一次性将数据传输到指定的avro服务的客户端。
agent:一个持续传输数据的服务。
Agent主要组件包含:Source 、Channel、Sink
数据在组件传输的单位是Event
二、Flume部署安装
1、下载:http://apache.communilink.net/flume/1.8.0/apache-flume-1.8.0-bin.tar.gz
2、解压缩:tar zvxf apache-flume-1.8.0-bin.tar.gz
3、修改配置
$ cp conf/flume-env.sh.template conf/flume-env.sh
在conf/flume-env.sh配置JAVA_HOME
创建配置文件example.conf 参考 conf/flume-conf.properties.template
注意:export JAVA_OPTS
4、启动agent
bin/flume-ng agent --conf conf/ --conf-file conf/example.conf
--name a1 -Dflume.monitoring.type=http Dflume.monitoring.port=34343 -Dflume.root.logger=INFO,console &
配置文件example.conf 内容:
#生命agent名字a1,声明sources 包含r1 sink:k1 channel:c1
a1.sources = r1
a1.sinks = k1
a1.channels = c1
#配置source
a1.sources.r1.type = exec
a1.sources.r1.command = tail -F /var/log/secure
# 配置sink
a1.sinks.k1.type = logger
# 配置channel
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100
# 绑定source与sink于channel
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1
三、Flume核心组件
1、source
主要作用:从Client收集数据,传递给Channel。可以接收外部源发送过来的数据。不同的 source,可以接受不同的数据格式。 比如有目录池(spooling directory)数据源,可以监控指定文件夹中的新文件变化,如果目录中有文件产生,就会立刻读取其内容。
常见采集的数据类型:
Exec Source、Avro Source、NetCat Source、Spooling Directory Source、Kafka Source等
不同source的具体作用:
AvroSource:监听一个avro服务端口,采集Avro数据序列化后的数据;
Thrift Source:监听一个Thrift 服务端口,采集Thrift数据序列化后的数据;
Exec Source:基于Unix的command在标准输出上采集数据;
JMS Source:Java消息服务数据源,Java消息服务是一个与具体平台无关的API,这是支持jms规范的数据源采集;
Spooling Directory Source:通过文件夹里的新增的文件作为数据源的采集;
Kafka Source:从kafka服务中采集数据。
NetCat Source: 绑定的端口(tcp、udp),将流经端口的每一个文本行数据作为Event输入
HTTP Source:监听HTTP POST和 GET产生的数据的采集
详细查看:
http://flume.apache.org/FlumeUserGuide.html#flume-sources
Source提供了两种机制: PollableSource(轮询拉取)和EventDrivenSource(事件驱动):
上图展示的Source继承关系类图。
通过类图我们可以看到NetcatSource,ExecSource和HttpSource属于事件驱动模型。KafkaSource,SequenceGeneratorSource和JmsSource属于轮询拉取模型。
2、channel
Channel:一个数据的存储池,中间通道抑或是缓存队列。
主要作用:Channel用于连接Source和Sink,Source将日志信息发送到Channel,Sink从Channel消费日志信息;Channel是中转日志信息的一个临时存储,保存有Source组件传递过来的日志信息。Channel中的数据直到进入到下一个channel中或者进入终端才会被删除。当sink写入失败后,可以自动重写,不会造成数据丢失,因此很可靠。
channel的类型很多比如:内存中、jdbc数据源中、文件形式存储等。
常见采集的数据类型:
Memory Channel、File Channel、JDBC Channel、KafkaChannel、Spillable Memory Channel等
不同Channel具体作用:
Memory Channel:使用内存作为数据的存储。
JDBC Channel:使用jdbc数据源来作为数据的存储。
Kafka Channel:使用kafka服务来作为数据的存储。
File Channel:使用文件来作为数据的存储。
Spillable Memory Channel:使用内存和文件作为数据的存储,即:先存在内存中,如果内存中数据达到阀值则flush到文件中。
详细查看:
http://flume.apache.org/FlumeUserGuide.html#flume-channels
3、sink
Sink:数据的最终的目的地。
主要作用:接受channel写入的数据以指定的形式表现出来(或存储或展示)。
sink的表现形式很多比如:打印到控制台、hdfs上、avro服务中、文件中等。
常见采集的数据类型:
HDFS Sink、Hive Sink、Logger Sink、Avro Sink、Thrift Sink、File Roll Sink、HBaseSink、Kafka Sink等
不同Sink具体作用:
HDFS Sink:将数据传输到hdfs集群中。
Hive Sink:将数据传输到hive的表中。
Logger Sink:将数据作为日志处理(根据flume中的设置的日志的级别显示)。
Avro Sink:数据被转换成Avro Event,然后发送到指定的服务端口上。
Thrift Sink:数据被转换成Thrift Event,然后发送到指定的的服务端口上。
IRC Sink:数据向指定的IRC服务和端口中发送。
File Roll Sink:数据传输到本地文件中。
Null Sink:取消数据的传输,即不发送到任何目的地。
HBaseSink:将数据发往hbase数据库中。
MorphlineSolrSink:数据发送到Solr搜索服务器(集群)。
ElasticSearchSink:数据发送到Elastic Search搜索服务器(集群)。
Kafka Sink:将数据发送到kafka服务中。(注意依赖类库)
详细查看:
http://flume.apache.org/FlumeUserGuide.html#flume-sinks
HDFSSink需要有hdfs的配置文件和类库。一般采取多个sink汇聚到一台采集机器负责推送到hdfs。
4、event
含义:event是Flume NG传输的数据的基本单位,也是事务的基本单位。
在文本文件,通常是一行记录就是一个event。
网络消息传输系统中,一条消息就是一个event。
结构:event里有header、body
Event里面的header类型:Map
我们可以在source中自定义header的key:value,在某些channel和sink中使用header。
四、架构举例
串行架构图、
聚合架构图、
五、Flume高级组件
1、Interceptors
Interceptors:source的拦截器
主要作用:对于一个source可以指定一个或者多个拦截器,按先后顺序依次对数据进行处理。
比如:在收集的数据的event的header中加入处理的时间戳、agent的主机或者IP、固定key-value等等。
常见Interceptors类型:
Timestamp Interceptor、Host Interceptor、Static Interceptor、UUID Interceptor、Morphline Interceptor、Search and Replace Interceptor、Regex Filtering Interceptor、Regex Extractor Interceptor等
详细查看:
http://flume.apache.org/FlumeUserGuide.html#flume-interceptors
如何使用Interceptor?将source加入Interceptor测试看下header即可。
例如:
a1.sources.r1.interceptors = i1 i2
a1.sources.r1.interceptors.i1.type =org.apache.flume.interceptor.HostInterceptor$Builder
a1.sources.r1.interceptors.i1.preserveExisting = false
a1.sources.r1.interceptors.i1.hostHeader = hostname
a1.sources.r1.interceptors.i2.type =org.apache.flume.interceptor.TimestampInterceptor$Builder
2、Channel Selectors:
Channel Selectors:Channel选择器
主要作用:对于一个source发往多个channel的策略设置
Channel Selectors类型:
Replicating Channel Selector (default)、Multiplexing Channel Selector
其中:Replicating 会将source过来的events发往所有channel,而Multiplexing selector会根据event中某个header对应的value来将event发往不同的channel(header与value就是KV结构)。
详细查看:
http://flume.apache.org/FlumeUserGuide.html#flume-channel-selectors
Event里面的header类型:Map
如果header中有一个key:state,我们在不同的数据源设置不同的stat则通过设置这个key的值来分配不同的channel
例如:
a1.sources.r1.channels = c1 c2 c3 c4
a1.sources.r1.selector.type = multiplexing
a1.sources.r1.selector.header = state
a1.sources.r1.selector.mapping.CZ = c1
a1.sources.r1.selector.mapping.US = c2 c3
a1.sources.r1.selector.default = c4
3、Sink Processor
Sink Processor:Sink处理器
主要作用:针对Sink groups的处理策略设置
Sink Processor类型:
Default Sink Processor、Failover Sink Processor、Load balancing Sink Processor
其中:Default是默认的情况不用配置sinkgroup,Failover是故障转移机制、Load balancing是负载均衡机制,后两个需要定义sinkgroup。
详细查看:
http://flume.apache.org/FlumeUserGuide.html#flume-sink-processors
应用:负载均衡、故障转移
Load balancing Sink Processor:processor.selector:round_robin,、random、自定义
轮询调度(Round Robin Scheduling)算法就是以轮询的方式依次将请求调度不同的服务器,即每次调度执行i = (i + 1) mod n,并选出第i台服务器。算法的优点是其简洁性,它无需记录当前所有连接的状态,所以它是一种无状态调度。
配置举例:
负载均衡
a1.sinkgroups=g1
a1.sinkgroups.g1.sinks=k1 k2
a1.sinkgroups.g1.processor.type=load_balance
a1.sinkgroups.g1.processor.backoff=true #失败的sink是否放入冷却池中
a1.sinkgroups.g1.processor.selector=round_robin
故障转移
a1.sinkgroups=g1
a1.sinkgroups.g1.sinks=k1 k2
a1.sinkgroups.g1.processor.type=failover
a1.sinkgroups.g1.processor.priority.k1=10
a1.sinkgroups.g1.processor.priority.k2=5
a1.sinkgroups.g1.processor.maxpenalty=10000 #冷却池最大冷却时间
负载均衡/故障转移架构图:
附-负载均衡与故障转移的完整配置:
①负载均衡
# 声明source sink channel
a1.sources = r1
a1.sinks = k1 k2
a1.channels = c1
# 定义source r1
a1.sources.r1.type = exec
a1.sources.r1.channels=c1
a1.sources.r1.command=tail -F /opt/logs/access.log
#定义sinkgroup g1 类型load_balance
a1.sinkgroups=g1
a1.sinkgroups.g1.sinks=k1 k2
a1.sinkgroups.g1.processor.type=load_balance
a1.sinkgroups.g1.processor.backoff=true
a1.sinkgroups.g1.processor.selector=round_robin
#定义 sink 1
a1.sinks.k1.type=avro
a1.sinks.k1.hostname=192.168.1.156
a1.sinks.k1.port=41414
#定义 sink 2
a1.sinks.k2.type=avro
a1.sinks.k2.hostname=192.168.1.162
a1.sinks.k2.port=41414
#定义 channel c1 用于缓存队列
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100
# 将r1与k1 k2做绑定
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1
a1.sinks.k2.channel=c1
②故障转移
# 声明source sink channel
a1.sources = r1
a1.sinks = k1 k2
a1.channels = c1
# 定义source r1
a1.sources.r1.type = exec
a1.sources.r1.channels=c1
a1.sources.r1.command=tail -F /opt/logs/access.log
#定义sinkgroup g1
a1.sinkgroups=g1
a1.sinkgroups.g1.sinks=k1 k2
a1.sinkgroups.g1.processor.type=failover
a1.sinkgroups.g1.processor.priority.k1=10
a1.sinkgroups.g1.processor.priority.k2=5
a1.sinkgroups.g1.processor.maxpenalty=10000
#定义 sink 1
a1.sinks.k1.type=avro
a1.sinks.k1.hostname=192.168.1.156
a1.sinks.k1.port=41414
#定义 sink 2
a1.sinks.k2.type=avro
a1.sinks.k2.hostname=192.168.1.162
a1.sinks.k2.port=41414
# 定义channel c1
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100
# 将r1与k1 k2做绑定
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1
a1.sinks.k2.channel=c1