flume介绍与配置
- 1.介绍
- 2.数据来源
- 3.实战
- 3.1 HW
- 3.1.1本地连本地
- 3.1.2设置允许外部链接到本地
- 3.2 Source
- 3.2.1 Spooldir
- 3.3 Sink
- 3.3.1 HDFS
- 3.3.2 Hive
1.介绍
Flume(水槽):采集工具,将大数据分散的数据源(数据库,日志)统一采集到一个地方(hdfs),
官网:http://flume.apache.org/
Flume是一种分布式、可靠和可用的服务,可以高效地收集、聚合和移动大量的日志数据。它具有基于流数据流的简单灵活的体系结构。它具有鲁棒性和容错性,具有可调的可靠性机制和多种故障转移和恢复机制。它使用了一个简单的、可扩展的数据模型,允许在线分析应用程序
结构:
Source:来源(flume)
Channel:渠道(flume)
Sink:目的地(flume)
webServer:数据源(产生数据的地方,tomcat)
Hdfs:它是把数据放到了hdfs中;
2.数据来源
下载地址(阿里云):
3.实战
3.1 HW
3.1.1本地连本地
首先确认每个(4个)虚拟机都安装了此命令
yum -y install telnet
系统要求:
1.Java运行时环境-Java1.8或更高版本
2.内存-为源、通道或接收器使用的配置提供足够的内存
3.磁盘空间.通道或接收器使用的配置的足够磁盘空间
目录权限-代理使用的目录的读/写权限
首先把flume上传到node3;
解压
tar -xzvf apache-flume-1.8.0-bin.tar.gz
修改名字
mv apache-flume-1.8.0-bin/ apache-flume/
删除文档
rm -rf docs/
新建一个配置文件,名字随便起(conf/flume_hw.properties)
加入内容
# flume配置的例子
# Name the components on this agent
# source:起一个别名
# properties文件它是java的配置文件,=左边就是键,=右边是值;键的开头都是以a1(就是flume的名字--agent的名字就是a1);a1随便起
a1.sources = r1
# sink:起一个别名
a1.sinks = k1
# channels;:起一个别名
a1.channels = c1
# Describe/configure the source
# a1(agent的名字).sources(来源).r1(来源的名字);配置多个来源
# type:不能随便写(文档上说明)
a1.sources.r1.type = netcat
# bind:netcat的一个属性(绑定)
a1.sources.r1.bind = localhost
# port:netcat的一个属性;(端口)
a1.sources.r1.port = 44444
# Describe the sink
# 描述一个sink: logger日志(打印到控制台上)
a1.sinks.k1.type = logger
# Use a channel which buffers events in memory
# 描述一下channel:内存
a1.channels.c1.type = memory
# capacity:容量
a1.channels.c1.capacity = 1000
# transactionCapacity:事务的容量
a1.channels.c1.transactionCapacity = 100
# Bind the source and sink to the channel
# 绑定;source和channel绑定
a1.sources.r1.channels = c1
# sink和channel绑定
a1.sinks.k1.channel = c1
然后将配置文件:(conf/flume-env.sh.template复制为conf/flume-env.sh)
更改里面的JAVA_MONE
启动flume服务器端
bin/flume-ng agent --conf conf --conf-file conf/flume_hw.properties --name a1 -Dflume.root.logger=INFO,console
再打开node3窗口
telnet localhost 44444
3.1.2设置允许外部链接到本地
修改配置文件(conf/flume_hw.properties)
# flume配置的例子
# Name the components on this agent
# source:起一个别名
# properties文件它是java的配置文件,=左边就是键,=右边是值;键的开头都是以a1(就是flume的名字--agent的名字就是a1);a1随便起
a1.sources = r1
# sink:起一个别名
a1.sinks = k1
# channels;:起一个别名
a1.channels = c1
# Describe/configure the source
# a1(agent的名字).sources(来源).r1(来源的名字);配置多个来源
# type:不能随便写(文档上说明)
a1.sources.r1.type = netcat
# bind:netcat的一个属性(绑定),允许任何人访问
a1.sources.r1.bind = 0.0.0.0
# port:netcat的一个属性;(端口)
a1.sources.r1.port = 44444
# Describe the sink
# 描述一个sink: logger日志(打印到控制台上)
a1.sinks.k1.type = logger
# Use a channel which buffers events in memory
# 描述一下channel:内存
a1.channels.c1.type = memory
# capacity:容量
a1.channels.c1.capacity = 1000
# transactionCapacity:事务的容量
a1.channels.c1.transactionCapacity = 100
# Bind the source and sink to the channel
# 绑定;source和channel绑定
a1.sources.r1.channels = c1
# sink和channel绑定
a1.sinks.k1.channel = c1
重启服务器端
nohup bin/flume-ng agent --conf conf --conf-file conf/flume_hw.properties --name a1 -Dflume.root.logger=INFO,console &
3.2 Source
3.2.1 Spooldir
监控某个目录的变化;只要有新文件就会被flume捕获
指定的目录必须存在
指定的目录下面所有的文件都会被flume获取,已经获取过的,会将源文件增加一个后缀名:(.COMPLETED–完成);(文件的扩展名properties)
创建配置文件(conf/flume_source.properties)
# flume配置的例子
# Name the components on this agent
# source:起一个别名
# properties文件它是java的配置文件,=左边就是键,=右边是值;键的开头都是以a1(就是flume的名字--agent的名字就是a1);a1随便起
a1.sources = r1
# sink:起一个别名
a1.sinks = k1
# channels;:起一个别名
a1.channels = c1
# Describe/configure the source
# spooldir:监控硬盘上指定的某个目录,如果文件发生变化,会被flume捕获;
a1.sources.r1.type = spooldir
# 要监控的目录,此目录必须存在
a1.sources.r1.spoolDir =/root/flume/
# 已经完成的文件,会加上一个后缀
a1.sources.r1.fileSuffix =.ok
# 已经完成的文件,会立即删除,默认值是never;(永不删除)
# a1.sources.r1.deletePolicy =immediate
# 是否添加存储绝对路径文件名的标题
a1.sources.r1.fileHeader =true
# 只处理此目录下面的txt文件;
a1.sources.r1.includePattern =^[\\w]+\\.txt$
# Describe the sink
# 描述一个sink: logger日志(打印到控制台上)
a1.sinks.k1.type = logger
# Use a channel which buffers events in memory
# 描述一下channel:内存
a1.channels.c1.type = memory
# capacity:容量
a1.channels.c1.capacity = 1000000
# transactionCapacity:事务的容量
a1.channels.c1.transactionCapacity = 1000000
# Bind the source and sink to the channel
# 绑定;source和channel绑定
a1.sources.r1.channels = c1
# sink和channel绑定
a1.sinks.k1.channel = c1
启动flume
nohup bin/flume-ng agent --conf conf --conf-file conf/flume_source.properties --name a1 -Dflume.root.logger=INFO,console &
看日志
tail -f nohup.out
如果配置文件发生了变化,需要重新启动flume;
停止
Kill -9 进程号
再启动
3.3 Sink
3.3.1 HDFS
启动hadoop
告诉flume,hadoop装哪了
Linux的环境变量:(vim /etc/profile);新增加内容;(系统的环境变量)
vim ~/.bash_profile(用户环境变量)
新建配置文件conf/flume_sink.properties
# flume配置的例子
# Name the components on this agent
# source:起一个别名
# properties文件它是java的配置文件,=左边就是键,=右边是值;键的开头都是以a1(就是flume的名字--agent的名字就是a1);a1随便起
a1.sources = r1
# sink:起一个别名
a1.sinks = k1
# channels;:起一个别名
a1.channels = c1
# Describe/configure the source
# spooldir:监控硬盘上指定的某个目录,如果文件发生变化,会被flume捕获;
a1.sources.r1.type = spooldir
# 要监控的目录,此目录必须存在
a1.sources.r1.spoolDir =/root/flume/
# 已经完成的文件,会加上一个后缀
a1.sources.r1.fileSuffix =.ok
# 已经完成的文件,会立即删除,默认值是never;(永不删除)
# a1.sources.r1.deletePolicy =immediate
# 是否添加存储绝对路径文件名的标题
a1.sources.r1.fileHeader =true
# 只处理此目录下面的txt文件;
a1.sources.r1.includePattern =^[\\w]+\\.txt$
# Describe the sink
# 描述一个sink: logger日志(打印到控制台上)
a1.sinks.k1.type = hdfs
# hdfs的路径;配置hdfs一定要是大哥的路径;(必须是active)
a1.sinks.k1.hdfs.path =hdfs://node1:8020/flume/%Y-%m-%d/
# 文件的前缀
a1.sinks.k1.hdfs.filePrefix =event
# 文件的后缀
a1.sinks.k1.hdfs.fileSuffix =.txt
# hdfs.inUsePrefix临时文件的前缀,hdfs.inUseSuffix临时文件的后缀
# hdfs.codeC 文件压缩
# 输出原来的文件内容,不要压缩
a1.sinks.k1.hdfs.fileType=DataStream
# 设置文件的格式为textFile
a1.sinks.k1.hdfs.writeFormat=Text
# 如果路径里面有时间,必须要加上hdfs.useLocalTimeStamp=true
a1.sinks.k1.hdfs.useLocalTimeStamp=true
# 时间舍去法;%y,%m,%d(机器的本地时间),集群中所有时间是一样的;(如果集中所有的服务器时间不一样,允许时间有误差;统一是当前时间-误差)
# 当前的时间允许的误差是20s;
a1.sinks.k1.hdfs.round = true
# 每隔多长时间
a1.sinks.k1.hdfs.roundValue = 20
# 时间单位
a1.sinks.k1.hdfs.roundUnit = second
# roll:滚动;时间30s,如果flume发现有新文件,上传到hdfs上,等待30秒
# 避免有大文件,拆分成多个小文件;
# 在等待的30秒以内,如果此文件发生了修改(也会进行拆分)
a1.sinks.k1.hdfs.rollInterval=30
# 滚动,新增加的文件大小(等待时间期间);0:表示不生效
a1.sinks.k1.hdfs.rollSize=1024
# 滚动多少行(新增加多少行)(等待时间期间),每隔10行会在hdfs上生成一个新文件;0:表示不生效
a1.sinks.k1.hdfs.rollCount=0
# Use a channel which buffers events in memory
# 描述一下channel:内存
a1.channels.c1.type = memory
# capacity:容量
a1.channels.c1.capacity = 1000000
# transactionCapacity:事务的容量
a1.channels.c1.transactionCapacity = 1000000
# Bind the source and sink to the channel
# 绑定;source和channel绑定
a1.sources.r1.channels = c1
# sink和channel绑定
a1.sinks.k1.channel = c1
启动flume
bin/flume-ng agent --conf conf --conf-file conf/flume_sink.properties --name a1 -Dflume.root.logger=INFO,console
看日志
tail -f nohup.out
hdfs文件拆分;(按照大小拆分,每10行一个文件)
3.3.2 Hive
启动hadoop
启动hive
在hive中创建一张表:
create table flume_table
(
id int,
msg string,
-- 年月日,时分秒
createtime string
)
-- 分区;只有年月日
partitioned by (ctime string)
-- 集群,id 放到了5桶里面
clustered by (id) into 5 buckets
-- 存储的格式为orc
stored as orc
tblproperties ("transactional"="true");
准备好一个数据文件(data.txt注意有格式);
1,aa,2019-02-01,
2,bb,2019-02-01,
3,cc,2019-02-03,
4,dd,2019-02-02,
5,ee,2019-02-03,
告诉flume,hive装哪了
需要把\hcatalog\share\hcatalog\hive-hcatalog-streaming-3.1.1.jar复制到flume\jar包下面
必须得是一个事务表,否则会报如下错
新建文件conf/flume_sink.properties
# flume配置的例子
# Name the components on this agent
# source:起一个别名
# properties文件它是java的配置文件,=左边就是键,=右边是值;键的开头都是以a1(就是flume的名字--agent的名字就是a1);a1随便起
a1.sources = r1
# sink:起一个别名
a1.sinks = k1
# channels;:起一个别名
a1.channels = c1
# Describe/configure the source
# spooldir:监控硬盘上指定的某个目录,如果文件发生变化,会被flume捕获;
a1.sources.r1.type = spooldir
# 要监控的目录,此目录必须存在
a1.sources.r1.spoolDir =/root/flume/
# 已经完成的文件,会加上一个后缀
a1.sources.r1.fileSuffix =.ok
# 已经完成的文件,会立即删除,默认值是never;(永不删除)
# a1.sources.r1.deletePolicy =immediate
# 是否添加存储绝对路径文件名的标题
a1.sources.r1.fileHeader =true
# 只处理此目录下面的txt文件;
a1.sources.r1.includePattern =^[\\w]+\\.txt$
# Describe the sink
# 采集的是日志(txt);在hive中创建一张表,load data把文件拷贝到指定目录下面,
# 相当于把日志文件中的记录插入到了hive表
# hive
a1.sinks.k1.type =hive
# hive的服务器
a1.sinks.k1.hive.metastore =thrift://node4:9083
# hive的数据库
a1.sinks.k1.hive.database =mydata
# hive的表名,(这张表一定得存在,需要在hive中创建表)
a1.sinks.k1.hive.table =flume_table
# 配置分区,多个分区使用逗号隔开;time=%Y-%m-%d,a=b,c=d;一个分区的时候名字可以省;分区不是必须配置的
a1.sinks.k1.hive.partition=time-%Y-%m-%d
# useLocalTimeStamp
a1.sinks.k1.useLocalTimeStamp =true
# 采集的数据是文本文件(如果是json文件就填写json)
a1.sinks.k1.serializer =DELIMITED
# 列与列之间的分隔符
a1.sinks.k1.serializer.delimiter=,
# 采集的源文件里面有好几列,到底要使用哪几列的数据
a1.sinks.k1.serializer.fieldnames=id,msg,createtime
# Use a channel which buffers events in memory
# 描述一下channel:内存
a1.channels.c1.type = memory
# capacity:容量
a1.channels.c1.capacity = 1000000
# transactionCapacity:事务的容量
a1.channels.c1.transactionCapacity = 1000000
# Bind the source and sink to the channel
# 绑定;source和channel绑定
a1.sources.r1.channels = c1
# sink和channel绑定
a1.sinks.k1.channel = c1
启动flume
bin/flume-ng agent --conf conf --conf-file conf/flume_sink.properties --name a1 -Dflume.root.logger=INFO,console
建议flume+hive这么玩
首先创建一张hive表,这张表得是textFile;得有分区;
flume监控某个日志文件目录
如果文件有变化,flume会把文件拷贝到hdfs上(考虑一下是否要滚动);它是一个临时的目录
Load data input :把上传到hdfs中的文件直接复制到textFile表中的指定分区就可以
解释:变化:
web开发组的服务器每天生成一个日志文件;(00点)
01点的时候会有一个定时脚本(crond)把日志的目录指定是当天的文件剪切到flume监控的目录;(目录有变化),flume马上就可以监控到
flume会把此日志文件(txt,log)上传到hdfs中指定的目录;(flume的hdfs sink中可以配置)(上传的时间:给他两个小时)
定时脚本(crond);每天4点执行;执行我们的load data input ‘’ partition(分区信息);(bin/hive -f ;-e)
执行我们的统计函数(需求);比如说:每天用户的注册数;注册用户的前10位;(奖)