Hive架构图
集群规划
服务器hadoop1.x | 服务器hadoop2.x | 服务器hadoop3.x | |
---|---|---|---|
Hive | Hive | ||
MySQL | MySQL |
1、Hive&MySQL安装
详细参照自己上次写的博客
MySql安装:
CentOS7安装MySQL
Navicat MySQL连接Linux下MySQL的问题解决方案
Hive安装:
数据仓库 Hive安装配置
2、Hive运行引擎Tez
Tez是一个Hive的运行引擎,性能优于MR。为什么优于MR呢?看下图。
用Hive直接编写MR程序,假设有四个有依赖关系的MR作业,上图中,绿色是Reduce Task,云状表示写屏蔽,需要将中间结果持久化写到HDFS。
Tez可以将多个有依赖的作业转换为一个作业,这样只需写一次HDFS,且中间节点较少,从而大大提升作业的计算性能。
- 安装包准备
(1) 下载tez的依赖包:http://tez.apache.org
也可以点击这里下载:运行引擎Tez.zip
(2) 上传解压缩apache-tez-0.9.0-bin.tar.gz
// 上传安装包
[root@hadoop1 hadoop]# rz -be
rz waiting to receive.
Starting zmodem transfer. Press Ctrl+C to cancel.
Transferring apache-tez-0.9.0-bin.tar.gz...
100% 59581 KB 19860 KB/sec 00:00:03 0 Errors
[root@hadoop1 hadoop]# ll
total 59588
-rw-r--r--. 1 root root 61011913 Apr 9 15:24 apache-tez-0.9.0-bin.tar.gz
drwxr-xr-x. 10 root root 4096 Apr 9 17:21 module
//解压
[root@hadoop1 hadoop]# tar -zxvf apache-tez-0.9.0-bin.tar.gz -C module/
(3) 修改名称
[root@hadoop1 module]# mv apache-tez-0.9.0-bin/ tez-0.9.0
- 在Hive中配置Tez
(1)进入到Hive的配置目录: hive-1.2.1/conf/
[root@hadoop1 module]# cd hive-1.2.1/conf/
(2)在hive-env.sh文件中添加tez环境变量配置和依赖包环境变量配置
[root@hadoop1 conf]# vim hive-env.sh
HADOOP_HOME=/usr/local/etc/hadoop/module/hadoop-2.7.2
export TEZ_HOME=/usr/local/etc/hadoop/module/tez-0.9.0 #是你的tez的解压目录
export TEZ_JARS=""
for jar in `ls $TEZ_HOME |grep jar`; do
export TEZ_JARS=$TEZ_JARS:$TEZ_HOME/$jar
done
for jar in `ls $TEZ_HOME/lib`; do
export TEZ_JARS=$TEZ_JARS:$TEZ_HOME/lib/$jar
done
export HIVE_AUX_JARS_PATH=/usr/local/etc/hadoop/module/hadoop-2.7.2/share/hadoop/common/hadoop-lzo-0.4.20.jar$TEZ_JARS
(3)在hive-site.xml文件中添加如下配置,更改hive计算引擎
<property>
<name>hive.execution.engine</name>
<value>tez</value>
</property>
- 配置Tez
(1) 在Hive的module/ hive-1.2.1/conf下面创建一个tez-site.xml文件
[root@hadoop1 hive-1.2.1]# cd conf/
[root@hadoop1 conf]# pwd
/usr/local/etc/hadoop/module/hive-1.2.1/conf
[root@hadoop1 conf]# vim tez-site.xml
//添加如下内容
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>tez.lib.uris</name> <value>${fs.defaultFS}/tez/tez-0.9.0,${fs.defaultFS}/tez/tez-0.9.0/lib</value>
</property>
<property>
<name>tez.lib.uris.classpath</name> <value>${fs.defaultFS}/tez/tez-0.9.1,${fs.defaultFS}/tez/tez-0.9.0/lib</value>
</property>
<property>
<name>tez.use.cluster.hadoop-libs</name>
<value>true</value>
</property>
<property>
<name>tez.history.logging.service.class</name> <value>org.apache.tez.dag.history.logging.ats.ATSHistoryLoggingService</value>
</property>
</configuration>
- 上传Tez到集群
(1) 将/module/tez-0.9.0上传到HDFS的/tez路径
//HDFS创建一个tez文件
[root@hadoop1 conf]# hadoop fs -mkdir /tez
//上传本地文件数据到HDFS
[root@hadoop1 module]# hadoop fs -put tez-0.9.0 /tez/
5) 测试
(1) 启动Hive
[root@hadoop1 hive-1.2.1]# bin/hive
//爆异常
Exception in thread "main" java.lang.RuntimeException: java.io.IOException: Previous writer likely failed to write hdfs://hadoop1.x:9000/tmp/hive/root/_tez_session_dir/0ff993ae-3e3f-4724-9073-93b947476f5f/hadoop-lzo-0.4.20.jar. Failing because I am unlikely to write too.
at org.apache.hadoop.hive.ql.session.SessionState.start(SessionState.java:535)
at org.apache.hadoop.hive.cli.CliDriver.run(CliDriver.java:677)
at org.apache.hadoop.hive.cli.CliDriver.main(CliDriver.java:621)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.hadoop.util.RunJar.run(RunJar.java:221)
at org.apache.hadoop.util.RunJar.main(RunJar.java:136)
Caused by: java.io.IOException: Previous writer likely failed to write hdfs://hadoop1.x:9000/tmp/hive/root/_tez_session_dir/0ff993ae-3e3f-4724-9073-93b947476f5f/hadoop-lzo-0.4.20.jar. Failing because I am unlikely to write too.
at org.apache.hadoop.hive.ql.exec.tez.DagUtils.localizeResource(DagUtils.java:980)
at org.apache.hadoop.hive.ql.exec.tez.DagUtils.addTempResources(DagUtils.java:860)
at org.apache.hadoop.hive.ql.exec.tez.DagUtils.localizeTempFilesFromConf(DagUtils.java:803)
at org.apache.hadoop.hive.ql.exec.tez.TezSessionState.refreshLocalResourcesFromConf(TezSessionState.java:219)
at org.apache.hadoop.hive.ql.exec.tez.TezSessionState.open(TezSessionState.java:147)
at org.apache.hadoop.hive.ql.exec.tez.TezSessionState.open(TezSessionState.java:116)
at org.apache.hadoop.hive.ql.session.SessionState.start(SessionState.java:532)
... 8 more
这种问题是从机上运行的Container试图使用过多的内存,而被NodeManager kill掉了。
解决方法:
方案一:或者是关掉虚拟内存检查。我们选这个,修改yarn-site.xml,修改后一定要分发,并重新启动hadoop集群。
注意:其他两台机器也要重新分发
方案二:mapred-site.xml中设置Map和Reduce任务的内存配置如下:(value中实际配置的内存需要根据自己机器内存大小及应用情况进行修改)
<property>
<name>mapreduce.map.memory.mb</name>
<value>1536</value>
</property>
<property>
<name>mapreduce.map.java.opts</name>
<value>-Xmx1024M</value>
</property>
<property>
<name>mapreduce.reduce.memory.mb</name>
<value>3072</value>
</property>
<property>
<name>mapreduce.reduce.java.opts</name>
<value>-Xmx2560M</value>
</property>
再次启动发现这种方法还是有点问题:
参照自己上次写的博客可以解决
数据仓库 Hive安装配置
2、项目经验之元数据备份
元数据备份(重点,如数据损坏,可能整个集群无法运行,至少要保证每日零点之后备份到其它服务器两个复本)
3、数仓搭建之ODS层
Hive仓库
- 创建数据库
(1) 创建gmall数据库
hive (default)> create database gmall;
OK
Time taken: 1.2 seconds
说明:如果数据库存在且有数据,需要强制删除时执行:drop database gmall cascade;
(2) 使用gmall数据库
hive (default)> use gmall;
OK
Time taken: 0.034 seconds
hive (gmall)>
- ODS层
原始数据层,存放原始数据,直接加载原始日志、数据,数据保持原貌不做处理。
创建启动日志表ods_start_log
(1) 创建输入数据是lzo输出是text,支持json解析的分区表
hive (gmall)>
drop table if exists ods_event_log;
CREATE EXTERNAL TABLE ods_event_log(`line` string)
PARTITIONED BY (`dt` string)
STORED AS
INPUTFORMAT 'com.hadoop.mapred.DeprecatedLzoTextInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION '/warehouse/gmall/ods/ods_event_log';
(2) 加载数据
hive (gmall)>
load data inpath '/origin_data/gmall/log/topic_event/2019-02-10' into table gmall.ods_event_log partition(dt='2019-02-10');
注意:时间格式都配置成YYYY-MM-DD格式,这是Hive默认支持的时间格式
(3) 查看是否加载成功
hive (gmall)> select * from ods_event_log limit 2;
4、Shell中单引号和双引号区别
案例:如当前日期为2020-04-10,想要回到昨天的时间,命令可以这样执行
[root@hadoop1 hive-1.2.1]# date -d "-1 day" +%F
2020-04-09
案例:如当前日期为2020-04-10,想要明天的时间,命令可以这样执行
[root@hadoop1 hive-1.2.1]# date -d "+1 day" +%F
2020-04-11
(1)接下来,我们写一个脚本。先到在/home/MrZhou/bin创建一个test.sh文件
[root@hadoop1 hive-1.2.1]# cd /home/MrZhou/bin/
[root@hadoop1 bin]# vim ods_log.sh
#!/bin/bash
# 定义变量方便修改
APP=gmall
hive=/usr/local/etc/hadoop/module/hive-1.2.1/bin/hive
# 如果是输入的日期按照取输入日期;如果没输入日期取当前时间的前一天
if [ -n "$1" ] ;then
do_date=$1
else
do_date=`date -d "-1 day" +%F`
fi
echo "===日志日期为 $do_date==="
sql="
load data inpath '/origin_data/gmall/log/topic_start/$do_date' into table "$APP".ods_start_log partition(dt='$do_date');
load data inpath '/origin_data/gmall/log/topic_event/$do_date' into table "$APP".ods_event_log partition(dt='$do_date');
"
$hive -e "$sql"
说明1:
[ -n 变量值 ] 判断变量的值,是否为空
– 变量的值,非空,返回true
– 变量的值,为空,返回false
说明2:
查看date命令的使用,[root@hadoop1 ~]$ date --help
(2)增加脚本执行权限
[root@hadoop1 bin]# chmod 777 ods_log.sh
(3)脚本使用
[root@hadoop1 bin]# ./ods_log.sh 2020-04-10
===日志日期为 2020-04-10===