Flume的一些事儿~~~
1. flume是什么
Apache Flume是一个可以从不同的数据源收集数据资源(例如日志,事件等),并将这些数量庞大的数据从各项数据源中集中起来存储的工具/服务。简略地说是一个分布式、高可用的数据收集系统。
2. flume是怎么工作的
外部数据源的信息以特定的格式向Flume发送events(事件),Flume通过启动agent来进行工作(agent之间可以级联,甚至组成复杂的拓扑结构)。当source接收到events时,它将其存储到一个或者多个channel。channel将会一直保存events,直到被sink读取完毕。sink从channel读取events之后将其发送到外部的存储系统或者转发到下一个source,成功后将该events在channel中删除。
3. flume的核心架构单元及组件的概念
-
Event(数据传输单元)
数据在channel中的封装形式,也是Flume数据传输的基本单元。因此,Source组件在获取到原始数据后,需要封装成Event放入channel,Sink组件从channel中取出Event后,需要根据目标存储的需求,转成其他形式的数据输出。
Event封装对象主要有两部分组成: Headers(标题)和 Body(正文)
header是一个集合 Map[String,String],用于携带一些KV形式的元数据(标志、描述等)
body: 就是一个字节数组byte[],装载具体的数据内容
-
Agent(Flume中最核心的角色)
lume采集系统就是由一个个agent连接起来所形成的一个或简单或复杂的数据传输通道。
每个Agent是一个独立的守护进程(JVM),它负责从数据源接收数据,并发往下一个目的地,相当于一个数据传递员。包括Source、Channel、Sink等组件。
Agent的3个组件的设计思想,主要是出于source和sink之间解耦合以及异步操作考虑
-
Source(源组件)
数据采集组件,用于跟数据源对接,以获取数据
它有各种各样的内置实现:Avro Source、Thrift Source、Kafka Source、JMS Source等
-
Channel(缓冲通道)
从source将数据传递到sink,是源和接收器之间的管道,用于临时存储数据的传输通道组件。
作用:解耦合(削峰填谷)。
可以是内存或持久化的文件系统:
Memory Channel:使用内存;优:速度快;缺:数据安全性低,数据有一定丢失可能性。
File Channel:使用持久化的文件系统;优:数据安全(可能重复,不易丢失);缺:速度慢
其他诸如Kafka Channel等类型在此不一一描述。
-
Sink(下沉组件)
用于往下一级agent传递数据或者向最终存储系统传递数据,成功后再从channel中删除event
4. flume中的一些核心概念理解:channel selector 、sink processor 、interceptor 、transaction
-
channel selector 频道选择器:
一个source可以对接多个channel,则event在这n个channel之间传递的策略,由配置的channel selector决定,即source将数据分发给他所连接的多个channel的方式。channel selector有2中实现 replicating(复制),multiplexing(多路复用)
replicating selector(复用选择器):
默认的选择器,selector将event复制,分发给所有下游节点
multiplexing selector(多路选择器):
根据event中的一个指定key的value来决定这条消息会写入的channel,具体在选择时,需要配置一个映射关系。如,a1.sources.r1.selector.mapping.CZ=c1 (header中的value为CZ的话,这条消息就会被写入c1这个channel)
-
sink processor 接收器处理器:
如果sink和channel是一对一关系,则不需要专门的sink processor;当配置的一个channel对应多个sink,则需要将这多个sink配置成一个sink group(sink组)。
event在一个组中的多个sink间如何传递,则由所配置的sink processor来决定,即协调一个sink组从channel中获取数据进行写出的方法。sink processor有2种 load balance (round robing 负载均衡)和 fail over(故障转移)。
Failover Sink Processor (失败切换):
一组中只有优先级高的那个sink工作,其余sink等待。如果高优先级的sink发送数据失败,发生错误,则转由其余sink中优先级较高的sink去工作。并且,在配置时间penalty之后,还会尝试用高优先级的去发送数据
Load balancing Sink Processor (负载均衡):
允许channel中的数据在一组sink中的多个sink之间进行轮转,策略有:round-robin(轮着发)和random(随机挑)
-
interceptor 拦截器:
拦截器工作发生在source写数据到channel之前,source产生的event会被传入拦截器(或拦截器组成的拦截器链)根据需要进行逻辑处理,然后再返回处理之后的event,从而达到对event进行加工处理的目的。这样就可以让用户在不需要改动source代码的情况下,就可以插入一些数据处理逻辑。
拦截器的调用顺序:SourceRunner -》 source 的start( )方法 --》读到一批数据,调channelProcessor . processEventBatch(events) --> 调拦截器进行拦截处理 --> 调选择器selector获取要发送的channle --> 提交数据
- static拦截器
让用户往event中添加一个自定义的header key-value(在配置文件中固定配死)
- Host 拦截器
往event的header中插入主机名(ip)信息
- UUID 拦截器
生成uuid放入event的header中
- timestamp 拦截器
向event中,写入一个kv到header里:k名称可配置;v就是当前的时间戳(毫秒)
在flume中有诸如上述的一些内置功能比较常用的拦截器,用户也可以根据自己的数据处理需求,自己开发自定义拦截器!这也是flume的一个可以用来自定义扩展的接口!
-
transaction 事务控制机制:
Flume使用两个独立的事务:
put操作:source读取数据源并写入event到channel
take操作:sink从channel中获取event并写出到目标存储
5. flume中的事务控制的设计
flume有两个独立的事务控制:
source --> channel (put事务)
channel --> sink (take事务)
事务的实现程度,取决于运行时所选择的具体的组件实现类,再好的组件的组合,目前也只能实现at least once!(不会丢失数据,但可能产生重复传输)。
一个事务的生命周期: start开启事务,commit提交事务,rollback回滚
事务实现的核心点,就是记录状态(比如source,记录自己完成的数据的偏移量)。如果因为某种原因使得事件无法记录,那么事务将回滚,且所有的事件都会保持到channel中,等待重新传递。若恰好在事件保存之后,偏移量记录之前发生宕机,则将造成这个小概率的数据重复传输,又因为数据往往按批次处理,因此,重复的事件发生时,重复的数据量往往是批次读取或处理的条数
如下例:
数据流程:
- source1产生Event,通过“put”、“commit”操作将Event放到Channel 1中
- sink 1通过“take”操作从Channel 1中取出Event,并把它发送到Source 2中
- source 2通过“put”、“commit”操作将Event放到Channel 2中
- source 2向sink 1发送成功信号,sink 1“commit”步骤2中的“take”操作(其实就是删除Channel 1中的Event)
6.flume简单使用
1.将Flume 的安装包上传到已经配好java和hadoop环境的服务器的数据源所在节点上,再进行解压:
tar -zxvf apache-flume-1.8.0-bin.tar.gz
2.根据数据采集的需求配置采集方案,描述在配置文件中(文件名可任意自定义)
- 在flume的安装目录下,新建一个文件夹(myconf),在新文件夹中再新建一个文件
- 在其中定义agent中各个组件的名称,再分别描述和配置source、channel、sink组件
3.指定采集方案配置文件,在相应的节点上启动flume agent
- 启动Flume agent(在flume的安装目录下)
bin/flume-ng agent -n a1 -c conf -f 新文件夹名/文件名 -Dflume.root.logger=INFO,console
agent 运行一个采集器
-n a1 指定这个agent
-c conf 指定flume自身的配置文件所在目录
-f 新文件夹名/文件名 指定自定义的采集方案
4.测试
往agent的source所监听的端口上发送数据,让agent有可采数据。通过telnet命令向端口发送消息
telnet linux01 44444
PS:如果没有telnet命令,用yum安装一个即可: yum -y install telnet
7.flume在大数据系统中,处于哪个环节
数据采集环节(采集层)时使用,通常用于日志数据的采集
8.什么是业务系统,大数据系统与业务系统的关系
一般来说,将公司提供业务功能的软件系统称为业务系统。不同的行业、不同的业务往往需要业务系统不同的功能。
业务系统一般是大数据系统的数据来源,大数据系统的处理结果是业务系统优化和设计的数据支撑。
OS:理解还大大的需要加强~感冒会丧失味觉什么的也太痛苦了吧 (=-=)
9.什么是序列化,avro序列化跟serializable/writable/kryo有何不同?
一个类在jvm中是有结构的,但即使是在jvm中,也是一堆数据。网络只能传文本,所以需要序列化和反序列化。
序列化是将对象的状态信息转换为可以存储或传输的形式的过程,可以将一个有复杂结构的数据块(对象)变成扁平的(线性的)二进制序列。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。
- jdk(serializable):把类的所有描述信息写在文本中传输。 效率较低。serializable接口是个标记接口,用来表示某个类可以被序列化。
- hadoop(writable):提前告知对方类的结构,则只需要传数据,发接双方的类在driver/job的配置中都已提前声明。 效率高。 类可以自定义,但必须实现hadoop提供的Writable接口,并且要自定义序列化和反序列化的方法。
- spark(kryo):默认使用jdk的序列化。 效率低。 spark在共享变量、shuffle、cache时都需要序列化。
- flume(avro):数据的读写操作很频繁,而这些操作都需要使用模式,这样就减少写入每个数据资料的开销,使得序列化快速又轻巧。这种数据及其模式的自我描述方便于动态脚本语言的使用。用JSON定义模式。
综上:
serializable是通用的,方便,效率低;
writable是定制的,需要导包,只能在MR体系内用。由开发者自定义序列化的细节。
kryo也是通用的,spark默认集成,针对Java语言,不需要导包,也可以共享类的结构信息。
PS:kryo、avro都是独立的序列化框架,spark都集成了。
10.常见的source有哪些,工作机制是怎样的
-
sink
hdfs sink:
数据最终被发往hdfs,可以生成text文件或 sequence 文件,而且支持压缩;
支持生成文件的周期性roll机制:基于文件size,或者时间间隔,或者event数量;
目标路径,可以使用动态通配符替换,比如用%D代表当前日期;
当然,它也能从event的header中,取到一些标记来作为通配符替换。如,header:{type=acb}
/weblog/%{type}/%D/ 就会被替换成: /weblog/abc/19-06-09/
kafka sink:
有了kafka channel之后,kafka sink就不那么必要了。
avro sink:
向avro source发送avro序列化数据,可以实现agent之间的级联
-
channel
channel跟事务控制有极大关系;有容量大小、可靠性级别、事务容量等特性;
memory channel:
事件被存储在实现配置好容量的内存(队列)中。
速度快,但可靠性较低,有可能会丢失数据
file channel:
event被缓存在本地磁盘文件中
可靠性高,不会丢失,在极端情况下可能会重复数据
kafka channel:
agent利用kafka作为channel数据缓存,kafka channel要跟 kafka source、 kafka sink区别开来,kafka channel在应用时,可以没有source,或者可以没有sink。
如果kafka作为最终采集存储,那就只需要 source + kafka channel
如果kafka作为数据源,要将kafka中的数据写往hdfs,那么就只要 kafka channel + hdfs sink
-
source
kafka source:
用kafka consumer连接kafka读取数据,然后转换成event写入channel
netcat source:
启动一个socket服务,监听一个端口,并将端口上收到的数据,转成event写入channel
Avro Source:
启动一个网络服务,监听一个网络端口来接受数据,而且接受的数据必须是使用avro序列化框架序列化后的数据(avro序列化流),拥有avro的反序列化器,能够将收到的二进制流进行正确反序列化,并装入一个event写入channel。
当与另一个Flume代理上的内置Avro Sink配对时,它可以创建分层集合拓扑。
Avro是一种跨语言的序列化框架。
Taildir Source:
可以实时监控一个或者一批文件,并记录每个文件被tail到的位置(或称文件读取位置,或称偏移量)到一个指定的positionfile保存目录中,格式为json(可以通过人为修改,让source从任意指定的位置开始读取数据)。对采集完成的文件,不会做任何修改。
把读到的数据成功写入channel后,再更新记录偏移量。能保证数据不会漏采(丢失),但是有可能会产生数据重复。
exec source:
启动一个用户所指定的linux shell命令,并采集这个linux shell命令的标准输出,作为收集到的数据,转为event写入channel
spooling source:
可以监听一个指定的文件夹,同步目录中的新文件内的数据,被同步完的文件被立即删除或被打上标记。将采集到的数据转成event写入channel。
适用于同步新文件,不适合对实时追加日志的文件进行监听并同步。
PS:spooling目录中的文件必须是不可变的(静态的),而且是不能重名的!否则,source会loudly fail!
OS:……其他的边积累边写吧(叮~羊可爱为您报时:晚上11点整 眼睛好累,女生专属茶话会所放松一哈儿去~~~)
11.taildir source可以用于生产环境的原因
Taildir Source可以用来实时监控一个或者一批文件,并记录每个文件最新的读取位置,若agent进程恰好在事件保存之后,偏移量记录之前发生宕机,则将造成这个小概率的数据重复传输,又因为数据往往按批次处理,因此,重启后事务不会回滚,而是在上次保存的文件读取位置再次读取,重复的数据量往往是批次读取或处理的条数。
在生产中,虽然数据的丢失和重复我们都不希望发生,但是显然,相对于丢失数据,我们对数据重复的容忍度更高一点。所以就数据基本不会发生的方面看来,Taildir Source是可靠的。