Flume安装配置
Flume是开源日志系统。Flume是流式日志采集工具。
- 提供从固定目录下采集日志信息到目的地(HDFS,HBase,Kafka)能力。
- 提供实时采集日志信息(taidir)到目的地的能力。
0.前言
Fulme是单独使用的,并不是集群模式,应为有三台虚拟机,每个都用得到,可先安装完一台在进行分发。
1.安装部署
(1.下载
Flume官网地址:flume.apache.org
下载地址:archive.apache.org/dist/flume
//上传,通过MobaXterm软件上传安装包放到已创建目录software
cd /opt/software //切换目录
//解压,压缩包修改成自己下载的
tar -zxvf apache-flume-1.10.1-bin.tar.gz -C /opt/module/
//切换目录
cd /opt/module/
//重命名
[root@hadoop01 module]# mv apache-flume-1.10.1-bin/ flume
(2.修改conf目录下的log4j2.xml配置文件,配置日志文件路径
vi /opt/module/flume/conf/log4j2.xml
#修改LOG_DIR为固定路径
<Property name="LOG_DIR">/opt/module/flume/log</Property>
#Root标签添加AppenderRef内容,引入控制台输出,方便学习查看日志,记得对齐
<Root level="INFO">
<AppenderRef ref="Console" />
</Root>
(3.分发flume
#分发flume
xsync /opt/module/flume
#修改/opt/module/flume/conf/flume-env.sh文件
cd /opt/module/flume/conf
mv flume-env.sh.template flume-env.sh #修改文件名,.template后缀文件名是模版不生效的
vi flume-env.sh
#修改调优参数,开发中Flume堆内存通常设置为4G或更高
export JAVA_OPTS="-Xms512m -Xmx1024m -Dcom.sun.management.jmxremote"
#分发flume-env.sh文件
xsync /opt/module/flume/conf/flume-env.sh
2.Flume数据传输配置
1)Kafka to HDFS
文档查看地址:flume.apache.org/FlumeUserGuide.html
Flume需要将Kafka中topic_db主题的数据传输到HDFS,故其需选用KafkaSource以及HDFSSink,Channel选用FileChannel。
#hadoop03创建Kafka发送数据到HDFS配置文件,粘贴下发文件内容
mkdir -p /opt/module/flume/job
vi /opt/module/flume/job/financial_kafka_to_hdfs_db.conf
#删除
rm -rf /opt/module/flume/job/financial_kafka_to_hdfs_db.conf
a1.sources = r1
a1.channels = c1
a1.sinks = k1
#sources
a1.sources.r1.type = org.apache.flume.source.kafka.KafkaSource
a1.sources.r1.kafka.bootstrap.servers = hadoop01:9092,hadoop02:9092
a1.sources.r1.kafka.topics = topic_db
a1.sources.r1.kafka.consumer.group.id = flume
#拦截器配置
a1.sources.r1.interceptors = i1
a1.sources.r1.interceptors.i1.type = com.mjx.financial.flume.interceptor.TimestampAndTableInterceptor$Builder
#channels
a1.channels.c1.type = file
a1.channels.c1.checkpointDir = /opt/module/flume/checkpoint/behavior1
a1.channels.c1.dataDirs = /opt/module/flume/data/behavior1/
a1.channels.c1.maxFileSize = 2146435071
a1.channels.c1.capacity = 1000000
a1.channels.c1.keep-alive = 6
#sinks
a1.sinks.k1.type = hdfs
a1.sinks.k1.hdfs.path = /origin_data/financial_lease/%{tableName}_inc/%Y-%m-%d
a1.sinks.k1.hdfs.round = false
#以下任意一个参数满足条件都会造成文件的滚动开发环境时间写30min-1h测试环境写10s即可
a1.sinks.k1.hdfs.rollInterval = 10
a1.sinks.k1.hdfs.rollSize = 134217728
a1.sinks.k1.hdfs.rollCount = 0
#添加压缩
a1.sinks.k1.hdfs.fileType = CompressedStream
a1.sinks.k1.hdfs.codeC = gzip
## 拼装
a1.sources.r1.channels = c1
a1.sinks.k1.channel= c1
在hadoop03启动flume配置好的文件,进行数据传输
#启动kafka之前先启动zookeeper,这里是之前写好的封装脚本
bash zk.sh start
#启动kafka,这里是之前写好的封装脚本
kf.sh start
#Flume启动命令,在hadoop03启动传输数据配置文件在hadoop03
/opt/module/flume/bin/flume-ng agent -c conf/ -f /opt/module/flume/job/financial_kafka_to_hdfs_db.conf -n a1
#Flume关闭命令
ps -ef | grep financial_kafka_to_hdfs_db | grep -v grep | awk '{print $2}'| xargs -n1 kill
#启动maxwell封装脚本监控mysql数据
mxw.sh start
#数据生成脚本,生成数据到mysql
financial_mock.sh 1
2)Java编写Flume拦截器
解决Kafka to HDFS发送数据目录问题
在idea里创建名为financial_lease的项目
pom.xml文件添如下配置
<dependencies>
<dependency>
<groupId>org.apache.flume</groupId>
<artifactId>flume-ng-core</artifactId>
<version>1.10.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 指示maven用什么版本的jdk编译 -->
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<!-- maven打包插件 -->
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<!--下面是为了使用 mvn package命令,如果不加则使用mvn assembly-->
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase><!-- 绑定到package生命周期 -->
<goals>
<goal>single</goal><!-- 只运行一次 -->
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Java代码编写Flume拦截器
在com.mjx.financial.flume.interceptor包下创建TimestampAndTableInterceptor类
package com.mjx.financial.flume.interceptor;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import org.apache.flume.Context;
import org.apache.flume.Event;
import org.apache.flume.interceptor.Interceptor;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/*
实现flume拦截器接口
alt+enter回车 实现四个抽象方法
*/
public class TimestampAndTableInterceptor implements Interceptor {
/**
* 初始化方法
*/
@Override
public void initialize() {
}
/**
* 处理单个event
*/
@Override
public Event intercept(Event event) {
// 需要想event的header中添加业务数据的时间戳 和 表格的名称
Map<String, String> headers = event.getHeaders();
// 从body字符串中提取json格式的数据
String log = new String(event.getBody(), StandardCharsets.UTF_8);
try {
JSONObject jsonObject = JSONObject.parseObject(log);
String tableName = jsonObject.getString("table");
// maxwell数据中的时间戳是10位的 正常使用一般是13位的ts 需要*1000
String ts = jsonObject.getString("ts") + "000";
headers.put("tableName",tableName);
headers.put("timestamp",ts);
}catch (JSONException e){
// 如果不是json格式数据 即为脏数据
return null;
}
return event;
}
/**
* 处理多条数据
*/
@Override
public List<Event> intercept(List<Event> events) {
// 批量处理event 同时实现过滤功能
Iterator<Event> iterator = events.iterator();
while (iterator.hasNext()) {
Event next = iterator.next();
if (intercept(next) == null){
iterator.remove();
}
}
return events;
}
/**
* 关闭方法
*/
@Override
public void close() {
}
/*
固定格式,建造者模式
*/
public static class Builder implements Interceptor.Builder{
@Override
public Interceptor build() {
return new TimestampAndTableInterceptor();
}
@Override
public void configure(Context context) {
}
}
}
重新打包
将打好的包放入到hadoop03的/opt/module/flume/lib文件夹下
maxwell修改
注:为了让Maxwell时间戳日期与模拟的业务日期保持一致,对Maxwell源码进行改动,增加了mock_date参数,在/opt/module/maxwell/config.properties文件中将该参数的值修改为业务日期即可。(补充mock.date参数)
vi /opt/module/maxwell/config.properties
# 指定数据按照主键分组进入Kafka不同分区,避免数据倾斜
producer_partition_by=primary_key
# 修改数据时间戳的日期部分,(这里是测试环节加,正常情况下不要加)
mock_date=2023-05-09
改完不会立即生效需要重启maxwell,mxw.sh start
#启动maxwell封装脚本监控mysql数据
mxw.sh start
#在hadoop03启动flume配置好的文件,进行数据传输
/opt/module/flume/bin/flume-ng agent -c conf/ -f /opt/module/flume/job/financial_kafka_to_hdfs_db.conf -n a1
#数据生成脚本,生成数据到mysql
financial_mock.sh 1
#hdfs查看数据
hdfs dfs -text /origin_data/financial_lease/contract_inc/2023-05-09/*
3.Flume启停脚本
//bin方便全局调用
vi /bin/financial_fl.sh
//脚本内容如下
#!/bin/bash
case $1 in
"start"){
echo ---------- 去掉日志后台启动 Kafka to HDFS ------------
ssh hadoop03 "nohup /opt/module/flume/bin/flume-ng agent -c conf/ -f /opt/module/flume/job/financial_kafka_to_hdfs_db.conf -n a1 >/dev/null 2>&1 &"
};;
"stop"){
echo ---------- 停止 Kafka to HDFS ------------
ssh hadoop03 "ps -ef | grep financial_kafka_to_hdfs_db | grep -v grep | awk '{print \$2}'| xargs -n1 kill"
};;
esac
chmod 777 /bin/financial_fl.sh //改权限
financial_fl.sh start //启动
financial_fl.sh stop //停止
4.增量表首日全量同步
执行的时候确保hadoop,zk,kafka,maxwell,flume传输数据是启动的
#在/bin目录创建financial_mysql_to_kafka_inc_init.sh
vi /bin/financial_mysql_to_kafka_inc_init.sh
//脚本内容如下
#!/bin/bash
# 该脚本的作用是初始化所有的增量表,只需执行一次
MAXWELL_HOME=/opt/module/maxwell
import_data() {
$MAXWELL_HOME/bin/maxwell-bootstrap --database financial_lease --table $1 --config $MAXWELL_HOME/config.properties
}
case $1 in
"contract" | "credit" | "credit_facility" | "credit_facility_status" | "reply")
import_data $1
;;
"all")
for table in "contract" "credit" "credit_facility" "credit_facility_status" "reply";
do
#statements
import_data $table
done
;;
esac
#增加执行权限
chmod 777 /bin/financial_mysql_to_kafka_inc_init.sh
#执行
financial_mysql_to_kafka_inc_init.sh all