-
hive的随机抓取策略
理论上来说,Hive中的所有sql都需要进行mapreduce,但是hive的抓取策略帮我们
省略掉了这个过程,把切片split的过程提前帮我们做了。
set hive.fetch.task.conversion=none;
(一旦进行这么设置,select字段名也是需要进行mapreduce的过程,默认是more) -
本地运行模式
大多数的 Hadoop Job 是需要 Hadoop 提供的完整的可扩展性来处理大数据集的。不过,有时 Hive 的输入数据量是非常小的。在这种情况下,为查询触发执行任务消耗的时间可能会比实际 job 的执行时间要多的多。对于大多数这种情况, Hive 可以通过本地模式在单台机器上处理所有的任务。对于小数据集,执行时间可以明显被缩短。用户可以通过设置 hive.exec.mode.local.auto 的值为 true ,来让 Hive 在适当的时候自动启动这个优化。 -
并行计算
通过设置以下参数开启并行模式(默认是false)
set hive.exec.parallel=true;
注意:hive.exec.parallel.thread.number
(一次SQl计算中允许并行执行的job个数最大值,默认是8个) -
严格模式
1.什么是Hive的严格模式
hive中的一种模式,在该模式下禁止一些不好SQL的执行。
2.Hive的严格模式不允许哪些SQL执行
2.1 禁止分区表全表扫描
分区表往往数据量大,如果不加分区查询会带来巨大的资源消耗 。例如以下分区表
SELECT DISTINCT(planner_id) FROM fracture_ins WHERE planner_id=5;
报错如下:
FAILED: Error in semantic analysis: No Partition Predicate Found for Alias
“fracture_ins” Table "fracture_ins
解决如下:
SELECT DISTINCT(planner_id) FROM fracture_ins WHERE planner_id=5 AND
hit_date=20120101;
2.2 禁止排序不加limit
排序最终是要都进到一个Reduce中操作,防止reducer额外执行很长一段时间
SELECT * FROM fracture_ins WHERE hit_date>2012 ORDER BY planner_id;
出现如下错误
FAILED: Error in semantic analysis: line 1:56 In strict mode,limit must be
specified if ORDER BY is present planner_id
解决方案就是增加一个limit关键字:
SELECT * FROM fracture_ins WHERE hit_date>2012 ORDER BY planner_id LIMIT 100000;
2.3 禁止笛卡尔积
笛卡尔积是什么: A={a,b}, B={0,1,2},则 A×B={(a, 0), (a, 1), (a, 2), (b, 0), (b,
1), (b, 2)}
SELECT * FROM fracture_act JOIN fracture_ads;
解决方法
SELECT * FROM fracture_act JOIN fracture_ads WHERE fracture_act.planner_id =
fracture_ads.planner_id;
3.Hive的严格模式怎样开启
// 查看当前严格模式的状态 set hive.mapred.mode; // 设置为严格模式 set hive.mapred.mode=strict; // 设置为非严格模式 set hive.mapred.mode=nonstrict;
-
Hive排序
order by 对于查询结果做全排序,只允许有一个reduce处理
sort by 对于单个reduce进行排序 但是我们将每个reduce里面进行排序,没有考虑到每个reduce之间的排序。所以我们引出下一个distribute by 分区排序,通常结合sort by一起使用(distribute by column sort by column asc|desc)cluster by 相当于distribute by + sort by (注意,虽然是两个结合,但是我们也不去用它原因很简单,cluster by不能通过asc desc的方式指定排序方式规则) -
Hive join数据倾斜
1、小表join小表 不管他
2、小表join大表 map-join
3、大表join大表 map-side
考虑会不会发生reduce,并且考虑reduce压力是否大(是否会出现某个reduce数据量庞大的情况)
关于小表join大表两种实现方式:
1、sql方式,在sql语句中添加Mapjoin标记(mapjoin hint)语法糖
select /+MAPJOIN(A)/ * from A join B on (A.key=B.key);
select /+MAPJOIN(smallTable)/ smallTable.key bigTable.value from smallTable join
bigTable on smallTable.key=bigTable.key;
2、自动开启mapjoin
通过修改以下配置启用自动的mapjoin:
set hive.auto.convert.join=true;
(注意:该参数为true的时候,Hive自动对左边的表统计量,如果
是小表,就加入到内存,即对小表使用Mapjoin)
3、尽可能使用相同的连接键,如果不同,多一个join就会多开启一个mapreduce,执行速度变得慢。
4、大表join大表
a: 空key过滤:
有时join超时是因为某些key对应的数据太多,而相同key对应的数据都会发送到相同的 reducer上,从而导致内存不够。此时我们应该仔细分析这些异常的key,很多情况下,这些key对应的数据是异常数据,我们需要在SQL语句中进行过滤。但是这个的前提条件是异常数据,但是我们一般拿到的数据都是经过ETL数据清洗过后的,一般影响不大,面试的时候可以说。
b: 空key转换:
有时虽然某个key为空对应的数据很多,但是相应的数据不是异常数据,必须要包含在join的结果中,此时我们可以表a中key为空的字段赋随机的值,使得数据随机均匀地分不到不同的 reducer上(加盐)。但是我们一般拿到的数据都是经过ETL数据清洗过后的,规则数据,一般影响不大,面试的时候可以说。
5、Map-Side聚合
通过设置以下参数开启在Map端的聚合set hive.map.aggr=true;(一定要进行开启,虽然进行了两个mapreduce,但是当数据倾斜发生的时候,很多时候会根本跑不出结果,卡死在99%或者100%,慢总比出不来结果要好)!!!!!!! -
合并小文件
1、hadoop不适合存储小文件
2、MR不适合处理小文件
3、Hive不适合处理小文件 -
控制map和reduce的数量(一般情况下我们不去动它)
-
JVM重用
当我们的小文件个数过多,task个数过多,需要申请的资源过多的时候,我们可以先申请一部分资源,全部执行完毕后再释放,
比我们申请一个释放一个要快。
通过 set mapred.job.reuse.jvm.num.tasks=n;来设置
(n为task插槽个数)
缺点:
设置开启后,task插槽会一直占用资源,无论是否有task进行,直到所有的task,
即整个job全部执行完毕后,才会释放所有的task插槽,所以我们要合理地设置这个n
(比如,我们设置申请了10个,但是现在来了6个,剩下4个插槽会在job全部执行完毕之前一直占用资源)