Hive简介
定义
Facebook为了解决海量日志数据的剖析而开发了hive,起初开源给了Apache基金会组织。 hive是一种用SQL语句来帮助读写、治理存储在HDFS上的大数据集的数据仓库软件。

hive特点
▪ hive 最大的特点是通过类 SQL 来剖析大数据,而防止了写 mapreduce Java 程序来剖析数据,这样使得剖析数据更容易。
▪数据是存储在HDFS上的,hive自身并不提供数据的存储性能
▪hive是将数据映射成数据库和一张张的表,库和表的元数据信息个别存在关系型数据库上(比方MySQL)。
▪数据存储方面:他可能存储很大的数据集,并且对数据完整性、格局要求并不严格。
▪数据处理方面:不适用于实时计算和响应,应用于离线剖析。

hive根本语法
hive中的语句有点相似于mysql语句,次要分为DDL,DML,DQL,在此笔者就不做具体介绍了,稍微指出一点hive表分为外部表、内部表、分区表和分桶表,大数据培训感兴趣的读者能够查阅相干材料。

Hive原理
hive架构图

hive内核
hive 的内核是驱动引擎,驱动引擎由四局部组成,这四局部别离是:
▪解释器:解释器的作用是将hiveSQL语句转换为语法树(AST)。
▪编译器:编译器是将语法树编译为逻辑执行打算。
▪优化器:优化器是对逻辑执行打算进行优化。
▪执行器:执行器是调用底层的运行框架执行逻辑执行打算。

hive底层存储
hive的数据是存储在HDFS上,hive中的库和表能够看做是对HDFS上数据做的一个映射,所以hive必须运行在一个hadoop集群上。

hive程序执行过程
hive执行器是将最终要执行的mapreduce程序放到YARN上以一系列job的形式去执行。

hive元数据存储
hive的元数据是个别是存储在MySQL这种关系型数据库上的,hive与MySQL之间通过 MetaStore服务交互。

表2 hive元数据相干信息

hive客户端
hive有很多种客户端,下边简略列举了几个:
▪ cli命令行客户端:采纳交互窗口,用hive命令行和hive进行通信。
▪ hiveServer2客户端:用Thrift协定进行通信,Thrift是不同语言之间的转换器,是连贯不同语言程序间的协定,通过JDBC或者ODBC去拜访hive(这个是目前hive官网举荐应用的连贯形式)。
▪ HWI客户端:hive自带的客户端,然而比拟毛糙,个别不必。
▪ HUE客户端:通过Web页面来和hive进行交互,应用比拟,个别在CDH中进行集成。

Hive调优
hadoop就像吞吐量微小的轮船,启动开销大,如果每次只做小数量的输入输出,利用率将会很低。所以用好hadoop的首要任务是增大每次工作所搭载的数据量。hive优化时,把hive Sql当做mapreduce 程序来读,而不是当做SQL来读。hive优化这要从三个层面进行,别离是基于mapreduce优化、hive架构层优化和hiveQL层优化。

基于mapreduce优化
正当设置map数
下面的mapreduce执行过程局部介绍了,在执行map函数之前会先将HDFS上文件进行分片,失去的分片做为map函数的输出,所以map数量取决于map的输出分片(inputsplit),一个输出分片对应于一个map task,输出分片由三个参数决定,如表3:

表3 输出分片决定参数

公式:分片大小=max(mapreduce.min.split.size,min(dfs.block.size, mapreduce.max.split.size)),默认状况下分片大小和dfs.block.size是统一的,即一个HDFS数据块对应一个输出分片,对应一个map task。这时候一个map task中只解决一台机器上的一个数据块,不须要将数据跨网络传输,进步了数据处理速度。

正当设置reduce数
决定 reduce 数量的相干参数如表4:

表4 reduce数决定参数

所以能够用set mapred.reduce.tasks手动调整reduce task个数。

hive架构层优化
不执行mapreduce
hive从HDFS读取数据,有两种形式:启用mapreduce读取、间接抓取。

set hive.fetch.task.conversion=more

hive.fetch.task.conversion参数设置成more,能够在 select、where 、limit 时启用间接抓取形式,能显著晋升查问速度。

本地执行mapreduce
hive在集群上查问时,默认是在集群上N台机器上运行,须要多个机器进行协调运行,这个形式很好地解决了大数据量的查问问题。然而当hive查询处理的数据量比拟小时,其实没有必要启动分布式模式去执行,因为以分布式形式执行就波及到跨网络传输、多节点协调等,并且耗费资源。这个工夫能够只应用本地模式来执行mapreduce job,只在一台机器上执行,速度会很快。

JVM重用
因为hive语句最终要转换为一系列的mapreduce job的,而每一个mapreduce job是由一系列的map task和Reduce task组成的,默认状况下,mapreduce中一个map task或者一个Reduce task就会启动一个JVM过程,一个task执行结束后,JVM过程就退出。这样如果工作破费工夫很短,又要屡次启动JVM的状况下,JVM的启动工夫会变成一个比拟大的耗费,这个时候,就能够通过重用JVM来解决。

set mapred.job.reuse.jvm.num.tasks=5

这个设置就是制订一个jvm过程在运行屡次工作之后再退出,这样一来,节约了很多的 JVM的启动工夫。

并行化
一个hive sql语句可能会转为多个mapreduce job,每一个job就是一个stage,这些 job 程序执行,这个在hue的运行日志中也能够看到。然而有时候这些工作之间并不是是相互依赖的,如果集群资源容许的话,能够让多个并不相互依赖stage并发执行,这样就节约了工夫,进步了执行速度,然而如果集群资源匮乏时,启用并行化反倒是会导致各个job互相抢占资源而导致整体执行性能的降落。
启用并行化:

set hive.exec.parallel=true

hiveQL层优化
利用分区表优化
分区表是在某一个或者某几个维度上对数据进行分类存储,一个分区对应于一个目录。在这中的存储形式,当查问时,如果筛选条件里有分区字段,那么hive只须要遍历对应分区目录下的文件即可,不必全局遍历数据,使得解决的数据量大大减少,进步查问效率。
当一个hive表的查问大多数状况下,会依据某一个字段进行筛选时,那么非常适合创立为分区表。

利用桶表优化
桶表的概念在本教程第一步有具体介绍,就是指定桶的个数后,存储数据时,依据某一个字段进行哈希后,确定存储再哪个桶里,这样做的目标和分区表相似,也是使得筛选时不必全局遍历所有的数据,只须要遍历所在桶就能够了。

hive.optimize.bucketmapJOIN=true;
hive.input.format=org.apache.hadoop.hive.ql.io.bucketizedhiveInputFormat;
hive.optimize.bucketmapjoin=true;
hive.optimize.bucketmapjoin.sortedmerge=true;

join优化
▪ 优先过滤后再join,最大限度地缩小参加join的数据量。
▪ 小表join大表准则
应该恪守小表join大表准则,起因是join操作的reduce阶段,位于join右边的表内容会被加载进内存,将条目少的表放在右边,能够无效缩小产生内存溢出的几率。join中执行程序是从做到右生成job,应该保障间断查问中的表的大小从左到右是顺次减少的。
▪ join on条件雷同的放入一个job
hive中,当多个表进行join时,如果join on的条件雷同,那么他们会合并为一个
mapreduce job,所以利用这个个性,能够将雷同的join on的放入一个job来节俭执行工夫。

select pt.page_id,count(t.url) PV
from rpt_page_type pt join ( select url_page_id,url from trackinfo where ds='2016-10-11' ) t on pt.page_id=t.url_page_id join ( select page_id from rpt_page_kpi_new where ds='2016-10-11' ) r on t.url_page_id=r.page_id group by pt.page_id;

▪ 启用mapjoin
mapjoin是将join单方比拟小的表间接散发到各个map过程的内存中,在map过程中进行join操作,这样就省掉了reduce步骤,进步了速度。
▪ 桶表mapjoin
当两个分桶表join时,如果join on的是分桶字段,小表的分桶数时大表的倍数时,能够启用map join来提高效率。启用桶表mapjoin要启用hive.optimize.bucketmapjoin参数。
▪ Group By数据歪斜优化
Group By很容易导致数据歪斜问题,因为理论业务中,通常是数据集中在某些点上,这也合乎常见的2/8准则,这样会造成对数据分组后,某一些分组上数据量十分大,而其余的分组上数据量很小,而在mapreduce程序中,同一个分组的数据会调配到同一个reduce操作下来,导致某一些reduce压力很大,其余的reduce压力很小,这就是数据歪斜,整个job 执行工夫取决于那个执行最慢的那个reduce。
解决这个问题的办法是配置一个参数:set hive.groupby.skewindata=true。
当选项设定为true,生成的查问打算会有两个MR job。第一个MR job 中,map的输入后果会随机散布到Reduce中,每个Reduce做局部聚合操作,并输入后果,这样解决的后果是雷同的Group By Key有可能被散发到不同的Reduce中,从而达到负载平衡的目标;第二个MR job再依据预处理的数据后果依照Group By Key散布到Reduce中(这个过程能够保障雷同的GroupBy Key被散布到同一个Reduce中),最初实现最终的聚合操作。
▪ Order By 优化
因为order by只能是在一个reduce过程中进行的,所以如果对一个大数据集进行order by,会导致一个reduce过程中解决的数据相当大,造成查问执行超级迟缓。
▪ 一次读取屡次插入
▪ Join字段显示类型转换
▪ 应用orc、parquet等列式存储格局

原创作者:bling ss