sink group允许组织多个sink到一个实体上,sink processors能够提供在组内所有sink之间实现负载均衡的能力,而且在失败的情况下能够进行故障转移从一个sink到另一个sink,简单的说就是一个source对应一个,即多个sink,这里考虑的是可靠性与性能,即故障转移与负载均衡的设置
Property Name
|
Default
|
Description
|
sinks
|
-
|
以空格分割sink列表
|
processor.type
|
default
|
组件类型名称,需要是默认值,故障转移或负载平衡
|
Processors类型:default(默认:无)、failover(故障转移)和load_balance(负载均衡),目前自定义processors还不支持
例:
a1.sinkgroups=g1
a1.sinkgroups.g1.sinks=k1 k2
a1.sinkgroups.g1.processor.type=load_balance
Default Sink Processor
接收单一的sink,不强制用户为sink创建processor。就是原始的写法
Failover Sink Processor(故障转移)
会通过配置维护一个优先级列表,保证每一个有效的事件都会被处理,故障转移的工作原理是将连续失败sink分配到一个池中,被分配一个冷冻期,在冷冻期内,这个sink不会做任何事一旦sink成功发送一个event,sink将被还原到live 池中。
在这配置中,要设置sinkgroups processor为failover,需要为所有的sink分配优先级,所有的优先级数字必须是唯一的,这个得格外注意。此外,failover time的上限可以通过maxpenalty 属性来进行设置。
例:
a1.sinkgroups=g1
a1.sinkgroups.g1.sinks=k1 k2
a1.sinkgroups.g1.processor.type=failover
a1.sinkgroups.g1.processor.priority.k1=5
a1.sinkgroups.g1.processor.priority.k2=10
a1.sinkgroups.g1.processor.maxpenalty=10000
这里首先要申明一个sinkgroups,然后再设置2个sink ,k1与k2,其中2个优先级是5和10,而processor的maxpenalty被设置为10秒,默认是30秒。
.png)
flume client端生成两个sink,每个sink分别指向到agent2、agent3的server端source,从而实现负载均衡原理,根据权重(优先级)去分配数据,小文件只使用一个优先级高的server端去收集数据、大文件通过优先级使用server端收集数据
master中的flume配置(client端)
#agent1名称 agent1.sources = r1 agent1.channels = c1 agent1.sinks = k1 k2 #sink组名称 agent1.sinkgroups = g1 #设置sink组包含sink1,sink2 agent1.sinkgroups.g1.sinks = k1 k2 #高可靠性 agent1.sinkgroups.g1.processor.type = failover #设置优先级 priority优先级 maxpenalty agent1.sinkgroups.g1.processor.priority.k1 = 10 agent1.sinkgroups.g1.processor.priority.k2 = 1 agent1.sinkgroups.g1.processor.maxpenalty = 10000 #日志源 agent1.sources.r1.type = spooldir agent1.sources.r1.spoolDir =/usr/local/logs #要收集数据的路径 #agent1.sources.r1.interceptors = i1 i2 #agent1.sources.r1.interceptors.i1.type = static #agent1.sources.r1.interceptors.i1.key = Type #agent1.sources.r1.interceptors.i1.value = LOGIN #agent1.sources.r1.interceptors.i2.type = timestamp # 设置sink1 agent1.sinks.k1.channel = c1 agent1.sinks.k1.type = avro #sink1所在主机 agent1.sinks.k1.hostname = 192.168.20.11 agent1.sinks.k1.port = 52020 #设置sink2 agent1.sinks.k2.channel = c1 agent1.sinks.k2.type = avro #sink2所在主机 agent1.sinks.k2.hostname = 192.168.20.12 agent1.sinks.k2.port = 52020 #因为flume 的client端的sink要把数据传输到server端,所有在启动client端的flume之前要先启动server端的flume,否则会抛错 #set channel agent1.channels.c1.type = memory agent1.channels.c1.capacity = 1000 agent1.channels.c1.transactionCapacity = 100 agent1.sources.r1.channels = c1
#设置 Agent名称 agent1.sources = r1 agent1.channels = c1 agent1.sinks = k1 #设置channlels agent1.channels.c1.type = memory agent1.channels.c1.capacity = 1000 agent1.channels.c1.transactionCapacity = 100 # 当前节点信息 agent1.sources.r1.type = avro #绑定主机名 agent1.sources.r1.bind = 192.168.20.11 #绑定从192.168.20.11 端口52020收集数据 #agent1.sources.r1.port = 52020 agent1.sources.r1.interceptors = i1 agent1.sources.r1.interceptors.i1.type = static agent1.sources.r1.interceptors.i1.key = Collector agent1.sources.r1.interceptors.i1.value = 192.168.20.11 agent1.sources.r1.channels = c1 #sink的hdfs地址 agent1.sinks.k1.type=hdfs agent1.sinks.k1.hdfs.path=hdfs://master:9000/logs #server端输出到hdfs://master:9000/logs这个文件夹 agent1.sinks.k1.hdfs.fileType=DataStream agent1.sinks.k1.hdfs.writeFormat=TEXT #每1K产生文件 agent1.sinks.k1.hdfs.rollInterval=1 agent1.sinks.k1.channel=c1 #文件后缀 agent1.sinks.k1.hdfs.filePrefix=%Y-%m-%d
启动flume集群
1)启动collector,即192.168.20.11,192.168.20.12
flume-ng agent -n agent1 -c . -f /usr/local/hadoop/flume-1.6.0/conf/agent.conf flume-server -Dflume.root.logger=INFO,console
2)启动agent,即192.168.20.10
flume-ng agent -n agent1 -c . -f /usr/local/hadoop/flume-1.6.0/conf/agent.conf flume-client -Dflume.root.logger=INFO,console
3)启动hdfs
start-dfs.sh/start-all.sh(启动全部hadoop)
疑难杂症
1、在搭建flume集群收集日志写入hdfs时发生了下面的错误:
java.lang.NullPointerException: Expected timestamp in the Flume event headers, but it was null
原因是因为写入到hfds时使用到了时间戳来区分目录结构,flume的消息组件event在接受到之后在header中没有发现时间戳参数,导致该错误发生,有三种方法可以解决这个错误;
1、agent1.sources.source1.interceptors = t1
agent1.sources.source1.interceptors.t1.type = timestamp 为source添加拦截,每条event头中加入时间戳;(效率会慢一些)
2、agent1.sinks.sink1.hdfs.useLocalTimeStamp = true (加到server端配置中)为sink指定该参数为true (如果客户端和flume集群时间不一致数据时间会不准确)
3、在向source发送event时,将时间戳参数添加到event的header中即可,header是一个map,添加时mapkey为timestamp(推荐使用)
2、
权限不够
java.io.FileNotFoundException: /home/hadoop/king/flume/103104/trackerDir/.flumespool-main.meta (Permission denied)
at java.io.FileOutputStream.open0(Native Method)
注意这里的这个/home/hadoop/king/flume/103104/trackerDir/.flumespool-main.meta 文件是个隐藏文件,
刚开始没找到,后面使用ll -a找到了。
然后修改权限 chmod 777 /home/hadoop/king/flume/103104/trackerDir/.flumespool-main.meta