版本
1.0以后的flume-ng以及0.9以前的flume-og,新旧版本区别很大。旧版本是一整套的分布式日志收集系统,分为agent,collector和storage三层架构。而新版本只是个工具,要轻量得多。新版本不但更加稳定,而且兼容的协议更多,使用也因此更加方便。这里只会对新版本flume进行讲解。
名词解释
- source 数据源,兼容不同的协议,收集各种格式数据,包括:avro http thrift 自定义等,并处理产生event
- sink 数据目的地,把event数据以各种格式和协议发往目的地组件,支持hdfs logger avro thrift file null hbase 自定义等
- channel 对source采集到的数据进行缓存,存放方式可以支持memory、jdbc、file
- agent flume的运行单位,是一个java进程,每台机器运行一个agent,一个agent对应一个配置文件,可以包含多个source和sink,channel
- event 事件,flume的数据单元,传输数据的基本单位,包括event headers,event body。
flume 运行机制
- flume的核心是把数据从数据源(source)收集过来,再将收集过来的数据送到目的地(sink)
- 为保证数据传输一定成功,再送到目的地之前,会先缓存到channel中,当数据真正到达sink后,flume再删除自己缓存在channel的数据
- 事务保证在event级别进行
event使用
- 一行文本被序列化为一个event, event的最大定义字节是2048字节(默认,在avro方式中),如果超过,则被切割,放到下一个event 默认编码utf-8
- 如果数据源是文本文件,body则是文本中的单行记录。
- 在flume源码中,headers的类型是Map
flume的可靠性&可恢复性
- 可靠性主要依靠运行机制保证,当sink传输成功后,再删除channel的缓存数据。在0.9版本以前,可靠性是可以配置的,即三种级别的可靠性保证:end-to-end级别 收到数据的agent首先将event写到磁盘上,数据传送成功后,再删除,如果数据发送失败,则重新发送 Store on failure级别 这时scribe采用的策略,当接受方crash时,将数据写到本地,待恢复后,继续发送 besteffort级别 数据发送到接收方后,不再确认,直接删除本地数据。但1.0版本以后,是不用配置级别的,依靠source和sink选取的协议组合搭配而产生的效果,比如sink使用tcp或者udt,对可靠性是有影响的。
- 可恢复性主要依靠file channel,可以把event持久化到本地文件系统。建议FileChannel设置的目录和程序日志文件保存的目录设成不同的磁盘,以便提高效率
flume用法
- 前后相继,多级串联
- 扇入,即接受多个source 输入
- 扇出,即数据可以输出到多个sink
flume配置文件
因为可配置项太多了,配置文件在这里是不可能穷举的。在这里,将配置文件大致分为以下几个部分:
整体描述
#该agent的name是a1,其中包含了哪些source,sink,channel a1.sources = r1,r2,r3 a1.sinks = k1,k2 a1.channels = c1,c2
source相关配置
#r1source的类型是netcat,不同类型的source的配置项也不同 a1.sources.r1.type = netcat #bind 日志需要发送到的主机名或者IP地址,该主机运行着netcat类型的source在监听 a1.sources.r1.bind = localhost #port 日志需要发送到的端口号,该端口号要有netcat类型的source在监听 a1.sources.r1.port = 44444
sink相关配置
a1.sinks.k1.type = logger
channel相关配置
a1.channels.c1.type = memory a1.channels.c1.capacity = 1000 #transactionCapacity:channel的putlist(source),takelist(sink)的初始化大小 a1.channels.c1.transactionCapacity = 100 #batchSize : sink source 的 一次性处理的event的数量 #channel的transactionCapacity参数不能小于sink的batchsize
通过channel将source和sink连接起来,即三者之间的配对关系
a1.sources.r1.channels=c1 a1.sinks.k1.channels=c1
因为在大数据中hdfs是极为常用的,flume的sink端常会配置成hdfs,因此在这里,附上一些hdfs相关的配置
a1.sinks.k1.type = hdfs
a1.sinks.k1.hdfs.path = hdfs://hadoop80:9000/dataoutput
a1.sinks.k1.hdfs.writeFormat = Text
#默认Writable
a1.sinks.k1.hdfs.fileType = DataStream
#默认 SequenceFile ,还包括 DataStream,CompressedStream, 使用DataStream时,文件不会被压缩,不需设置hdfs.codeC,
a1.sinks.k1.hdfs.rollInterval = 10
#默认值:30,单位秒,每10秒将临时文件滚动生成最终目标文件。其中,滚动:指的是 hdfs sink将临时文件重命名成最终文件,并重新打开一个临时文件来写入数据
a1.sinks.k1.hdfs.rollSize = 0
#默认1024,单位bytes, 当临时文件超过rollSize时,滚动生成最终目标文件,如果为0,则不根据该值生成目标文件
a1.sinks.k1.hdfs.rollCount = 0
#默认值10 ,为events数量,当events数量到达rollCount时,则滚动生成最终目标文件,如果为0,则不根据events数量生成目标文件
a1.sinks.k1.hdfs.filePrefix = %Y-%m-%d-%H-%M-%S
#最终文件的前缀,默认值 FlumeData,可以使用flume提供的日期及%{host}表达式
a1.sinks.k1.hdfs.fileSuffix
#写入hdfs的文件名后缀,比如:.lzo .log等。
a1.sinks.k1.hdfs.inUsePrefix
#临时文件前缀
a1.sinks.k1.hdfs.inUseSuffix
#临时文件后缀
a1.sinks.k1.hdfs.useLocalTimeStamp = true
#是否使用本地时间
a1.sinks.k1.hdfs.codeC = gzip
#当fileType是CompressedStream时,需要设置
a1.sinks.k1.hdfs.idleTimeout = 30
#当没有数据写入当前临时文件时,多长时间后,将临时文件关闭,并命名生成目标文件
a1.sinks.k1.hdfs.batchSize = 100
#默认100,batchSize 每个批次刷新到hdfs上的events数量
a1.sinks.k1.hdfs.maxOpenFiles= 5000
#默认值5000,最大允许打开的hdfs文件数,当打开的文件数达到最大值,最早打开的文件将会被关闭
a1.sinks.k1.hdfs.minBlockReplicas =
#写入hdfs文件块的最小副本数,该参数会影响文件的滚动配置,一般将该参数配置成1,才可以按照配置正确滚动文件
a1.sinks.k1.hdfs.callTimeout=10000
#默认值10000, 执行hdfs操作的超时时间,单位:毫秒
a1.sinks.k1.hdfs.threadsPoolSize = 1
#默认值10,hdfs sink启动的操作hdfs的线程数
a1.sinks.k1.hdfs.kerberosPrincipal=
a1.sinks.k1.hdfs.kerberosKeytab=
#在试图连接 带有Kerberos安全认证的CDH Hadoop集群时,需要配置
a1.sinks.k1.hdfs.round=false
#默认值false 是否启用时间上的“舍弃”,这里的“舍弃”,类似于“四舍五入”,启用后,会影响除了%t的其他所有时间表达式
a1.sinks.k1.hdfs.roundValue=1
#默认值1,时间上“舍弃”的值
a1.sinks.k1.hdfs.roundUnit=seconds
#默认值seconds, 还包括:minute, hour, 时间上“舍弃”的单位
示例:
a1.sinks.k1.hdfs.path = /flume/events/%y-%m-%d/%H%M/%S
a1.sinks.k1.hdfs.round = true
a1.sinks.k1.hdfs.roundValue = 10
a1.sinks.k1.hdfs.roundUnit = minute
当时间是 2015-10-16 17:38:59时,hdfs.path,依然会被解析为 /flume/events/20151016/17:30/00,因为设置的是舍弃10分钟内的时间,因此该目录是每10分钟生成一个新的。
a1.sinks.k1.hdfs.timeZone=LocalTime
#默认值LocalTime 时区
a1.sinks.k1.hdfs.userLocalTimeStamp=false
#是否使用当地时间
a1.sinks.k1.hdfs.closeTries=0
#默认值0,尝试关闭文件的次数,如果设置为1,则尝试一次后,不再尝试,如果文件关闭失败,则该文件将会一直是打开状态,当设置为0时,则会继续尝试,直到文件关闭为止
a1.sinks.k1.hdfs.retryInterval=180
#默认值180,单位秒,尝试关闭文件的时间间隔,如果设置为0,表示不尝试,相当于closeTries设置成1
a1.sinks.k1.hdfs.serializer=Text
#默认值TEXT,序列化类型,还包括:avro_event或者是实现了EventSerializer.Builder的类名
另外,再附上spooling directory source的配置
spoolDir 监听目录
fileSuffix .COMPLETED 文件写入到channel后,标记该文件
deletePolicy never 文件写入到channel后的删除策略 never or immediate
fileHeader false Whether to add a header storing the absolute path filename. 是否添加一个header,在header中存下文件的绝对路径
ignorePattern ^$ Regular expression specifying whick files to ignore 判断文件是否被忽略的正则表达式
interceptors 指定传输中event的head(头信息),常用timestamp
fileHeader 设置为true时 logger的结果
Event: { headers:{file=/home/light/grootenv/data/datafile, timestamp=1523864703546} body: 62 69 67 20 64 61 74 61 20 77 6F 72 6C 64 21 big data world! }
设置为false时
Event: { headers:{timestamp=1523865061746} body: 62 69 67 20 64 61 74 61 20 77 6F 72 6C 64 21 big data world! }
flume拦截器
flume拦截器是属于配置的内容,但是因为比较常用,所以拿出来单独讲
拦截器定义
host类型拦截器的定义方式如下:
1. a1.sources.r1.interceptors = i1
2. a1.sources.r1.interceptors.i1.type = host
3. a1.sources.r1.interceptors.i1.hostHeader = [hostname]
时间戳类型的拦截器
type=timestamp
1. a1.sources.r1.interceptors = i1
2. a1.sources.r1.interceptors.i1.type = timestamp
自定义类型拦截器:
type=static
1. a1.sources.r1.interceptors = i1
2. a1.sources.r1.interceptors.i1.type = static
3. a1.sources.r1.interceptors.i1.key= [topic]
4. a1.sources.r1.interceptors.i1.value= [flume_test]
Regex Filtering Interceptor:通过正则来清洗或包含匹配的events。
1. tier1.sources.source1.interceptors=i1
2. tier1.sources.source1.interceptors.i1.type=regex_filter
3. tier1.sources.source1.interceptors.i1.regex=\\{.*\\}
Regex Extractor Interceptor:通过正则表达式来在header中添加指定的key,value则为正则匹配的部分
flume环境/安装/启动
flume官网下载http://flume.apache.org/download.html
环境依赖jvm
下载后直接解压即可
启动:
- 编写配置文件,conf目录下,可以copy已有的模板,在模板基础上进行修改
- 进入bin目录
flume-ng agent -n a1 -c ../conf -f ../conf/example.file -Dflume.root.logger=DEBUG,console
-n 指定agent名称 与配置文件中代理的名字相同 -c 指定flume中配置文件的目录 -f 指定配置文件 -Dflume.root.logger=DEBUG,console设置日志等级
flume demo
- 准备两台服务器(可以使用虚拟机),并在其中一台下载flume
- source使用netcat,sink使用logger,channel使用memory
flume 配置文件如下:
a1.sources = r1 a1.channels = c1 a1.sinks = k1 # For each one of the sources, the type is defined a1.sources.r1.type = netcat # 0.0.0.0代表任何一台机器向这部机器的4444端口发送内容,都会被收集 a1.sources.r1.bind = 0.0.0.0 a1.sources.r1.port = 4444 # The channel can be defined as follows. a1.sources.r1.channels = c1 # Each sink's type must be defined a1.sinks.k1.type = logger #Specify the channel the sink should use a1.sinks.k1.channel = c1 # Each channel's type is defined. a1.channels.c1.type = memory a1.channels.c1.transactionCapacity = 100 # Other config values specific to each type of channel(sink or source) # can be defined as well # In this case, it specifies the capacity of the memory channel a1.channels.c1.capacity = 1000
- 启动flume
flume-ng agent -n a1 -c ../conf -f ../conf/netcat.conf -Dflume.root.logger=DEBUG,console 在另一台机器上,使用telnet发送数据(安装了flume的机器IP是192.168.80.80)
- windows系统时,telnet 192.168.80.80 44444 big data world!
linux中时,telnet 192.168.80.80 44444
Trying 192.168.10.71... Connected to 192.168.10.71. Escape character is '^]'.
出现以上内容后,再输入内容“big data world!”,并回车
在flume启动后的控制台上查看到了flume收集到的日志数据