Hive:基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张表,并提供类SQL查询功能
数据存储在HDFS,底层的实现是MapReduce,spark等,运行在Yarn上。
优点:
(1)操作接口采用类SQL语法,提供快速开发的能力(简单、容易上手)。
(2)避免了去写MapReduce,减少开发人员的学习成本。
(3)Hive优势在于处理大数据,支持海量数据的分析与计算。
(4)Hive支持用户自定义函数,用户可以根据自己的需求来实现自己的函数。
缺点:
1)Hive的HQL表达能力有限:
(1)Hive自动生成的MapReduce作业,通常情况下不够智能化
(2)数据挖掘方面不擅长,由于MapReduce数据处理流程的限制,效率更高的算法却无法实现。
2)Hive的效率比较低:
(1)Hive的执行延迟比较高,因此Hive常用于数据分析,对实时性要求不高的场合。
(2)Hive调优比较困难,粒度较粗
3)Hive不支持实时查询和行级别更新
1)hive分析的数据是存储在hdfs上,hdfs不支持随机写,只支持追加写,所以在hive中不能delete和update,只能select和insert
Hive架构原理:
Client:CLI(command-line interface)、JDBC/ODBC(jdbc访问hive)、WEBUI(浏览器访问hive)
元数据:Metastore
默认存储在derby数据库(不支持多客户端连接),推荐使用MySQL存储Metastore(多客户端访问)
Hadoop:
使用HDFS进行存储,使用MapReduce进行计算
驱动器:Driver
SQL解析器antlr语法分析-->编译器生成逻辑执行计划-->优化器对逻辑执行计划进行优化-->执行器运行的物理计划,就是MR/Spark
Hive安装:
下载地址:http://archive.apache.org/dist/hive/
检查当前系统是否安装过Mysql:rpm -qa|grep mariadb
卸载mariadb:sudo rpm -e --nodeps mariadb-libs
安装mysql:按照顺序依次执行
安装包拷贝到/opt/software目录下
tar -xvf mysql-5.7.28-1.el7.x86_64.rpm-bundle.tar
sudo rpm -ivh mysql-community-common-5.7.28-1.el7.x86_64.rpm
sudo rpm -ivh mysql-community-libs-5.7.28-1.el7.x86_64.rpmsudo rpm -ivh
mysql-community-libs-compat-5.7.28-1.el7.x86_64.rpm
sudo rpm -ivh mysql-community-client-5.7.28-1.el7.x86_64.rpm
sudo rpm -ivh mysql-community-server-5.7.28-1.el7.x86_64.rpm
报错下载依赖:sudo yum install -y libaio
初始化数据库:sudo mysqld --initialize --user=mysql
临时生成的root用户的密码:sudo cat /var/log/mysqld.log
启动MySQL:sudo systemctl start mysqld
登录MySQL数据库:mysql -uroot -p 回车输入临时密码
修改root用户的密码:set password = password("123456");
修改mysql库下的user表中的root用户允许任意ip连接:update mysql.user set host='%' where user='root';
flush privileges;
2.3 Hive安装部署:解压
修改/etc/profile.d/my_env.sh,添加环境变量
#HIVE_HOME
export HIVE_HOME=/opt/module/hive
export PATH=$PATH:$HIVE_HOME/bin
日志Jar包冲突:
mv $HIVE_HOME/lib/log4j-slf4j-impl-2.10.0.jar $HIVE_HOME/lib/log4j-slf4j-impl-2.10.0.bak(改名字方式)
Hive元数据配置到MySql
将MySQL的JDBC驱动拷贝到Hive的lib目录:cp /opt/software/mysql-connector-java-5.1.37.jar $HIVE_HOME/lib
配置Metastore到MySql:
$HIVE_HOME/conf目录下新建hive-site.xml文件
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<!-- jdbc连接的URL -->
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://hadoop102:3306/metastore?useSSL=false</value>
</property>
<!-- jdbc连接的Driver-->
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
</property>
<!-- jdbc连接的username-->
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value>
</property>
<!-- jdbc连接的password -->
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>123456</value>
</property>
<!-- Hive默认在HDFS的工作目录 -->
<property>
<name>hive.metastore.warehouse.dir</name>
<value>/user/hive/warehouse</value>
</property>
<!-- 指定hiveserver2连接的端口号 -->
<property>
<name>hive.server2.thrift.port</name>
<value>10000</value>
</property>
<!-- 指定hiveserver2连接的host -->
<property>
<name>hive.server2.thrift.bind.host</name>
<value>hadoop102</value>
</property>
<!-- 指定存储元数据要连接的地址 -->
<property>
<name>hive.metastore.uris</name>
<value>thrift://hadoop102:9083</value>
</property>
<!-- 元数据存储授权 -->
<property>
<name>hive.metastore.event.db.notification.api.auth</name>
<value>false</value>
</property>
<!-- Hive元数据存储版本的验证 -->
<property>
<name>hive.metastore.schema.verification</name>
<value>false</value>
</property>
<!-- hiveserver2的高可用参数,开启此参数可以提高hiveserver2的启动速度 -->
<property>
<name>hive.server2.active.passive.ha.enable</name>
<value>true</value>
</property>
</configuration>
启动Hive
登陆MySQL:mysql -uroot -p123456
新建Hive元数据库:create database metastore;
初始化Hive元数据库:schematool -initSchema -dbType mysql -verbose
启动metastore和hiveserver2
nohup hive --service metastore>log.txt 2>&1 &
nohup hive --service hiveserver2>log2.txt 2>&1 &
脚本来管理服务的启动和关闭,详见脚本
HiveJDBC访问:
启动beeline客户端:bin/beeline -u jdbc:hive2://hadoop102:10000 -n 用户名
启动hive客户端: bin/hive
打印 当前库 和 表头:hive-site.xml中加入如下两个配置
<property>
<name>hive.cli.print.header</name>
<value>true</value>
<description>Whether to print the names of the columns in query output.</description>
</property>
<property>
<name>hive.cli.print.current.db</name>
<value>true</value>
<description>Whether to include the current database in the Hive prompt.</description>
</property>
交互:
不进入hive的交互窗口执行sql语句:bin/hive -e "sql语句"
执行脚本中sql语句:bin/hive -f 绝对路径/sql脚本
将结果写入文件中:bin/hive -f 绝对路径/sql脚本 > 绝对路径/结果接收文件
Hive其他命令操作:
退出hive窗口:exit;-->:先隐性提交数据,再退出 quit;-->不提交数据,退出
hive客户端查看hdfs文件系统:dfs -ls /;
查看hive中历史命令:当前用户的家目录.hivehistory文件
查看beeline中历史命令:当前用户的家目录.beeline/history文件
查看当前所有的配置信息:set;
Hive常见属性配置:
Hive的log默认存放在/tmp/用户名/hive.log目录下
hive-log4j.properties-->mv hive-log4j.properties.template hive-log4j.properties
hive-log4j.properties文件中修改log存放位置:
property.hive.log.dir=/opt/module/hive/logs
jvm堆内存设置(本地模式):默认申请的jvm堆内存大小为256M
修改$HIVE_HOME/conf下的hive-env.sh.template为hive-env.sh
将hive-env.sh其中的参数 export HADOOP_HEAPSIZE=1024的注释放开,重启hive。
参数的配置三种方式:
(1)默认配置文件:hive-default.xml
用户自定义配置文件:hive-site.xml
用户自定义配置会覆盖默认配置。Hive的配置会覆盖Hadoop的配置
(2)命令行参数方式
命令行添加-hiveconf param=value来设定参数--->仅对本次hive启动有效
(3)参数声明方式
sql中:setparam=value;
查看参数设置:set mapred.reduce.tasks;
Hive数据类型:
HIVE MySQL JAVA
TINYINT TINYINT byte
SMALINT SMALINT short
INT INT int
BIGINT BIGINT long
BOOLEAN 无 boolean
FLOAT FLOAT float
DOUBLE DOUBLE double
STRING VARCHAR string
TIMESTAMP TIMESTAMP
BINARY BINARY
复杂数据类型
STRUCT-->可以通过“点”符号访问元素内容
MAP-->MAP是一组键-值对元组集合,使用数组表示法可以访问数据
ARRAY-->数组是一组具有相同类型和名称的变量的集合。这些变量称为数组的元素,每个数组元素都有一个编号,编号从零开始。
类型转换:Hive的原子数据类型是可以进行隐式转换的
规则:
(1)任何整数类型都可以隐式地转换为一个范围更广的类型,如TINYINT可以转换成INT,INT可以转换成BIGINT。
(2)所有整数类型、FLOAT和STRING类型都可以隐式地转换成DOUBLE。
(3)TINYINT、SMALLINT、INT都可以转换为FLOAT。
(4)BOOLEAN类型不可以转换为任何其它的类型。
可以使用CAST操作显示进行数据类型转换:强制类型转换失败,如执行CAST('X' AS INT),表达式返回空值 NULL。
HIVE SQL:详见hivesql总结
压缩和存储
压缩方式和对比详见:压缩和解压缩
开启hive中间传输数据压缩功能
set hive.exec.compress.intermediate=true;
开启mapreduce中map输出压缩功能
set mapreduce.map.output.compress=true;
设置mapreduce中map输出数据的压缩方式
set mapreduce.map.output.compress.codec=org.apache.hadoop.io.compress.SnappyCodec;
开启hive最终输出数据压缩功能
set hive.exec.compress.output=true;
开启mapreduce最终输出数据压缩
set mapreduce.output.fileoutputformat.compress=true;
设置mapreduce最终数据输出压缩方式
set mapreduce.output.fileoutputformat.compress.codec =org.apache.hadoop.io.compress.SnappyCodec;
设置mapreduce最终数据输出压缩为块压缩
set mapreduce.output.fileoutputformat.compress.type=BLOCK;
Hive支持的存储数据的格式主要有:TEXTFILE 、SEQUENCEFILE、ORC、PARQUET
TextFile:默认格式,数据不做压缩,磁盘开销大,数据解析开销大
Orc:由1个或多个stripe组成,每个stripe一般为HDFS的块大小,stripe包含多条记录,按照列进行独立存储
Parquet:以二进制方式存储,不可直接读取,包括数据和元数据,Parquet是自解析的
TEXTFILE和SEQUENCEFILE的存储格式都是基于行存储的
ORC和PARQUET是基于列式存储的
行存储的特点:查询满足条件的一整行数据的时候,行存储查询的速度更快
列存储的特点:查询只需要少数几个字段的时候,大大减少读取的数据量、更好的设计压缩算法
hive调优
Fetch抓取
hive-default.xml.template文件中hive.fetch.task.conversion默认more,老版本hive默认minimal,修改为more后,在全局查找、字段查找、limit查找等都不走mapreduce。
对于小数据集,本地模式在单台机器上处理所有的任务
set hive.exec.mode.local.auto=true; //开启本地mr
设置local mr的最大输入数据量,默认128M
set hive.exec.mode.local.auto.inputbytes.max=50000000;
设置local mr的最大输入文件个数默认为4
set hive.exec.mode.local.auto.input.files.max=10;
表的优化
大小表join:数据量小的表放在join的左边,减少内存溢出错误发生的几率;再进一步,使用map join让小的维度表(1000条以下的记录条数)先进内存。在map端完成reduce。(新版已自动优化)
大表Join大表:空KEY过滤或空key转换
开启MapJoin参数设置:set hive.auto.convert.join = true; 默认为true
大表小表的阈值,默认25M以下是小表:set hive.mapjoin.smalltable.filesize=25000000;
Group By
同一Key数据分发给一个reduce,当一个key数据过大时就倾斜
不是所有的聚合操作都需要在Reduce端完成,很多聚合操作都可以先在Map端进行部分聚合,最后在Reduce端得出最终结果
Map端聚合参数设置
是否在Map端进行聚合,默认为True
set hive.map.aggr = true
在Map端进行聚合操作的条目数目
set hive.groupby.mapaggr.checkinterval = 100000
数据倾斜的时候进行负载均衡(默认是false)
set hive.groupby.skewindata = true
TRUE时,生成的查询计划会有两个MR Job
Count(Distinct) 去重统计
使用先GROUP BY再COUNT的方式替换,但是需要注意group by造成的数据倾斜问题.
避免笛卡尔积
行列过滤:
少用SELECT *
使用外关联时,如果将副表的过滤条件写在Where后面,那么就会先全表关联,之后再过滤
分区分桶
合理设置Map及Reduce数
小文件多就小文件进行合并,减少map,字段少,记录多的可以增多map
复杂文件增加Map数
小文件合并:
map执行前合并小文件,减少map数:CombineHiveInputFormat具有对小文件进行合并的功能
set hive.input.format= org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
map-only任务结束时合并小文件,默认true
SET hive.merge.mapfiles = true;
map-reduce任务结束时合并小文件,默认false
SET hive.merge.mapredfiles = true;
合并文件的大小,默认256M
SET hive.merge.size.per.task = 268435456;
输出文件的平均大小小于该值时,启动一个独立的map-reduce任务进行文件merge
SET hive.merge.smallfiles.avgsize = 16777216;
合理设置Reduce数:
处理大数据量利用合适的reduce数;使单个reduce任务处理数据量大小要合适;
每个Reduce处理的数据量默认是256MB
hive.exec.reducers.bytes.per.reducer=256000000
每个任务最大的reduce数,默认为1009
hive.exec.reducers.max=1009
计算reducer数的公式
N=min(参数2,总输入数据量/参数1)
mapred-default.xml文件
设置每个job的Reduce个数
set mapreduce.job.reduces = 15;
并行执行
MapReduce阶段、抽样阶段、合并阶段、limit阶段,默认情况下,Hive一次只会执行一个阶段
set hive.exec.parallel=true; //打开任务并行执行,默认为false
set hive.exec.parallel.thread.number=16;//同一个sql允许最大并行度,默认为8。
严格模式
将hive.strict.checks.no.partition.filter设置为true对于分区表,除非where语句含分区字段过滤条件限制范围,否则不允许执行
将hive.strict.checks.orderby.no.limit设置为true时,对于使用了order by语句的查询,要求必须使用limit语句
将hive.strict.checks.cartesian.product设置为true时,会限制笛卡尔积的查询。
JVM重用
压缩
am比例适当调大
将$HADOOP_HOME/etc/hadoop/capacity-scheduler.xml文件
<property>
<name>yarn.scheduler.capacity.maximum-am-resource-percent</name>
<value>0.1</value>
<description>
Maximum percent of resources in the cluster which can be used to run
application masters i.e. controls number of concurrent running
applications.
</description>
</property>
注:hive默认的输入格式处理是CombineHiveInputFormat,会对小文件进行合并
可以采用HiveInputFormat就会根据分区数输出相应的文件
启动mysql服务时,报MySQL server PID file could not be found! 异常
在/var/lock/subsys/mysql路径下创建hadoop102.pid,并在文件中添加内容:4396