Flume

Flume简介:

1.1 大数据处理流程

数据源(RDBMS,日志文件,web数据)数据采集(sqoop,flume,kafka) ---> 数据存储(hdfs,hbase,es) ----> 数据清洗(mapreduce,hive,spark) ---> 数据分析(mapreduce,hive,spark) ---> 数据存储(mysql,oracle,sqlserver) ----> web展示

flume简介:

Flume是一种分布式的,可靠的,高可用的服务,用于有效的收集,聚合和移动大量的日志数据,它具有基于流数据流的简单灵活的体系结构,它具有可调整的可靠性机制以及许多故障转移和恢复机制,具有强大的功能和容错能力,它使用一个简单的可扩展数据模型,允许在线分析应用程序

flume最开始是由cloudera开发的实时日志手机系统,受到了业界的认可和广泛的应用,但随着flume功能的扩展,flume的代码工程臃肿,核心组件设计不合理,核心配置不标准等问题逐渐暴露出来,尤其是在发行版本0.9.4中,日志传输不稳定的现象尤为严重,为了解决这些问题,2011年10月22日,cloudera对flume进行了里程碑式的改动:重构核心组件,核心配置和代码架构,并将Flume纳入到apache旗下,从cloudera Flume改名为apache Flume

版本区别:
	为了与之前的版本区分开来,重构后的版本统称为Flume NG(next generation),重构后的版本被统称为Flume OG(orginal generation),Flume目前只有Linux系统的启动脚本,没有Windows环境的启动脚本

Flume的体系架构:

Flume的运行核心是Agent,Flume是以agent为最小的独立运行单位,一个agent就是一个JVM,他是一个完整的数据收集工具,含有三个组件,分别是source,channel,sink,通过这些组件,event就可以从一个地方流向另一个地方
组件:
client:客户端,client产生数据,运行在一个独立的线程中
event:一个数据单元,消息头和消息体组成(events可以是日志记录,avro对象等)
flow:event从源点到达目的地的迁移的抽象
agent:一个独立的flume进程,运行在jvm中,包含组件source,channel,sink,每台机器运行一个agent,但是一个agent中可以包含多个	sources和sinks
source:数据收集组件,source从client收集数据,传送给channel
channel:管道,负责接收source段的数据,然后将数据推送到sink端
sink:负责从channel端拉取数据,并将其推送到持久化系统或者下一个agent
selector:选择器,作用于source端,然后决定数据发送到哪个目标
interceptor:拦截器,flume允许使用拦截器拦截数据,允许使用拦截器链,作用于source和sink端

Flume的安装

上传,解压,配置环境变量,配置flume-env.sh中的jdk

Flume的部署

数据模型:
	单一数据模型
	多数据流模型

单一数据模型:
	在单个agent内,由单个source,channel,sink建立一个单一的数据流模型,如下图所示,整个数据流为WebServer-->Soure-->Channel-->Sink-->HDFS

多数据流模型:略	
	
总结:
在Flume提供的数据流模型中,几个原则很重要:

Source-->Channel
	1.单个Source组件可以与多个Channel组合建立数据流,即可以replicating和multiplexing
	2.多个Source可以写入单个Channel
Channel-->Sink
	3.多个Sinks又可以组合成Sinkgroups从Channel中获取数据,既可以loadbalancing和failover机制
	4.多个Sinks也可以从单个Channel中取数据
	5.单个Sink只能从单个Channel中取数据

配置介绍:

1.定义组件名称:

要定义单个代理中的流,您需要通过通道链接源和接收器,您需要列出给定代理的源,接收器和通道,然后将源和接收器指向一个通道,一个源实例可以指定多个通道,但是一个接收器只能指定一个通道,格式如下:

2.常用的Flume Sources:

#Avro source:
	avro
#Syslog TCP source:
	syslogtcp
#HTTP source:
	http
#Exec source:
	exec
#JMS source:
	jms
#Thrift source:
	thrift
#Spooling directory source:
	spooldir
#Kafka source:
	org.apache.flume.source.kafka.KafkaSource

3.常用的Flume Channel:

#Memory Channel:
	memory
#JDBC Channel:
	jdbc
#Kafka Channel:
	org.apache.flume.channel.kafka.KafkaChannel
#File Channel:
	file

4.常用的flume sinks:

#HDFS Sink
	hdfs
#Hive Sink
	hive
#Logger Sink
	logger
#Avro Sink
	avro
#Kafka Sink
	org.apache.flume.sink.kafka.KafkaSink
#Hbase Sink
	hbase

案例演示:(avro+memory+logger)

Avro Source:监听一个指定的Avro端口,通过Avro端口可以获取到Avro client发送过来的文件,即只要应用程序通过Avro端口发送文件,source组件就可以获取该文件中的内容,输出位置为logger

1.	创建一个配置文件,将相关的配置都写到这个配置文件中
	这个文件的格式不限,但是我们一般将其写成.properties文件
	mkdir flume_conf
	vi avro_memory_logger.properties
#以a1作为agent的名字,这个名字可以在启动agent的时候进行配置

#1.指定当前的agent中有什么source,有什么channel,有什么sink
a1.sources=r1
a1.channels=c1
a1.sinks=s1

#2.进行属性的关联
#设置a1.agent中的r1的source需要将event发送给哪些channel
a1.sources.r1.channels=c1
#设置a.agent中的s1的sink需要拉取哪个channel中的数据
a1.sinks.s1.channel=c1

#3.设置source的属性
a1.sources.r1.type=avro
a1.sources.r1.bind=qianfeng01
a1.sources.r1.port=12345

#4.设置channel的属性
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000

#5.设置sink的属性
a1.sinks.s1.type=logger
a1.sinks.s1.maxBytesToLog=32
avro是一种数据传输格式:json数据+schema信息
avro是rpc和数据序列化系统(data serialization system),使用json定义的数据类型及通讯协议,使用压缩二进制来序列化数据,是Hadoop持久化数据的一种序列化格式

启动0RUERPU

flume-ng agent -c ../conf -f ./avro-mem-logger.properties -n a1 -Dflume.root.logger=INFO,console

测试数据:

使用avro的客户端象qianfeng01的12345端口发送数据:
flume-ng avro-client -c /usr/local/flume/conf/ -H qianfeng01 -p 12345 -F flumeData1
#avro的输出作为下一个avro的source,从而实现多agent串行
#为source,channel,sink设置名称
a1.sources=r1
a1.channels=c1
a1.sinks=s1

#设置source,sink和channel的关系
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1

#设置sources
a1.sources.r1.type=exec
a1.sources.r1.command=tail -f /root/flumedata/data1.txt

#设置channel
a1.channels.c1.type=memory

#设置sink(与以往不同,这次设置的sink直接作为下一agent的sources)
a1.sinks.s1.type=avro
a1.sinks.s1.hostname=qianfeng1
a1.sinks.s1.port=9999

实时采集(监听文件):exec+memory+hdfs

exec source:监听一个指定的命令,获取1条命令的结果作为它的数据源

#常用的tail -f file 指令,即只要应用程序象日志(文件)里面写数据,source组件就可以获取到日志(文件)中最新的内容

memory:传输数据的Channel为Memory

#指定当前的agent有什么source,有什么sink,有什么channel
a1.sources=r1
a1.channels=c1
a1.sinks=s1

#指定组件之间的依赖关系
#设置a1.agent中的r1的source需要将event发送给哪些channel
a1.sources.r1.channels=c1
#设置a1.agent中的s1的sink需要拉取哪个channel中的数据
a1.sinks.s1.channel=c1

#配置source
a1.sources.r1.type=exec
a1.sources.r1.command=tail -F /root/flumedata/data1.txt

#配置sink
a1.sinks.s1.type=hdfs
a1.sinks.s1.hdfs.path=hdfs://qianfeng01:8020/flume/tailout/

#配置channel
a1.channels.c1.type=memory
启动agent
flume-ng agent -c /usr/local/flume/conf -f exec-memory-logger.conf -n a1 -Dflume.root.logger=INFO,console

测试:
ping www.baidu.com >> /root/flumeData/data1.txt

实时采集(监听文件):exec+memory+logger

exec source:监听一个指令的命令,获取一条命令的结果作为它的数据源

#常用的是tail -f file指令,即只要应用程序向日志(文件)里写数据,source组件就可以获取到日志(文件)中的最新内容

logger为日志格式输出

#配置source,channel,sink的名称
a3.sources=r1
a3.channels=c1
a3.sinks=s1

#配置sources和sink与channel之间的依赖关系
a3.sources.r1.channels=c1
a3.sinks.s1.channel=c1

#配置source
a3.sources.r1.type=exec
a3.sources.r1.command=tail -F /root/flumedata/data2.txt

#配置channel
a3.channels.c1.type=memory

#配置sink
a3.sinks.s1.type=logger
启动:
flume-ng agent -c /usr/local/flume/conf -f exec-memory-logger.conf -n a3 -Dflume.root.logger=INFO,console

测试:
echo "wddmn" >> /root/flumedata/data2.txt

实时采集(监听目录):spool+file+hdfs

spool是Source来源于目录,有文件进入目录就摄取,FileChannel将它暂时存放到磁盘,最终目的地是HDFS,即只要某个目录不断有文件,HDFS上也会同步到所有的数据

#配置sources,channels,sinks的名称
a4.sources=r1
a4.channels=c1
a4.sinks=s1

#配置source,sink与channel的依赖关系
a4.sources.r1.channels=c1
a4.sinks.s1.channel=c1

#配置source
a4.sources.r1.type=spooldir
a4.sources.r1.spoolDir=/root/flumedata/

#配置channel
a4.channels.c1.type=file

#配置sinks
a4.sinks.s1.type=hdfs
a4.sinks.s1.hdfs.path=hdfs://qianfeng01:8020/flume/spooldir
启动agent:
flume-ng agent -c /usr/local/flume/conf -f spool-file-hdfs.conf -n a4 -Dflume.root.logger=INFO,console

测试:
cd /root/flumedata
echo "w" >> data3.txt
echo "d" >> data4.txt

补充:

如果本地的file路径中已经有文件了,那么启动agent的时候会报如下异常,但是不影响正常的数据采集,原文件会直接被上传到hdfs上,所以尽量避免使用同一个数据文件

实时采集(监听目录):spool+memory+logger

spool:Source来源于目录里,有文件进入目录就摄取,File Channel将它暂存到磁盘,最终的目的地是HDFS,即只要某个目录

不断有文件,HDFS上也会同步所有数据

mem:通过内存赖传数据

logger:是传送到日志

#配置source,channel,sink的名称
a5.sources=r1
a5.channels=c1
a5.sinks=s1

#配置souece,sink与channel的关系
a5.sources.r1.channels=c1
a5.sinks.s1.channel=c1

#配置source
a5.sources.r1.type=spooldir
a5.sources.r1.spoolDir=/root/flumedata2

#配置channel
a5.channels.c1.type=memory

#配置sink
a5.sinks.s1.type=logger
启动agent:
flume-ng agent -c /usr/local/flume/conf -f spool-memory-logger.conf -n a5 -Dflume.root.logger=INFO,console

测试:
echo "hello" >> data1.txt

文件监控

flume中有三种可监控文件或目录的source,分别是exec source,spooling directory source,taildir source,taildir source:是1.7版本的新特性,综合了spooling directory source和exec source的优点

exec source:可以通过tail -f命令去tail住一个文件,然后实时同步日志到sink,但存在的问题是,当agent进程挂掉重启后,会有重复消费的问题,可以通过增加uuid来解决,或者是通过exec source来解决

spooling directory source可监听一个目录,同步目录中的新文件到sink,被同步完的文件可被立即删除或者被打上标记,适合同步新文件,但不适合对实时9追加日志的文件进行监听并且同步,如果需要实时监听追加内容的文件,可对SpoolDirectorySource进行改进

taildir source可实时监控一批文件,并记录每个文件最新消费的位置,agent进程重启之后不会有重复消费的问题,使用时建议用1.8.0版本的flume,1.8.0版本中解决了taildir source一个可能会丢失数据的bug

HTTP+memory+logger

http:表示数据来源是http网络协议,一般接收的请求是get或者post请求,所有的http请求会通过插件格式的handle转化成一个flume的event数据

memory:表示用内存传输通道

logger:表示输出格式为logger

#指定source,channel,sink的名称
a6.sources=r1
a6.channels=c1
a6.sinks=s1

#配置source,sink和channel之间的依赖关系
a6.sources.r1.channels=c1
a6.sinks.s1.channel=c1

#配置source
a6.sources.r1.type=http
a6.sources.r1.bind=qianfeng01
a6.sources.r1.port=6666
a6.sources.r1.handler=org.apache.flume.source.http.JSONHandler
a6.sources.r1.handler.nickname= random props

#配置channel
a6.channels.type=memory

#配置sink
a6.sinks.s1.type=logger
启动agent:
flume-ng agent -c /usr/local/flume/conf -f http-memory-logger.conf -n a6 -Dflume.root.logger=INFO,console

测试:
curl -X POST -d '[{"headers":{"name":"zhangsan","pwd":"123456"},"body":"this is my content"}]' http://192.168.10.101:6666

Syslog tcp +memory+logger

Syslog tcp:syslog广泛应用于系统日志,syslog日志消息既可以记录在本地文件中,也可以通过网络发送到接收syslog的服务器,接收syslog的服务器可以对多个设备的syslog消息进行统一的存储,或者解析其中的内容做相应的处理,本数据源指的是syslog的通过tcp的端口来传送数据

memory:通过内存选择器来处理

logger:输出目的地为logger

#配置sources,channels,sinks的名称
a7.sources=r1
a7.channels=c1
a7.sinks=s1

#配置source,channel,sink间的依赖关系
a7.sources.r1.channels=c1
a7.sinks.s1.channel=c1

#设置source
a7.sources.r1.type=syslogtcp
a7.sources.r1.host=qianfeng01
a7.sources.r1.port=6666

#设置channel
a7.channels.c1.type=memory

#设置sink
a7.sinks.s1.type=logger
启动agent
flume-ng agent -c /usr/local/flume/conf -f syslog-memory-logger.conf -n a7 -Dflume.root.logger=INFO,console

测试
echo "helloworld" | nc qianfeng01 6666

Syslogtcp+memory+hdfs

syslogtcp:syslog广泛应用于系统日志,syslog日志消息既可以记录在本地文件中,又可以通过网络发送到接收syslog的服务器,接收syslog的服务器可以对多个设备的syslog进行统一的存储,或者解析其中的内容做出相应的处理,本数据源指的是syslog的通过tcp的端口来传递数据

memory:内存传送

hdfs:目的地为hdfs服务器

#配置source,channel,sink的名称
a8.sources=r1
a8.channels=c1
a8.sinks=s1

#配置source,sink和channel的依赖关系
a8.sources.r1.type=syslogtcp
a8.sources.r1.host=qianfeng01
a8.sources.r1.port=6666

#配置channel
a8.channels.c1.type=memory

#配置hdfs
a8.sinks.s1.type=hdfs
a8.sinks.s1.hdfs.path=hdfs://qianfeng01:8020/flume/syslogtcp

#配置source,sink与channel的依赖关系
a8.sources.r1.channels=c1
a8.sinks.s1.channel=c1
启动agent
flume-ng agent -c /usr/local/flume/conf -f syslogtcp-memory-hdfs.conf -n a8 -Dflume.root.logger=INFO,console

测试
echo "hello world" | nc qianfeng01 6666

syslogtcp+file+hdfs

syslogtcp:syslog广泛应用于系统日志,syslog日志消息既可以记录在本地文件中,又可以通过网络发送到接收syslog的服务器,接收syslog的服务器可以对多个设备的syslog进行统一的存储,或者解析其中的内容做出相应的处理,本数据源指的是syslog的通过tcp的端口来传递数据

file:表示用file作为channel传送介质

hdfs:表示目的地为hdfs

#配置source,sink,channel的名称
a9.sources=r1
a9.channels=c1
a9.sinks=s1

#配置source,sink与channel之间的依赖关系
a9.sources.r1.channels=c1
a9.sinks.s1.channel=c1

#配置source
a9.sources.r1.type=syslogtcp
a9.sources.r1.host=qianfeng01
a9.sources.r1.port=6666

#配置channel
a9.channels.c1.type=file

#配置sink
a9.sinks.s1.type=hdfs
a9.sinks.s1.hdfs.path=hdfs://qianfeng01:8020/flume/sfh
启动agent
flume-ng agent -c /usr/local/flume/conf -f syslogtcp-file-hdfs.conf -n a9 -Dflume.root.logger=INFO,console

测试:
echo "imissyou" | nc qianfeng01 6666

taildir+memory+hdfs

#为source,channel,sink设置名称
a1.sources=r1
a1.channels=c1
a1.sinks=s1

#设置source,sink与channel的关系
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1

#设置source
a1.sources.r1.type=TAILDIR
a1.sources.r1.filegroups=f1		//可以随便为文件组设置一个名称
a1.sources.s1.filegroups.f1=/root/flumedata/log.+			

#设置channel
a1.channels.s1.type=memory

#设置sick
a1.sicks.s1.type=hdfs
a1.sicks.s1.hdfs.path=hdfs://qianfeng01/flume/taildir
a1.sinks.sk1.hdfs.filePrefix = taildir
a1.sinks.sk1.hdfs.rollInterval = 60		---设置文件翻新的时间间隔
a1.sinks.sk1.hdfs.rollCount = 300		---设置文件翻新里的监听次数
a1.sinks.sk1.hdfs.rollSize = 102400		---设置文件翻新文件大小阈值

拦截器

为什么要使用拦截器:

Flume中的拦截器(interceptor),用户Source读取events发送到Sink的时候,在events header中加入一些有用的信息,或者对events的内容进行过滤,完成初步的数据清洗。这在实际业务场景中非常有用
在flume的运行过程中 ,flume有能力在运行阶段修改/删除event,这是通过拦截器(interceptors)来实现的,拦截器有以下几个特点:

1,拦截器需要实现org.apache.flume.interceptor.Interceptor接口

2,拦截器可以修改或者删除事件基于开发者在选择其中选择的任何条件

3,拦截器采用了责任链模式,多个拦截器可以按照指定的顺序拦截

4,一个拦截器返回的事件列表被传递给链中的下一个拦截器

5,如果一个拦截器需要删除事件,它只需要在返回的事件集中不包含要删除的事件即可
常用的拦截器:

1,Timestamp Interceptor:事件拦截器,将当前时间戳加入到events header中,key的名字是:timestamp,值为当前时间戳(用的不是很多)

2,Host Interceptor:主机名拦截器,将运行Flume agent的主机名或者ip地址加入到events header中,key名字为host(也可以自定义)

3,Static Interceptor:静态拦截器,用于在events header中加入一组静态的key和value

案例演示:

Timestamp + Syslogtcp + file + hdfs

通过时间拦截器,数据源是syslogtcp,传送的管道是file,最后的输出地是hdfs

#配置source,channel,sink的名称
a1.sources=r1
a1.channels=c1
a1.sinks=s1

#配置source,sink和channel的依赖关系
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1

#配置source
a1.sources.r1.type=syslogtcp
a1.sources.r1.host=qianfeng01
a1.sources.r1.port=6666

#设置拦截器
a1.sources.r1.interceptors=i1 i2 i3
#将时间加入到event的header中,timestamp=158784562325869
a1.sources.r1.interceptors.i1.type=timestamp
#是否覆盖原来的值,如果存在是否保留
a1.sources.r1.interceptors.i1.preserveExisting=false
#将主机名加入到event的header中,hostname=192.168.10.101
a1.sources.r1.interceptors.i2.type=host
a1.sources.r1.interceptors.i2.preserveExisting=false
a1.sources.r1.interceptors.i2.useIP=true
a1.sources.r1.interceptors.i2.hostHeader=hostname
#static拦截器,可以向header中自定义class=bigdata2102
a1.sources.r1.interceptors.i3.type=static
a1.sources.r1.interceptors.i3.preserveExisting=false
a1.sources.r1.interceptors.i3.key=class
a1.sources.r1.interceptors.i3.value=bigdata2002

#设置channel的属性
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000

#设置sink的属性
a1.sinks.s1.type=hdfs
a1.sinks.s1.hdfs.path=hdfs://qianfeng01:8020/flume/timestamp/%Y-%m-%d-%H
#a1.sinks.s1.hdfs.useLocalTimeStamp=false
a1.sinks.s1.hdfs.filePrefix=events-
a1.sinks.s1.hdfs.rollInterval=0
a1.sinks.s1.hdfs.rollSize=102400
a1.sinks.s1.hdfs.rollCount=30
a1.sinks.s1.hdfs.fileType=DataStream
a1.sinks.s1.hdfs.writeFormat=Text
启动agent:
flume-ng agent -c /usr/local/flume/conf -f timestamp-smh.conf -n a1 -Dflume.root.logger=INFO,console

测试:
echo "hello world" | nc qianfeng01 6666

regex + Syslogtcp + file + hdfs

拦截器是正则表达式拦截器,数据源是Syslogtcp格式,传送通道是FIleChannel,最后传送的目的地是HDFS

#配置source,channel,sink的名称
a1.sources=r1
a1.channels=c1
a1.sinks=s1

#配置source,sink和channel的依赖关系
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1

#配置source
a1.sources.r1.type=syslogtcp
a1.sources.r1.host=qianfeng01
a1.sources.r1.port=6666

#设置静态拦截器
a1.sources.r1.interceptors=i1
a1.sources.r1.interceptors.i1.type=regex_filter                                                     
a1.sources.r1.interceptors.i1.regex=^[0-9].+$


#设置channel的属性
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000

#设置sink的属性
a1.sinks.s1.type=hdfs
a1.sinks.s1.hdfs.path=hdfs://qianfeng01:8020/flume/timestamp/%Y-%m-%d-%H
a1.sinks.s1.hdfs.useLocalTimeStamp=false
a1.sinks.s1.hdfs.filePrefix=events-
a1.sinks.s1.hdfs.rollInterval=0
a1.sinks.s1.hdfs.rollSize=102400
a1.sinks.s1.hdfs.rollCount=30
a1.sinks.s1.hdfs.fileType=DataStream
a1.sinks.s1.hdfs.writeFormat=Text
event{
	header{
		timestamp=xxxxxxxxxx
	}
	
	body{
		//采集到的数据
	}
}
//timestamp拦截器会在event的header中添加一个键值对,timestamp=xxxxxxxxxx,当设置
正则表达式:
^:匹配一个字符串的开头
$:匹配一个字符串的结尾
[]:匹配一个字符
\:转义字符
\d:匹配所有的数字,等同于[0-9]
\D:匹配所有的非数字,等同于[^0-9]
\w:匹配所有的单词字符,等同于[a-zA-Z0-9]
\W:匹配所有的非单词字符,等同于[^a-zA-Z0-9]
.:通配符,可以匹配一个任意的字符
+:前面的一位或者一组字符,连续出现一次或者多次
?:前面的一位或者一组字符,连续出现了一次或者0次
*:前面的一组或者一组字符,连续出现了0次,1次或者多次
{}:对前面的一组或者一组字符连续出现的次数的精准匹配
|:作用于整体或者一个分组
():分组,把某些连续的字符是为一个整体对待

自定义拦截器:

1.自定义正则表达式过滤拦截器:
    
2.将jar包放到/usr/local/flume/lib下
    
3.配置拦截器:
    a1.sources.r1.interceptors.i4.type=com.qf.bigdata.flume.interceptors.MyRegexFilter$Builder
    
4.测试
#配置source,channel,sink的名称
a1.sources=r1
a1.channels=c1
a1.sinks=s1

#配置source,sink和channel的依赖关系
a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1

#配置sources
a1.sources.r1.type=exec
a1.sources.r1.command=tail -f /root/flumedata/data1.txt
#配置拦截器
a1.sources.r1.interceptors=i1
a1.sources.r1.interceptors.i1.type=com.qf.Flume.MyRegexFilter$Builder
a1.sources.r1.interceptors.i1.param=^[0-9].*&


#配置channel
a1.channels.c1.type=memory

#配置sink
a1.sinks.s1.type=logger

选择器:

Flume中的Channel选择器作用于source阶段,是决定Source接受的特定的事件写入到哪个Channel的组件,他们告诉Channel处理器,然后由其将事件写入到Channel

Agent中各个组件的交互

 由于Flume不是两阶段提交,事件被写入到一个Channel,然后事件在写入下一个Channel之前提交,如果写入一个Channel出现异常,那么之前已经写入到其他Channel的相同事件不能被回滚。当这样的异常发生时,Channel处理器抛出ChannelException异常,事务失败,如果Source试图再次写入相同的事件(大多数情况下,会再次写入,只有Syslog,Exec等Source不能重试,因为没有办法生成相同的数据),重复的事件将写入到Channel中,而先前的提交是成功的,这样在Flume中就发生了重复。

Channel选择器的配置是通过Channel处理器完成的,Channel选择器可以指定一组Channel是必须的,另一组的可选的。

Flume分为两种选择器

replicating:该选择器复制每个事件到通过Source的Channel参数指定的所在Channel中

multiplexing:是一种专门用于动态路由事件的Channel选择器,通过选择事件应该写入到哪个Channel,基于一个特定的事件头的值进行路由

replicating selector

a1.sources=r1
a1.channels=c1 c2
a1.sinks=s1 s2

a1.sources.r1.type=syslogtcp
a1.sources.r1.host=qianfeng01
a1.sources.r1.port=6666
a1.sources.r1.selector.type=replicating

a1.channels.c1.type=memory
a1.channels.c2.type=memory

a1.sinks.s1.type=hdfs
a1.sinks.s1.hdfs.path=hdfs://qianfeng01:8020/flume/%Y/%m/%d/rep
a1.sinks.s2.type=hdfs
a1.sinks.s2.hdfs.path=hdfs://qianfeng01:8020/flume/%Y/%m/%d/rep
a1.sinks.s1.hdfs.useLocalTimeStamp=true
a1.sinks.s2.hdfs.useLocalTimeStamp=true

a1.sources.r1.channels=c1 c2
a1.sinks.s1.channel=c1
a1.sinks.s2.channel=c2

multiplexing selector

a1.sources=r1
a1.channels=c1 c2
a1.sinks=s1 s2

a1.sources.r1.type=http
a1.sources.r1.bind=qianfeng01
a1.sources.r1.port=6666
a1.sources.r1.selector.type=multiplexing
a1.sources.r1.selector.header=state
a1.sources.r1.selector.mapping.USER=c1
a1.sources.r1.selector.mapping.ORDER=c2
a1.sources.r1.selector.default=c1

a1.channels.c1.type=memory
a1.channels.c2.type=memory

a1.sinks.s1.type=hdfs
a1.sinks.s1.hdfs.path=hdfs://qianfeng01:8020/flume/%Y/%m/%d/mul
a1.sinks.s1.hdfs.useLocalTimeStamp=true

a1.sinks.s2.type=hdfs
a1.sinks.s2.hdfs.path=hdfs://qianfeng01:8020/flume/%Y/%m/%d/mul
a1.sinks.s2.hdfs.useLocalTimeStamp=true

a1.sources.r1.channels=c1 c2
a1.sinks.s1.channel=c1
a1.sinks.s2.channel=c2

自定义拦截器和选择器搭配使用:

a1.sources=r1
a1.channels=c1 c2 c3
a1.sinks=s1 s2 s3
a1.sources.r1.channels=c1 c2 c3
a1.sinks.s1.channel=c1
a1.sinks.s2.channel=c2
a1.sinks.s3.channel=c3

#设置sources的属性
a1.sources.r1.type=syslogtcp
a1.sources.r1.host=qianfeng01
a1.sources.r1.port=12345
#设置选择器的属性
a1.sources.r1.selector.type=multiplexing
a1.sources.r1.selector.header=location
a1.sources.r1.selector.mapping.number=c1
a1.sources.r1.selector.mapping.character=c2
a1.sources.r1.selector.mapping.other=c3

#设置拦截器
a1.sources.r1.interceptors=i1
a1.sources.r1.interceptors.i1.type=com.qf.Flume.Interceptors$MyBuilder

#设置channel的属性
a1.channels.c1.type=memory
a1.channels.c2.type=memory
a1.channels.c3.type=memory

#设置sink的属性
a1.sinks.s1.type=hdfs
a1.sinks.s1.hdfs.path=hdfs://qianfeng01:8020/flume/interceptor/s1/%Y-%m-%d-%H
a1.sinks.s1.hdfs.useLocalTimeStamp=true
a1.sinks.s2.type=hdfs
a1.sinks.s2.hdfs.path=hdfs://qianfeng01:8020/flume/interceptor/s2/%Y-%m-%d-%H
a1.sinks.s2.hdfs.useLocalTimeStamp=true
a1.sinks.s3.type=hdfs
a1.sinks.s3.hdfs.path=hdfs://qianfeng01:8020/flume/interceptor/s3/%Y-%m-%d-%H
a1.sinks.s3.hdfs.useLocalTimeStamp=true

Flume的集群

qianfeng01:

a1.sources=r1
a1.channels=c1
a1.sinks=s1

a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1

a1.sources.r1.type=systcplog
a1.sources.r1.host=qianfeng01
a1.sources.r1.port=6666

a1.channels.c1.type=memory

a1.sinks.s1.type=avro
a1.sinks.s1.hostname=qianfeng03
a1.sinks1.s1.port=6666

qianfeng02:

a1.sources=r1
a1.channels=c1
a1.sinks=s1

a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1

a1.sources.r1.type=http
a1.sources.r1.bind=qianfeng02
a1.sources.r1.port=6666

a1.channels.c1.type=memory

a1.sinks.s1.type=avro
a1.sinks.s1.hostname=qianfeng03
a1.sinks.s1.port=6666

qianfeng03:

a1.sources=r1
a1.channels=c1
a1.sinks=s1

a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1

a1.sources.r1.type=avro
a1.sources.r1.bind=qianfeng03
a1.sources.r1.port=6666

a1.channels.c1.type=memory

a1.sinks.s1.type=logger

tamp=true




Flume的集群

qianfeng01:

```properties
a1.sources=r1
a1.channels=c1
a1.sinks=s1

a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1

a1.sources.r1.type=systcplog
a1.sources.r1.host=qianfeng01
a1.sources.r1.port=6666

a1.channels.c1.type=memory

a1.sinks.s1.type=avro
a1.sinks.s1.hostname=qianfeng03
a1.sinks1.s1.port=6666

qianfeng02:

a1.sources=r1
a1.channels=c1
a1.sinks=s1

a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1

a1.sources.r1.type=http
a1.sources.r1.bind=qianfeng02
a1.sources.r1.port=6666

a1.channels.c1.type=memory

a1.sinks.s1.type=avro
a1.sinks.s1.hostname=qianfeng03
a1.sinks.s1.port=6666

qianfeng03:

a1.sources=r1
a1.channels=c1
a1.sinks=s1

a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1

a1.sources.r1.type=avro
a1.sources.r1.bind=qianfeng03
a1.sources.r1.port=6666

a1.channels.c1.type=memory

a1.sinks.s1.type=logger
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值