0 修改压缩编码格式
(1)业务数据首日同步脚本
#修改之前编写的同步脚本文件压缩编码
vim /home/hzy/bin/mysql_to_hdfs_init.sh
#修改如下内容
import_data(){
$sqoop import \
--connect jdbc:mysql://hadoop102:3306/$APP \
--username root \
--password 123456 \
--target-dir /origin_data/$APP/db/$1/$do_date \
--delete-target-dir \
--query "$2 where \$CONDITIONS" \
--num-mappers 1 \
--fields-terminated-by '\t' \
--compress \
--compression-codec org.apache.hadoop.io.compress.GzipCodec \
--null-string '\\N' \
--null-non-string '\\N'
# 删除下面一行内容
hadoop jar /opt/module/hadoop-3.1.3/share/hadoop/common/hadoop-lzo-0.4.20.jar com.hadoop.compression.lzo.DistributedLzoIndexer /origin_data/$APP/db/$1/$do_date
}
##修改之前编写的同步脚本文件压缩编码
vim /home/hzy/bin/mysql_to_hdfs.sh
#修改如下内容
import_data(){
$sqoop import \
--connect jdbc:mysql://hadoop102:3306/$APP \
--username root \
--password 123456 \
--target-dir /origin_data/$APP/db/$1/$do_date \
--delete-target-dir \
--query "$2 and \$CONDITIONS" \
--num-mappers 1 \
--fields-terminated-by '\t' \
--compress \
--compression-codec org.apache.hadoop.io.compress.GzipCodec \
--null-string '\\N' \
--null-non-string '\\N'
# 删除下面一行内容
hadoop jar /opt/module/hadoop-3.1.3/share/hadoop/common/hadoop-lzo-0.4.20.jar com.hadoop.compression.lzo.DistributedLzoIndexer /origin_data/$APP/db/$1/$do_date
}
(2)修改消费(第二层)Flume的配置文件
进入hadoop101的/opt/module/flume-1.9.0/jobs/gmall目录
vim kafka-flume-hdfs.conf
#修改如下内容
## 控制输出文件是原生文件。
a1.sinks.k1.hdfs.fileType = CompressedStream
a1.sinks.k1.hdfs.codeC = gzip
1 Hive环境搭建
此处已经默认采集项目环境搭建完成(hadoop、Zookeeper、kafka、flume、mysql、hive、hbase),如没有搭建完成,参考1,参考2。
(1)Hive引擎简介
Hive引擎包括:默认MR、tez、spark
tez:MR的改进版,将MR静态的计算方法改成DAG有向图的计算,MR每进行一次MR都会落一次盘,然后再执行一次MR,DAG有向图则可以进行map、map、map、reduce、reduce…方式的计算,tez可以看做是弱化版的spark。
Hive on Spark:Hive既作为存储元数据又负责SQL的解析优化,语法是HQL语法,执行引擎变成了Spark,Spark负责采用RDD执行。
Spark on Hive : Hive只作为存储元数据,Spark负责SQL解析优化,语法是Spark SQL语法,Spark负责采用RDD执行。
(2)Hive on Spark配置
兼容性说明
注意:官网下载的Hive3.1.2和Spark3.0.0默认是不兼容的。因为Hive3.1.2支持的Spark版本是2.4.5,所以需要我们重新编译Hive3.1.2版本。
编译步骤:官网下载Hive3.1.2源码,解压到本地,修改pom文件中引用的Spark版本为3.0.0,这时如果hive其他的代码报错,哪里报错改哪里。
最后如果编译通过,直接打包获取jar包。如果报错,根据提示,修改相关方法,直到不报错,打包获取jar包。
部署hive
查看spark的配置文件,如上图显示为做过兼容的版本,从官网上下载的为2.4.5 非3.0.0,在执行的时候就会报错。
# 让hive元数据库支持中文注释
alter table metastore.COLUMNS_V2 modify column COMMENT varchar(256) character set utf8mb4 COLLATE utf8mb4_unicode_ci;
alter table metastore.TABLE_PARAMS modify column PARAM_VALUE varchar(4000) character set utf8mb4 COLLATE utf8mb4_unicode_ci;
alter table metastore.PARTITION_PARAMS modify column PARAM_VALUE varchar(4000) character set utf8mb4 COLLATE utf8mb4_unicode_ci;
alter table metastore.PARTITION_KEYS modify column PKEY_COMMENT varchar(4000) character set utf8mb4 COLLATE utf8mb4_unicode_ci;
alter table metastore.PARTITION_KEY_VALS modify column PART_KEY_VAL varchar(256) character set utf8mb4 COLLATE utf8mb4_unicode_ci;
alter table metastore.INDEX_PARAMS modify column PARAM_VALUE varchar(4000) character set utf8mb4 COLLATE utf8mb4_unicode_ci;
# 修改元数据的
# 在$HIVE_HOME/conf目录下修改hive-site.xml文件
#修改如下内容
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://hadoop101:3306/metastore?useSSL=false&useUnicode=true&characterEncoding=UTF-8</value>
</property>
#测试修改是否成功
hive
create database test comment '测试';
use test;
create table student(id int comment '测试',name string);
desc student;
# 能够插入数据,说明hive运行正常
insert into student values(1001,'zhangsan');
select * from student;
在Hive所在节点部署Spark
如果之前已经部署了Spark,则该步骤可以跳过,但要检查SPARK_HOME的环境变量配置是否正确。
tar -zxf spark-3.0.0-bin-hadoop3.2.tgz -C /opt/module/
mv spark-3.0.0-bin-hadoop3.2/ spark
sudo vim /etc/profile.d/my_env.sh
# SPARK_HOME
export SPARK_HOME=/opt/module/spark
export PATH=$PATH:$SPARK_HOME/bin:$SPARK_HOME/sbin
source /etc/profile.d/my_env.sh
# 测试
spark tab 查看是否可以看到spark相关命令
# 在hive中创建spark配置文件
cd /opt/module/hive/conf/
# 新建文件
vim spark-defaults.conf
# 添加如下内容(在执行任务时,会根据如下参数执行)
spark.master=yarn
spark.eventLog.enabled=true
spark.eventLog.dir=hdfs://hadoop101:8020/spark/history
# 堆内内存
spark.executor.memory=4g
spark.driver.memory=4g
# 堆外内存,用于存储
spark.memory.offHeap.enable=true
spark.memory.offHeap.size=2g
# 解决spark运行时找不到本地库的问题
spark.driver.extraLibraryPath=/opt/module/hadoop-3.1.3/lib/native
spark.exector.extraLibraryPath=/opt/module/hadoop-3.1.3/lib/native
# 在HDFS创建如下路径,用于存储历史日志
hadoop fs -mkdir /spark/history
向HDFS上传Spark纯净版jar包
说明1:由于Spark3.0.0非纯净版默认支持的是hive2.3.7版本,直接使用会和安装的Hive3.1.2出现兼容性问题。所以采用Spark纯净版jar包,不包含hadoop和hive相关依赖,避免冲突。
说明2:Hive任务最终由Spark来执行,Spark任务资源分配由Yarn来调度,该任务有可能被分配到集群的任一个节点。所以需要将Spark的依赖上传到HDFS集群路径,这样集群中任何一个节点都能获取到。
# 上传并解压spark-3.0.0-bin-without-hadoop.tgz
tar -zxf /opt/software/spark-3.0.0-bin-without-hadoop.tgz
# 上传Spark纯净版jar包到HDFS
cd spark-3.0.0-bin-without-hadoop
hadoop fs -put jars /spark/
# 在hdfs查看,在/spark/jars文件中共有146个文件
vim /opt/module/hive/conf/hive-site.xml
# 添加一些内容
<!--Spark依赖位置(注意:端口号8020必须和namenode的端口号一致)-->
<property>
<name>spark.yarn.jars</name>
<value>hdfs://hadoop101:8020/spark/jars/*</value>
</property>
<!--Hive执行引擎-->
<property>
<name>hive.execution.engine</name>
<value>spark</value>
</property>
<!--Hive和Spark连接超时时间-->
<property>
<name>hive.spark.client.connect.timeout</name>
<value>10000ms</value>
</property>
Hive On Spark配置完成
# 测试hive引擎
hive
use test;
show tables;
select * from student;
insert into student values(1002,'lisi');
# 测试snappy压缩
create table stu_orc stored as orc tblproperties("orc.compress"="SNAPPY") as select * from student;
select * from stu_orc cluster by id;
其他配置
增加hiveserver2默认堆内存
# 增加hiveserver2 的默认堆内存
# 查看hiveserver2 的默认内存
# -Djava.library.path=/opt/module/hadoop-3.1.3/lib/native -Xmx256m,最大256M
cd /opt/module/hive/conf/
mv hive-env.sh.template hive-env.sh
vim hive-env.sh
修改如下配置
# The heap size of the jvm stared by hive shell script can be controlled via:
#
export HADOOP_HEAPSIZE=2048
#
# Larger heap size may be required when running queries over large number of files or partitions.
# By default hive shell scripts use a heap size of 256 (MB). Larger heap size would also be
# appropriate for hive server.
2 Yarn配置
增加ApplicationMaster资源比例
容量调度器对每个资源队列中同时运行的Application Master占用的资源进行了限制,该限制通过yarn.scheduler.capacity.maximum-am-resource-percent参数实现,其默认值是0.1,表示每个资源队列上Application Master最多可使用的资源为该队列总资源的10%,目的是防止大部分资源都被Application Master占用,而导致Map/Reduce Task无法执行。
生产环境该参数可使用默认值。但学习环境,集群资源总数很少,如果只分配10%的资源给Application aster,则可能出现,同一时刻只能运行一个Job的情况,因为一个Application Master使用的资源就可能已经达到10%的上限了。故此处可将该值适当调大。
如果没有这个限制,集群的AM想用多少资源就用多少,这时假设出现高并发,向集群提交很多很多的任务,会瞬间启动非常多的AM,而这些AM会将集群的资源耗尽,结果就是没有Container给AM打工,整个集群就卡住了,导致集群的资源分配出现严重的失衡。
在生产环境下很合适,因为一个AM可能会有1000个Container给这个AM打工,10%足够了。但是在自己配置的集群中,一个AM可能就有一个或两个Container打工仔,可以将其改为0.3或者0.5。对于12G内存(一台4G,3台)来说,0.3就意味着会有3.6G的内存去运行AM,同时可以运行2个任务。
yarn结构回忆:yarn中有RM和NM,但是在运行APP时,负责管理job的角色叫做AM,AM不负责job的计算,只负责管理job的运行,真正计算的功能是Container负责,启动什么样的Master是通过计算架构的不同导致的。如MR启动的AM叫做MapReduceAppMaster,启动的进程(实际干活的)叫做MapTask和ReduceTask。
Spark的打工仔是Exector,一个它的AM是Driver,在生产环境下,一个Driver可以有4-10个Exector。
cd /opt/module/hadoop-3.1.3/etc/hadoop/
vim capacity-scheduler.xml
# 修改如下内容
<property>
<name>yarn.scheduler.capacity.maximum-am-resource-percent</name>
<value>0.3</value>
</property
# 分发capacity-scheduler.xml配置文件
xsync capacity-scheduler.xml
# 关闭正在运行的任务,重新启动yarn集群
sbin/stop-yarn.sh
sbin/start-yarn.sh
3 数仓开发环境
(1)启动hiveserver2
数仓开发工具可选用DBeaver或者DataGrip。两者都需要用到JDBC协议连接到Hive,故需要启动HiveServer2。
# 启动hiveserver2
hiveserver2
# 验证是否启动成功--10000端口是否被占用
netstat -nltp | grep 10000
(2)配置DataGrip连接
创建连接
配置连接属性
所有属性配置,和Hive的beeline客户端配置一致即可。初次使用,配置过程会提示缺少JDBC驱动,按照提示下载即可。
配置完成后,点击测试连接,成功后,点击ok。
注:新版IDEA中需要将上图的username改为user
(3)测试使用
创建数据库gmall,并观察是否创建成功。
创建数据库
修改连接,指明连接数据库
查看数据库
选择当前数据库为gmall
4 数据准备
一般企业在搭建数仓时,业务系统中会存在一定的历史数据,此处为模拟真实场景,需准备若干历史数据。假定数仓上线的日期为2020-06-14,具体说明如下。
(1)用户行为数据
用户行为日志,一般是没有历史数据的,故日志只需要准备2020-06-14一天的数据。具体操作如下:
- 启动日志采集通道,包括Flume、Kafak等
- 修改两个日志服务器(hadoop102、hadoop103)中的/opt/module/applog/application.yml配置文件,将mock.date参数改为2020-06-14。
- 执行日志生成脚本lg.sh。
- 观察HDFS是否出现相应文件。
# 确认kafka已经打开
kafka.sh status
f1.sh start
f2.sh start
jpsall
# 假设之前没有用户行为数据
log.sh 2020-06-14
# 查看集群是否有数据
# 文件目录origin_data/gmall/log/topic_log/日期里面会有.gz文件
(2)业务数据
# 业务数据生成
mysql -uroot -p123456
show databases;
drop database gmall;
新建maven项目,连接数据库
注:如果出现连接失败,更新下数据库连接驱动。
创建数据库
# 在idea执行,创建支持utf-8的数据库
create database gmall character set utf8mb4 collate utf8mb4_general_ci;
# 在服务器执行
use gmall
# 执行脚本文件--建立表格,插入数据
source /opt/module/db_log/gmall.sql
模拟插入数据
业务数据是有历史的,可以从前面几天模拟数据
# start
cd /opt/module/db_log/
# 修改文件内容
vim application.properties
# 生成第一天数据
#业务日期
mock.date=2020-06-09
#是否重置
mock.clear=1
#是否重置用户
mock.clear.user=1
java -jar gmall2020-mock-db-2021-01-22.jar
# 生成第二天数据
#业务日期
mock.date=2020-06-10
#是否重置
mock.clear=0
#是否重置用户
mock.clear.user=0
java -jar gmall2020-mock-db-2021-01-22.jar
# 重复执行几次,生成到2020-06-14
使用sqoop将数据从mysql采集到HDFS
[hzy@hadoop101 db_log]$ mysql_to_hdfs_init.sh all 2020-06-14
快速模拟数据
- 将xcall 和 xsync 两个脚本文件放在/bin目录下,并添加执行权限
- 安装依赖:
sudo yum install -y pdsh
- 将lg.sh 和 mock.sh 放入 /home/hzy/bin目录下
# xcall
#!/bin/bash
while getopts "w:" arg; do
case $arg in
w)
CLUSTER_TMP=$OPTARG
;;
?)
echo "unkonw argument $arg"
exit 1
;;
esac
done
if [ "$CLUSTER_TMP" ]; then
CLUSTER=$CLUSTER_TMP
shift
shift
fi
[ -z "$CLUSTER" ] && CLUSTER="hadoop101,hadoop102,hadoop103"
#pdsh -w "$CLUSTER" "$*" | sort -k1 -t" " | awk -F ": " '{if (host!=$1) {host=$1;print ">>>>>>>>>>>> "host" <<<<<<<<<<<<"};$1=null;print $0 }'
pdsh -w "$CLUSTER" "$*" | awk -F ": " '{key=$1;$1=null;out[key]=out[key]"\n"$0} END{ for (i in out) {print ">>>>>>>>>>>> "i" <<<<<<<<<<<<"out[i]} }'
# lg.sh
#!/bin/bash
CLUSTER='hadoop101,hadoop102'
APP_HOME='/opt/module/applog'
if [ "$1" ]; then
xcall -w "$CLUSTER" "sed -i '/mock.date/s/\".*\"/\"$1\"/' $APP_HOME/application.yml"
fi
xcall -w "$CLUSTER" "cd $APP_HOME; java -jar gmall2020-mock-log-2021-01-22.jar >/dev/null 2>&1 &"
init :从"2020-06-14“ 15天之前的数据开始生成
*:mock.sh 日期
# mock.sh
#!/bin/bash
DB_HOME='/opt/module/db_log'
function add_property() {
if [ ! -e "$1" ]; then
touch "$1"
fi
sed -i "/$2/d" "$1"
echo "$2=$3" >>"$1"
}
function mock_data() {
add_property $DB_HOME/application.properties "mock.date" "$1"
cd $DB_HOME || exit 1
java -jar gmall2020-mock-db-2021-01-22.jar 1>/dev/null 2>&1
}
case $1 in
"init")
add_property "$DB_HOME/application.properties" "mock.clear" "1"
add_property "$DB_HOME/application.properties" "mock.clear.user" "1"
DT=$(date -d "2020-06-14 -15 days" +%F)
echo "正在生成${DT}的数据"
mock_data "$DT"
add_property "$DB_HOME/application.properties" "mock.clear" "0"
add_property "$DB_HOME/application.properties" "mock.clear.user" "0"
for ((i = 14; i >= 0; i--)); do
DT=$(date -d "2020-06-14 -$i days" +%F)
echo "正在生成${DT}的数据"
mock_data "$DT"
done
;;
*)
mock_data "$1"
;;
esac
在hdfs上的/origin_data/gmall/db目录下可以看到数据,共27张表
至此,所有数据准备工作完成!