作者: 佚名 浏览: 日期:2024-05-06
Hive简介
一、Hadoop开发存在的问题
二、Hive概述
三、Hive的HQL
四、特点
五、适用场景
数据库和数据仓库
一、数据仓库和数据库对比
二、OLTP和OLAP对比
流程
1. 通过客户端提交一条Hql语句
2. 通过complier(编译组件)对Hql进行词法分析、语法分析。在这一步,编译器要知道此hql语句到底要操作哪张表
3. 去元数据库找表信息
4. 得到信息
5. complier编译器提交Hql语句分析方案
6. 执行流程
a. executor 执行器收到方案后,执行方案(DDL过程)。在这里注意,执行器在执行方案时,会进行判断:如果当前方案不涉及到MR组件,比如为表添加分区信息、比如字符串操作等,比如简单的查询操作等,此时就会直接和元数据库交互,然后去HDFS上去找具体数据;如果方案需要转换成MR job,则会将job 提交给Hadoop的JobTracker
b. MR job完成,并且将运行结果写入到HDFS上
c. 执行器和HDFS交互,获取结果文件信息
7. 如果客户端提交Hql语句是带有查询结果性的,则会发生:7-8-9步,完成结果的查询。
优化
b. 优化后:
i. 利用Hive对嵌套语句的支持,将原来一个MapReduce作业转换为两个作业:在第一阶段选出全部的非重复id,在第二阶段再对这些已消重的id进行计数
ii. 在第一阶段我们可以通过增大Reduce的并发数,并发处理Map输出
iii. 在第二阶段,由于id已经消重,因此COUNT(*)操作在Map阶段不需要输出原id数据,只输出一个合并后的计数即可。这样即使第二阶段Hive强制指定一个Reduce Task,极少量的Map输出数据也不会使单一的Reduce Task成为瓶颈
iv. 这一优化使得在同样的运行环境下,优化后的语句执行只需要原语句20%左右的时间
e. 调整切片数(map任务数)
i. Hive底层自动对小文件做了优化,用了CombineTextInputFormat,将做个小文件切片合成一个切片。如果合成完之后的切片大小>mapred.max.split.size 的大小,就会生成一个新的切片
ii. mapred.max.split.size 默认是128MB,设置方式为:set mapred.max.split.size=134217728(128MB)
iii. 对于切片数(MapTask)数量的调整,要根据实际业务来定,比如一个100MB的文件包含了有1千万条数据,此时可以调成10个MapTask,则每个MapTask处理1百万条数据。
f. JVM重利用
i. 设置方式:set mapred.job.reuse.jvm.num.tasks=20(默认是1个)
ii. JVM重用是hadoop调优参数的内容,对hive的性能具有非常大的影响,特别是对于很难避免小文件的场景或者task特别多的场景,这类场景大多数执行时间都很短。这时JVM的启动过程可能会造成相当大的开销,尤其是执行的job包含有成千上万个task任务的情况
iii. JVM重用可以使得一个JVM进程在同一个JOB中重新使用N次后才会销毁。
g. 启用严格模式
i. 用户可以通过 set hive.mapred.mode=strict 来设置严格模式,改成unstrict则为非严格模式
ii. 在严格模式下,用户在运行如下query的时候会报错:
i. 分区表的查询没有使用分区字段来限制
ii. 使用了order by 但没有使用limit语句(如果不使用limit,会对查询结果进行全局排序,消耗时间长)
iii. 产生了笛卡尔积
h. 关闭推测执行机制
通常在测试环境下机会确定应用程序是否跑通,如果还加上推测执行,那么在数据分片本来就会发生数据倾斜,执行执行时间就是比其他的时间长,那么hive就会把这个执行时间长的job当作运行失败,继而又产生一个相同的job去运行,造成资源的浪费。可通过如下设置关闭推测执行:
set mapreduce.map.speculative=false
set mapreduce.reduce.speculative=false
set hive.mapred.reduce.tasks.speculative.execution=false