从两个小例子开始学习flume

前言

之前没接触过flume,也没有什么目标(不是为了解决某个问题而去学习),纯粹是因为我们头让我去学的,所以对flume完全没什么概念,也不知道要拿这东西去干什么。所以学习过程异常痛苦。
经过两三天的接触,我慢慢发现为什么这东西不好理解了:因为flume是一个之前我没接触过的软件概念(注意,是概念,比如 即使你你没接触过HBase,也很容易理解,因为它和数据库属于一个概念体系)。
如果要比喻一下,flume就像一个“带抽水功能的管道”,有两个开口————一进一出,可以装在各种容器之间传导数据。
现在跟着我一起学这个东西

先看几个详细定义

flume介绍与原理
当然如果你英文不错,看官网是最好的选择
其他的我就不多例举了,上面两个觉得不够,还可以继续百度

第一个小例子

作为一个没接触过的软件,先操作一遍,有个概念,下面是个不错的入手案例
Flume环境部署和配置详解及案例大全
跟着这12个例子,做一遍,就对flume有个大致的感性的认识了。
针对这些案例的几个注意点:
1. 没必要一定安装在文中所说的/home/hadoop目录中,就把flume当作一个普通的Linux开源软件一样安装————解压到你放软件的目录里即可,后面执行命令时别照抄他的路径就行了
2. 稍解释一下要执行的这几个命令
首先就拿第一个需要执行的命令来稍解释一下

root@m1:/home/hadoop# /home/hadoop/flume-1.5.0-bin/bin/flume-ng agent -c . -f /home/hadoop/flume-1.5.0-bin/conf/avro.conf -n a1 -Dflume.root.logger=INFO,console

flume-ng:flume的可执行脚本
avro.conf: 一开始我说了,flume就像一个管道,既然是管道,那么就有:一进一出两个端口,还有这个管道有多粗,多长等等配置信息,这些信息全在这个配置文件里写着
a1: 在这根管道的名字(这个名字在配置文件里也有,要对应上)

root@m1:/home/hadoop# echo "hello world" > /home/hadoop/flume-1.5.0-bin/log.00

这些例子都是在演示:flume在各种容器之间安装管道,并成功把一端A的数据 传到另一段B。
这第二个命令的意思就是:让你创建一个日志文件,作为A,把这里的数据面的数据传出去。

root@m1:/home/hadoop# /home/hadoop/flume-1.5.0-bin/bin/flume-ng avro-client -c . -H m1 -p 4141 -F /home/hadoop/flume-1.5.0-bin/log.00

这句话我也不过多解释,就提醒一点:
注意里面的 “m1”, 这不是固定写法,仔细看看就知道这是当前计算机名,要改成自己的。

下面的例子套路都差不多,就是在“案例6”你可能会在执行

root@m1:/home/hadoop# echo "hello idoall flume -> hadoop testing one" | nc localhost 5140

报错:

-bash: nc: command not found

这是因为你的机器上没有安装nc这个东西,这需要用yum安装一下就好了

yum install -y nc

还有Hadoop那个例子,得先安装部署Hadoop,这个就不说了,否则扯得就太远了,我的意见是:虽然有12个例子,现在我们也没必要全做一遍,现在只是让自己先有个概念,而且这些例子套路都一样。

成功的完成了几个案例后,我们就站在这个基础上进一步深究一下 这些例子里很关键的,也是让人比较晕的配置文件(以案例1的avro.conf为例):

a1.sources = r1
a1.sinks = k1
a1.channels = c1

# Describe/configure the source
a1.sources.r1.type = avro
a1.sources.r1.channels = c1
a1.sources.r1.bind = 0.0.0.0
a1.sources.r1.port = 4141

# Describe the sink
a1.sinks.k1.type = logger

# Use a channel which buffers events in memory
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100

# Bind the source and sink to the channel
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1

在讲这个之前,我先放上一张几乎每个讲述flume原理的文章都会贴的一张图
1
之所以这个图很重要,因为它描述的就是flume最直观的工作原理:
Agent:flume的最小运作单元
这个图描述了:数据从Web Server进入flume的Agent,然后传输到HDFS的过程(这里只是举了个例子,这一进一出两个口未必一定是Web Server和HDFS)
然后是关键的Agent内部原理(之所以要画出内部的这几个关键部件,因为它直接关系着 配置文件):我不多说,大家从名字上也很容易和上面的配置文件里的信息对应上

稍解释一下具体配置意思:
a1.sources = r1
声明数据入口名字为r1(知道了Source在这里的大致意思,以后就直接称为source,而不翻译成“数据入口”,因为这种不太准确的翻译可能容易让人误解)
a1.sinks = k1
声明数据出口为k1(同上)
a1.channels = c1
声明数据管道名字为c1(同上)
a1.sources.r1.type = avro
sources是avro类型的
a1.sources.r1.channels = c1
sources关联的channels是c1(前面定义了)
a1.sources.r1.bind = 0.0.0.0
sources绑定的ip
a1.sources.r1.port = 4141
sources绑定的端口
a1.sinks.k1.type = logger
sinks的类型是logger(把日志写到日志文件)
a1.channels.c1.type = memory
channels的数据缓存在内存中
a1.sinks.k1.channel = c1
k1关联的channel是c1

第二个例子

第一个例子是教你怎么配置一下,让flume开始工作,但作为一个程序员,我更关心的是:这东西怎么和代码结合使用,为什么要和代码结合使用?
从第一个例子我们知道,flume可以满足在各种“容器”之间搭建管道,只需要配置不同souce和sink类型就行了,但是总会有一些比较特殊的需求是满足不了的,比如,我要把日志抽到数据库里,就没有mysql相关的sink。当然,flume肯定是考虑到这种情况了,它给我们暴露了一些“接口”允许我们自定义sink或source:在自定义source里我们需要做的是:想办法获取数据,然后传给channel在自定义sink里需要做的是:把channel里的数据 想办法输出到你想存的地方。下面以连接mysql的自定义sink为例子作为说明:
Flume 抓取日志文件存入MySQL中
下面是几个你可能在按照这篇博客操作的过程中遇到的问题:
1.启动后报错:找不到你写的类
问题还在关键的配置文件上,下面我把配置文贴上,并把可能需要自己改动的加粗显示(因为会影响文章格式,注释被我去掉了):
agent1.sources = source1
agent1.sinks = mysqlSink
agent1.channels = channel1
agent1.sources.source1.type = exec
agent1.sources.source1.command = tail -F /home/yong/Work/flum-1.6/tail_log_exec
agent1.sources.source1.channels = channel1
agent1.sinks.mysqlSink.type = org.flume.mysql.sink.MysqlSink
agent1.sinks.mysqlSink.hostname=localhost
agent1.sinks.mysqlSink.port=3306
agent1.sinks.mysqlSink.databaseName=sinktest
agent1.sinks.mysqlSink.tableName=mysqltest
agent1.sinks.mysqlSink.user=root
agent1.sinks.mysqlSink.password=root
agent1.sinks.mysqlSink.channel = channel1
agent1.channels.channel1.type = memory
agent1.channels.channel1.capacity = 1000
agent1.channels.channel1.transactionCapactiy = 100

尤其是agent1.sinks.mysqlSink.type。首先这里不是什么固定写法(当你把jar包扔到flume的lib目录里还不够,不指定类的全路径,flume是不知道你写的sink是哪个的)。其次 你的包名未必和他的一样。

2.怎么打jar包
一般来说我们都是要用IDE的,比如我就用的eclipse,然后建了个Maven项目,把它的那个类拷到项目里,然后用Maven打包。当然,你也可以不用Maven打包,直接eclipse右键——export也可以。

这个时候你会不会有很多疑问:我是把依赖包一起打进去呢,还是只打我们自己写的那个类呢?而且那篇文章中说“同时需要上传MySQL的驱动jar包” 是什么意思,上传到哪?mysql驱动包不也是个依赖包吗,难道这个特殊?
我先说结论:一般只打自己写的代码,如果出现报错,找不到第三方的类,则把相关jar包也同你打的那个jar包一样扔到flume的lib目录里。
然后说为什么:就以上面这个例子来说
你只需要打一个自己写的jar包就行了(即不需要把依赖包一起打进去),然后按照文章所说的 把mysql驱动包也扔到lib目录里。程序就能正常运行
然后你可能想了:
代码中引用的

import org.apache.flume.*;  
import org.apache.flume.conf.Configurable;  
import org.apache.flume.sink.AbstractSink; 

我们知道flume里肯定有,这个我们不添加进去,没关系,可以理解。但是下面这些依赖

import com.google.common.base.Preconditions;  
import com.google.common.base.Throwables;
import com.google.common.collect.Lists;
import org.slf4j.Logger;  
import org.slf4j.LoggerFactory;

总不会flume也“自带”的吧?…恭喜你答对了!这些还真是flume“自带”的,不信打开你的eclipse里的pom文件的“依赖层级树”,你就会发现google的工具包guava和slf4j就是flume的依赖之一。
然后你可能又会问了:那mysql驱动包怎么解释,为什么要单独扔到lib目录里?(事实上可以试一下,如果不放mysql驱动,是会报错的)
再做个实验:把依赖包(包括mysql驱动)一起打包到jar包里,这次我们不单独在lib里放驱动包,执行一下。你会发现:可以正常执行。
这下就就可以解释这所有的现象了:
google和slf4j等依赖包之所以不用一起打进包里,是因为flume依赖的有,而像mysql驱动这样的 flume没有依赖的包 就需要单独添加了。(要么打到jar包里,要么单独扔到lib目录里)。由于把依赖包全打进jar包太大了(我试了一下有十多兆,不打进去的jar包只有7k),所以我建议把并不多的第三方依赖包直接仍lib目录里(除非你的程序很复杂,有大量的依赖包)

3.打包的时候需要指定main方法所在类吗
结论:这个程序没有main方法入口,所以不需要指定main方法入口
验证:自己可以做做实验,用Maven打包,不指定main方法所在类,看看会不会影响运行

4.引申:如果你写过Hadoop的mapreduce,或Hbase的协处理器,应该会想到:他们在打jar包这个问题上是不是“同理”的


以上只是初次接触flume的入门总结,在之后的学习使用中,如果有新的经验,我会继续完善这篇博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值