4.6合并流
日志收集中很常见的情况是大量日志生成客户端将数据发送到连接到存储子系统的少数客户代理。例如,从数百个Web服务器收集的日志发送给十几个写入HDFS集群的代理。
Flume可以通过配置多个第一层代理和一个avro sink来实现这一点,所有代理都指向单一代理的avro source(同样,您可以在这种情况下使用thrift source/sink/客户端)。第二层代理上的此源将接收到的事件整合到单个channel中,最终由sink消费。
1、将分散的大量数据合并输出到一台服务器,可以通过配置多个第一层代理和一个avro sink来实现。该avro sink指定目标服务器的avro source。 2、实现合并流,除了使用avro以外,还可以使用thrift。 |
4.7复用流
Flume支持将事件流复用到一个或多个目的地。这是通过定义一个流复用器来实现的,该复用器可以复制或选择性地将事件路由到一个或多个通道。
上面的例子显示了来自代理“foo”的信息源将信息流分散到三个不同的渠道。这扇出(fan-out)可以复制或复用。在复制流程的情况下,每个事件都发送到所有三个通道。对于复用案例,当事件的属性与预配置的值匹配时,事件将传递到可用通道的子集。例如,如果名为“txnType”的事件属性设置为“customer”,则它应该转到channel1和channel3,如果它是“vendor”,那么它应该转到channel2,否则转到channel3。映射可以在代理的配置文件中设置。
通过Flume的配置(使用一个source,配置多个channel和sink),可以实现流的复用。 |
4.8配置详解
如前面部分所述,Flume代理配置是从类似具有分层属性设置的Java属性文件格式的文件中读取的。
1、定义流程
要在单个代理中定义流程,需要通过channel来连接source和sink。需要列出给定agent的source,sink和channel,然后将source和sink指向一个channel。Source的实例可以指定多个channel,但一个sink实例只能指定一个channel。格式如下:
# list the sources, sinks and channels for the agent <Agent>.sources = <Source> <Agent>.sinks = <Sink> <Agent>.channels = <Channel1> <Channel2>
# set channel for source <Agent>.sources.<Source>.channels = <Channel1> <Channel2> ...
# set channel for sink <Agent>.sinks.<Sink>.channel = <Channel1> |
例如,名为agent_foo的代理正在从外部avro客户端读取数据,并通过内存通道将其发送到HDFS。配置文件weblog.config可能如下所示:
# list the sources, sinks and channels for the agent agent_foo.sources = avro-appserver-src-1 agent_foo.sinks = hdfs-sink-1 agent_foo.channels = mem-channel-1
# set channel for source agent_foo.sources.avro-appserver-src-1.channels = mem-channel-1
# set channel for sink agent_foo.sinks.hdfs-sink-1.channel = mem-channel-1 |
这将使事件通过内存通道mem-channel-1从avro-AppSrv-source流向hdfs-Cluster1-sink。当代理以weblog.config作为其配置文件启动时,它将实例化该流。
1、在单个agent中定义流程的时候,需要通过channel来连接source和sink。需要列出给定agent的source,sink和channel,然后将source和sink指向一个channel。Source的实例可以指定多个channel,但一个sink实例只能指定一个channel。 2、Source和channel的关系可以是一对一,一对多,也可以是多对一。但channel和sink的关系只能是一对一。 |
2、配置单个组件
定义流程之后,您需要设置每个source,sink和channel的属性。这是以相同的分层名称空间方式完成的,您可以在其中设置特定于每个组件的属性的组件类型和其他值:
# properties for sources <Agent>.sources.<Source>.<someProperty> = <someValue>
# properties for channels <Agent>.channel.<Channel>.<someProperty> = <someValue>
# properties for sinks <Agent>.sources.<Sink>.<someProperty> = <someValue> |
需要为Flume的每个组件设置属性“type”,以便了解它需要的对象类型。每个source,sink和channel类型都有自己的一组属性,以使其按预期运行。所有这些都需要根据需要进行设置。在前面的示例中,我们通过内存通道mem-channel-1从avro-AppSrv-source流向hdfs-Cluster1-sink。以下是一个显示每个组件的配置的示例:
agent_foo.sources = avro-AppSrv-source agent_foo.sinks = hdfs-Cluster1-sink agent_foo.channels = mem-channel-1
# set channel for sources, sinks
# properties of avro-AppSrv-source agent_foo.sources.avro-AppSrv-source.type = avro agent_foo.sources.avro-AppSrv-source.bind = localhost agent_foo.sources.avro-AppSrv-source.port = 10000
# properties of mem-channel-1 agent_foo.channels.mem-channel-1.type = memory agent_foo.channels.mem-channel-1.capacity = 1000 agent_foo.channels.mem-channel-1.transactionCapacity = 100
# properties of hdfs-Cluster1-sink agent_foo.sinks.hdfs-Cluster1-sink.type = hdfs agent_foo.sinks.hdfs-Cluster1-sink.hdfs.path = hdfs://namenode/flume/webdata
#... |
1、流程定义完之后,需要设置每个source、channel和sink的属性。如果某一类组件有多个,需要使用空白符分割。 2、每个组件的“type”属性是必须的。 3、每个组件都有一组属性,它们都是可配置的。 |
3、在一个agent中添加多个流
一个Flume agent可以包含多个独立的流程。您可以在配置中列出多个source,sink和channel。这些组件可以链接以形成多个流程:
# list the sources, sinks and channels for the agent <Agent>.sources = <Source1> <Source2> <Agent>.sinks = <Sink1> <Sink2> <Agent>.channels = <Channel1> <Channel2> |
然后,您可以将sources和sinks链接到channel(用于sinks)的相应channels(用于sources)以设置两个不同的流。例如,如果您需要在代理中设置两个流程,一个从外部avro客户端到外部HDFS,另一个从tail source输出到avro sink,那么这里是一个配置来执行此操作:
# list the sources, sinks and channels in the agent agent_foo.sources = avro-AppSrv-source1 exec-tail-source2 agent_foo.sinks = hdfs-Cluster1-sink1 avro-forward-sink2 agent_foo.channels = mem-channel-1 file-channel-2
# flow #1 configuration agent_foo.sources.avro-AppSrv-source1.channels = mem-channel-1 agent_foo.sinks.hdfs-Cluster1-sink1.channel = mem-channel-1
# flow #2 configuration agent_foo.sources.exec-tail-source2.channels = file-channel-2 agent_foo.sinks.avro-forward-sink2.channel = file-channel-2 |
上面的配置可以用下面这个图来表示:
一个agent中可以配置多个流。 |
4、配置一个多agent的流
要建立一个多层流,你需要有一个第一个hop的avro/thrift sink指向下一个hop的avro/thrift source。这将使第一个Flume agent将events转发到下一个Flume gent。例如,如果您定期使用avro客户端将文件(每个event一个文件)发送到本地Flume agent,则此本地agent可以将其转发给已安装存储的另一个agent。
Weblog代理配置:
# list sources, sinks and channels in the agent agent_foo.sources = avro-AppSrv-source agent_foo.sinks = avro-forward-sink agent_foo.channels = file-channel
# define the flow agent_foo.sources.avro-AppSrv-source.channels = file-channel agent_foo.sinks.avro-forward-sink.channel = file-channel
# avro sink properties agent_foo.sinks.avro-forward-sink.type = avro agent_foo.sinks.avro-forward-sink.hostname = 10.1.1.100 agent_foo.sinks.avro-forward-sink.port = 10000
# configure other pieces #... |
HDFS代理配置:
# list sources, sinks and channels in the agent agent_foo.sources = avro-collection-source agent_foo.sinks = hdfs-sink agent_foo.channels = mem-channel
# define the flow agent_foo.sources.avro-collection-source.channels = mem-channel agent_foo.sinks.hdfs-sink.channel = mem-channel
# avro source properties agent_foo.sources.avro-collection-source.type = avro agent_foo.sources.avro-collection-source.bind = 10.1.1.100 agent_foo.sources.avro-collection-source.port = 10000
# configure other pieces #... |
在这里,我们将weblog代理的avro-forward-sink链接到hdfs代理的avro-collection-source。这将使来自外部应用服务器源的事件最终存储在HDFS中。
这个配置的示意图如下:
多层流需要注意的是:前一个sink或者后一个source必须是avro/thrift类型。 |
5、扇出(fan out)流
正如前面部分所讨论的,Flume支持从一个source向多个channels。实现fan out,有复制和复用两种模式。在复制流程中,事件被发送到所有配置的通道。在多路复用的情况下,该事件仅被发送到限定的channels的一个channel。为了扩大流量,需要为source指定一个channel列表和扇出的策略。这通过添加可以复制或复用的channel“选择器”(selector)来完成。如果是一个多路复用器,然后进一步指定选择规则就可以了。如果您不指定选择器,则默认情况下它使用复制的模式。
# List the sources, sinks and channels for the agent <Agent>.sources = <Source1> <Agent>.sinks = <Sink1> <Sink2> <Agent>.channels = <Channel1> <Channel2>
# set list of channels for source (separated by space) <Agent>.sources.<Source1>.channels = <Channel1> <Channel2>
# set channel for sinks <Agent>.sinks.<Sink1>.channel = <Channel1> <Agent>.sinks.<Sink2>.channel = <Channel2>
<Agent>.sources.<Source1>.selector.type = replicating |
复用选择使用另一组属性来分流。这要求指定一个事件属性到通道集的映射。选择器检查事件头中的每个已配置属性。如果它匹配指定的值,那么该事件将被发送到映射到该值的所有通道。如果没有匹配,则将事件发送到配置为默认值的一组通道:
# Mapping for multiplexing selector <Agent>.sources.<Source1>.selector.type = multiplexing <Agent>.sources.<Source1>.selector.header = <someHeader> <Agent>.sources.<Source1>.selector.mapping.<Value1> = <Channel1> <Agent>.sources.<Source1>.selector.mapping.<Value2> = <Channel1> <Channel2> <Agent>.sources.<Source1>.selector.mapping.<Value3> = <Channel2> #...
<Agent>.sources.<Source1>.selector.default = <Channel2> |
映射允许每个值重复使用channel。
以下示例具有复用到两 个路径的单个流。名为agent_foo的agent具有一个avro source和两个链接到两个sinks的通道:
# list the sources, sinks and channels in the agent agent_foo.sources = avro-AppSrv-source1 agent_foo.sinks = hdfs-Cluster1-sink1 avro-forward-sink2 agent_foo.channels = mem-channel-1 file-channel-2
# set channels for source agent_foo.sources.avro-AppSrv-source1.channels = mem-channel-1 file-channel-2
# set channel for sinks agent_foo.sinks.hdfs-Cluster1-sink1.channel = mem-channel-1 agent_foo.sinks.avro-forward-sink2.channel = file-channel-2
# channel selector configuration agent_foo.sources.avro-AppSrv-source1.selector.type = multiplexing agent_foo.sources.avro-AppSrv-source1.selector.header = State agent_foo.sources.avro-AppSrv-source1.selector.mapping.CA = mem-channel-1 agent_foo.sources.avro-AppSrv-source1.selector.mapping.AZ = file-channel-2 agent_foo.sources.avro-AppSrv-source1.selector.mapping.NY = mem-channel-1 file-channel-2 agent_foo.sources.avro-AppSrv-source1.selector.default = mem-channel-1 |
选择器检查名为“State”的header(event分为header和body)。如果该值为“CA”,则其发送到mem-channel-1,如果它是“AZ”则转到file-channel-2,如果它是“NY”则转到这两个channels。如果“State”的header未设置或与三者中的任何一个不匹配,则它转到被指定为“default”的mem-channel-1。
selector还支持可选channels。要为header指定可选channel,可按以下方式使用config参数'optional':
# channel selector configuration agent_foo.sources.avro-AppSrv-source1.selector.type = multiplexing agent_foo.sources.avro-AppSrv-source1.selector.header = State agent_foo.sources.avro-AppSrv-source1.selector.mapping.CA = mem-channel-1 agent_foo.sources.avro-AppSrv-source1.selector.mapping.AZ = file-channel-2 agent_foo.sources.avro-AppSrv-source1.selector.mapping.NY = mem-channel-1 file-channel-2 agent_foo.sources.avro-AppSrv-source1.selector.optional.CA = mem-channel-1 file-channel-2 agent_foo.sources.avro-AppSrv-source1.selector.mapping.AZ = file-channel-2 agent_foo.sources.avro-AppSrv-source1.selector.default = mem-channel-1 |
selector将首先尝试写入所需的channel,如果这些channels中的一个channel未能消费events,则消费失败(因为这个过程是一个事务)。这个消费会在所有channels上重新尝试。一旦所有需要的channel消费了events,则selector将尝试写入可选channel。任何可选channel消费事件的时候出现故障都会被忽略,不会重试。
如果可选channels和指定的headers所需的chnnels之间存在重叠,则认为该channel是必需的,并且channel故障将导致重试整组所需的channel。例如,在上面的例子中,对于标题“CA”,mem-channel-1被认为是所需的chnnel,即使它被标记为必需和可选,并且写入该channel的失败将导致该event在为selector配置的所有channels上重试。
请注意,如果header没有任何所需的channels,则该event将被写入default channels,并将尝试写入该header的可选channel。如果没有指定所需的channel,指定可选channel仍然会将event写入default channels。如果没有channel被指定为default channel并且没有要求,则selector将尝试将event写入可选channel。在这种情况下,任何失败都会被忽略。
1、由一个source到多个channel,就是扇出(fan out)。 2、实现扇出,有两种方式:复制和复用。复制为默认的方式。 3、复制的模式就是为所有的channel都复制一份数据。复用就是只发送到一个channel。因为是多个channel,所以就涉及到选择发送到哪个channel的问题。通道选择器就是实现这个功能的。 4、通道选择器属于Flume的一个组件。有单独的一组属性需要配置。 5、配置通道选择器需要指定一个map,即指定event的header符合哪个条件路由到哪个channel的规则。可以将多个header的条件分配到一个channel中。如果没有匹配,会发送到默认的channel。 6、通道选择器选择channel的时候分为必须的channel和可选的channel。必须的channel的失败会重试,可选的channel的失败会被忽略。 7、一个channel如果既是必须的又是可选的。则Flume按照该channel是必须的来进行处理。 |