大数据为时下热门,国家倡导五大新基建之内容,在这个时代要想发财,一要抱紧国家大腿,紧跟党的步伐。其二要在时代风口来临大家还没有一窝蜂地涌上的时候果断杀上去。三是要有门槛,不能一个农民工培训一下出来也能跟你竞争干这个。所以在这个七月我果断辞职(之前干的是一个专做外包业务的小公司的Java开发)报名了拉勾教育的大数据高薪训练营。
在之前那个做政府外包项目的小公司干的时候,工资少,技术没有成长,政府项目还傻逼,给一个boss看一下就要你整个需求翻天覆地地改一遍,然而,他们有很多个领导,要看很多次。而且,领导看之前你就得熬夜加班改一宿,我那个破小公司还没有加班工资......而且我们这个Java开发行业,干外包的,门槛极低,低得令人发指,一个农民工培训一下出来就能上手干活了,而且农民工还吃苦耐劳,要得还少,我曾亲眼见到一个培训机构里面一个老师满口答应着一大帮高中出来的农民工说可以帮他们培训出来并且找到工作......我也曾亲眼见过一个农民工只要1000块实习工资就肯跟着一个出来创业的人干活......
这些都太恐怖了,想起这些每每都把我从梦中惊醒过来。
2020年上半年时,经手两个政府的外包项目,作为Java后端开发的总负责人,坐在椅子上连轴转了大约三个月左右,那时候天气热,又生痔疮,工期紧没空去医院看,那段时间我天天大便出血,也许是身体缺血,虚弱到了极致,那时候天天想着解决bug极其烧脑,耗伤心血,天天掉发,我整个人极度憔悴。终于有一天我在镜子里看到失去了往日乌黑浓密的秀发的我再也没有以前那么靓仔了,我伤心欲绝,大有种逝去的芳华再也无法挽留的伤感,于是我思前想后,总结了一下我这两年的开发生涯,正好在微信公号上看到拉勾招生训练营的招生广告,于是痛定思痛,咬咬牙,狠心辞职报名了拉勾的大数据高薪训练营。
当初之所以选择了拉勾教育的大数据高薪训练营是基于两点来考虑的,一、拉勾本身是一个面向互联网行业的招聘平台,手中握有大量的优质互联网,那他的内推就肯定是有实际资源的背书。像别的培训机构都是往届学员进了某大厂然后就在外面瞎吹牛说自己有什么大厂合作资源,可以内推,就像某廖X峰团队一样,你交了钱进去肯定以后还是要让你编造项目经历的。第二就是人家大数据,说的是大数据,那当然是要有大量的数据给你做项目练习用的,不然怎么叫大数据?而拉勾作为一个互联网平台自身就有真实并且是实时的数据给学员作为练习用的,而其他的团队呢?从网上爬取?用离线的非实时数据?开什么玩笑。
虽然作为其中的学员这段话是有点偏向性,但是理确实是这么个理。
好,废话不多说,既然是写学习笔记当然还是得回到学习内容上来。之前的前导内容有Hadoop核心基础(hdfs、mapreduce、yarn)和hive、hue,但是前面学这些内容时太忙了没来得及写笔记,以后会一一补上。下面开始flume之旅。
我们学习一个工具及其原理时,都需要回答这几个问题,它是什么,它是怎样的,它有什么,为什么,它是怎么做的。学完这几个问题你能回答得上你就出师了。
首先,它是什么,flume是一个数据采集工具。然后解答为什么,你想想,之前你要用Hadoop分析数据,难道你要一份一份地down下来然后再吭哧吭哧地上传到Hadoop平台上去吗?都说了大数据大数据,他的数据量肯定不会少的,如果是个几百个G的数据,你手工这么搞,等你采集完数据猫都睡了,负责干数据分析的伙计还用不用干活了,所以flume解决的就是自动化采集数据的这么一个问题。然后flume还有其独门秘籍:他可以部署在多个节点上,他是分布式,因此他是高可用的,可以传输海量的数据。
然后再来回答他有什么,他是怎样的。
1、flume由source、channel、sink组成,source是数据采集端,channel是数据缓冲区,sink是数据输出端。source和sink都是容易理解的,channel是个什么鬼?你可以理解成一条生产线,生产线上端(source)的伙计不断的往传送带上放东西,放得很快,然后传送带下端的伙计(sink)处理不过来,快干崩了,这时下端的伙计急了得找上端的伙计拼命了,这个时候就需要channel来协调这种传送和处理的速率不一致的问题了。
2、flume的结构,flume的基本结构是source、channel、sink,三者缺一不可,但是我可没告诉过你不可以有重复。一个source+一个或多个channel+一个或多个sink组成的基本单元叫agent。
串行级联方式:就是一个agent后面接着另一个agent,上一个agent的sink输出作为下一个agent的source输入。
多channel多sink方式:就是从一个source后面出发可以接多个channel,然后每一个channel后面接不同的sink,这样子一个source输入就可以有多种不同的输出方式了,真正做到一鱼多吃。值得注意的是每一个channel后面只能接一个sink输出。
负载均衡模式:一个agent后面级联多个并列的agent,这几个并列的agent部署在不同的节点上。可以由不同的agent分担传输的压力,一个节点挂了之后可以由另外一个agent顶上。
聚合模式:多个并列的agent后面级联一个agent把拿到的数据聚集在一个agent上,这样子多个agent分担了传输压力,集中到一个agent上方便统一处理。
3、flume有不同类型的source、channel和sink,可以用不同类型的这三个伙计干不同类型的活,source有avro、exec、netcat、spooldir、taildir。channel有memory和file。sink有avro、hdfs、logger、file。
下面来一一解释都是用来干嘛的。
avro source,前面说过了,agent之间会有级联的方式,而不同的agent会处于不同的节点上,而avro source/sink就是用来进行节点间传输用的,一般avro sink后面的下游agent开头就是avro source。netcat source是用来监听端口的数据的,结合telnet host port服用效果更好。exec source是用来监听命令产生的数据的,比如tail -F命令(一个用来获取文件尾部内容的命令),但是不稳定,会产生数据丢失,也就是不能断点续传,因此生产环境很少用这个东西了。spooldir source是用来监听文件夹里的新文件的,这个东西不像exec source那样会不可靠易丢失文件,但是也有缺点就是不能上传重名文件,以及不能对文件内容修改。而相当于exec source+spooldir source的taildir source就结合了两者的特点而又没有两者的弊端,他会产生一个json文件记录各个文件的最新消费位置,也可以通过配置修改读取位置。source的种类比较多,但是一般记住avro、spooldir、taildir三种也就差不多了。
channel有两种,memory和file,memory可以理解为内存,file可以理解为磁盘文件,前者高速但是易失,后者慢但是不易丢失。
sink的avro前面说过了,logger是把输出打印在控制台上,一般是用来调试的,file类型是把数据存到本地文件中。hdfs是最重要的,是把输出数据保存到hdfs文件系统中。
好了,以上,就全部述说了flume是什么,有什么,怎么样,为什么。还有最后一步,也是最关键的一步,怎么做。对于代码从业者来说,搞懂前面几个能让你应付面试,但是最后一步你不会你的所学就永远只能是空中楼阁,掌握了学习方法论中的怎么做你才能把所学融会贯通。
我这人一向主张操作式学习——通过操作自然而然形成肌肉记忆和理解,自上而下式学习——你能操作复杂的东西自然就懂得简单的东西了,所以下面直接上比较复杂的flume配置——级联式负载均衡flume结构。
级联式负载均衡flume采用一个agent后面级联两个agent实现故障转移。直接上拓扑图:
这里配置节点三用taildir source,channel用memory channel,sink用avro sink进行远程传输,用两个sink配成一个sink组,sink组配成故障转移模式。节点一和二配成一样的,当其中一个节点宕机后把传输任务转移到另一个节点上。
首先简述flume怎么运作起来,首先得在各个节点安装flume,这个不细说了,现在都是傻瓜化安装,先解压缩flume安装包然后在/etc/profile配置flume的环境变量,然后执行source /etc/profile命令。然后在每个节点写一个配置文件配置agent,写明source、channel、sink的类型,然后用flume的命令把配置文件运行起来。下面写一下各节点的配置,各个配置的说明都写在里面了。
节点三配置文件名flume-taildir-avro.conf,以下是配置信息:
##gent与source、channel、sink的命名
##agent=a1
a1.sources = r1
a1.channels = c1 c2
a1.sinks = k1 k2
##复制选择器
a1.sources.r1.selector.type=replicating
##把c2设置成可选发送失败不会重发
a1.sources.r1.selector.optional=c2
### host拦截器
a1.sources.r1.interceptors=i1 i2 i3
a1.sources.r1.interceptors.i1.type=static
a1.sources.r1.interceptors.i1.key=Type
a1.sources.r1.interceptors.i1.value=LOGIN
###header中同名属性是否保留
a1.sources.r1.interceptors.i1.preserveExisting=flase
a1.sources.r1.interceptors.i2.type=host
###header中同名属性是否保留
a1.sources.r1.interceptors.i2.preserveExisting=flase
##是否使用ip
a1.sources.r1.interceptors.i2.useIP=flase
a1.sources.r1.interceptors.i3.type=timestamp
a1.sources.r1.interceptors.i3.preserveExisting=false
##taildir source
a1.sources.r1.type = taildir
##记录消费位置的文件
a1.sources.r1.positionFile =/root/flume/taildir_position.json
##文件组
a1.sources.r1.filegroups=f1
##匹配以一个或多个log结尾的文件
a1.sources.r1.filegroups.f1=/opt/lagou/servers/hive-2.3.7/logs/.*log
##memory channel1
a1.channels.c1.type = memory
a1.channels.c1.capacity = 10000
a1.channels.c1.transactionCapacity = 500
##memory channel2
a1.channels.c2.type = memory
a1.channels.c2.capacity = 10000
a1.channels.c2.transactionCapacity = 500
a1.sinkgroups=g1
a1.sinkgroups.g1.sinks=k1 k2
##avro sink1
a1.sinks.k1.type = avro
a1.sinks.k1.hostname = linux1
a1.sinks.k1.port = 9091
##avro sink2
a1.sinks.k2.type = avro
a1.sinks.k2.hostname = linux2
a1.sinks.k2.port = 9092
##sink组故障转移
a1.sinkgroups.g1.processor.type=failover
a1.sinkgroups.g1.processor.priority.k1=100
a1.sinkgroups.g1.processor.priority.k2=60
a1.sinkgroups.g1.processor.maxpenalty=10000
##source、channel、sink的关系
##source会对应多channel,但每个sink只能对应单channel
a1.sources.r1.channels = c1 c2
a1.sinks.k1.channel = c1
a1.sinks.k2.channel = c2
节点一配置文件名flume-avro-hdfs.conf,以下是配置信息:
##agent=a2
a2.sources = r2
a2.channels = c2
a2.sinks = k2
##avro source
a2.sources.r2.type = avro
a2.sources.r2.bind=linux1
a2.sources.r2.port=9091
##interceptors
a2.sources.r2.interceptors=i1
a2.sources.r2.interceptors.i1.type=static
a2.sources.r2.interceptors.i1.key=collector
a2.sources.r2.interceptors.i1.value=linux1
##memory channel
a2.channels.c2.type = memory
a2.channels.c2.capacity = 10000
a2.channels.c2.transactionCapacity = 500
##hdfs sink
a2.sinks.k2.type = hdfs
a2.sinks.k2.hdfs.path=hdfs://linux1:9000/flume/failover/%Y%m%d/%H%M
a2.sinks.k2.hdfs.filePrefix=%Y-%m-%d
a2.sinks.k2.hdfs.writeFormat=TEXT
##此处用header拦截器时间
a2.sinks.k2.hdfs.useLocalTimeStamp =false
##积攒够500Event就flush到hdfs一次
a2.sinks.k2.hdfs.batchSize = 500
##文件类型与压缩,datastream不支持压缩
a2.sinks.k2.hdfs.fileType = DataStream
##60s滚动一次文件
a2.sinks.k2.hdfs.rollInterval =60
##128m滚动一次禁用
a2.sinks.k2.hdfs.rollSize=0
##多少个Event滚动一次
a2.sinks.k2.hdfs.rollCount=0
a2.sinks.k2.hdfs.idleTimeout=0
##最小冗余数
a2.sinks.k2.hdfs.minBlockReplicas=1
##source、channel、sink的关系
a2.sources.r2.channels = c2
a2.sinks.k2.channel = c2
节点二配置文件名也是flume-avro-hdfs.conf,和节点一的大同小异,就agent名、主机名和端口号不同,以下是配置信息:
##agent=a3
a3.sources = r2
a3.channels = c2
a3.sinks = k2
##avro source
a3.sources.r2.type = avro
a3.sources.r2.bind=linux2
a3.sources.r2.port=9092
##interceptors
a3.sources.r2.interceptors=i1
a3.sources.r2.interceptors.i1.type=static
a3.sources.r2.interceptors.i1.key=collector
a3.sources.r2.interceptors.i1.value=linux2
##memory channel
a3.channels.c2.type = memory
a3.channels.c2.capacity = 10000
a3.channels.c2.transactionCapacity = 500
##hdfs sink
a3.sinks.k2.type = hdfs
a3.sinks.k2.hdfs.path=hdfs://linux1:9000/flume/failover/%Y%m%d/%H%M
a3.sinks.k2.hdfs.filePrefix=%Y-%m-%d
a3.sinks.k2.hdfs.writeFormat=TEXT
##此处用header拦截器时间
a3.sinks.k2.hdfs.useLocalTimeStamp =false
##积攒够500Event就flush到hdfs一次
a3.sinks.k2.hdfs.batchSize = 500
##文件类型与压缩,datastream不支持压缩
a3.sinks.k2.hdfs.fileType = DataStream
##60s滚动一次文件
a3.sinks.k2.hdfs.rollInterval =60
##128m滚动一次禁用
a3.sinks.k2.hdfs.rollSize=0
##多少个Event滚动一次
a3.sinks.k2.hdfs.rollCount=0
a3.sinks.k2.hdfs.idleTimeout=0
##最小冗余数
a3.sinks.k2.hdfs.minBlockReplicas=1
##source、channel、sink的关系
a3.sources.r2.channels = c2
a3.sinks.k2.channel = c2
更详细的配置内容可见:https://flume.liyifeng.org/。
然后在每一个节点用flume命令运行flume,这个时候应先运行级联agent的下游节点一和节点二。在节点一上用:
flume-ng agent --name a2 --conf-file flume-avro-hdfs.conf -Dflume.root.logger=INFO,console
在节点二上用:
flume-ng agent --name a3 --conf-file flume-avro-hdfs.conf -Dflume.root.logger=INFO,console。
在节点三上用:flume-ng agent --name a1 --conf-file flume-taildir-avro.conf - Dflume.root.logger=INFO,console
这几个命令把节点运行起来。其中,a1、a2和a3是配置文件里写的agent名,--conf-file后面跟的是配置文件名,-Dflume.root.logger=INFO,console的意思是把运行的日志信息打印在控制台上。
各个agent节点都运行起来之后,因为配置里监控的是节点三hive的日志信息(节点三上之前已经安装好了hive),然后用命令hive -e "show databasess"(这里故意写个错误的命令让他产生错误的日志信息)启动hive,启动完之后可以看见hdfs上采集到文件了,配置文件里配置的是节点一的权重比节点二的权重高,此时是节点一在采集数据,用kill 命令把节点一的flume进程杀掉,然后可以看到节点三提示与节点一的连接报错了,然后与节点二进行连接,数据继续愉快地采集,再启动一下hive命令,hdfs上依然可以产生新的数据文件,大功告成。
以上就是flume的完整学习笔记,帮大家捋通了flume是什么,为什么,有什么,怎么样的问题,还详尽地教大家搭建一个分布式高可用的级联式flume。接下来会讲sqoop,敬请期待。