说明:本文主要涉及hadoop、hive查询统计基础知识及一些进阶方法
不要用context.write(new Text(...),new Text(...))
而是用
key.set(...);
value.set(...);
不要使用Formatter,不要使用StringBuffer,不要介意使用+
//StringBuilder sb = new StringBuilder(); //警告全局变量勿用
map(....) {
StringBuilder sb = new StringBuilder()
}
很多人喜欢使用string split方法,简单快捷,但是split底层每次使用的时候要重新new Pattern(),new几千万次效率何其较低下,
推荐使用StringUtils或者正则表达式预先声明
StringBuilder、集合类,有些时候一个劲儿装载数据,却不清空,导致full gc,甚至集群一下子增加十几个T的空间,把集群搞死。
可以用,但是不要超过50个。
where分区中的条件,会提前生效,不必特意做子查询。可参考hive执行计划树解析hive.optimize.pruner=true,hive默认为true
在读取数据的时候,只读取查询需要用到的列。
hive.optimize.cp=true,hive默认为true
尽量避免笛卡尔积,join的时候不加on条件,hive只能使用1个reduce来完成笛卡尔积。(on条件只支持等值操作)
先做union all再做join或group by等操作可以有效减少MR过程,尽管又多个select但是只有一个MR过程。
读取一次,多个查询统计
FROM(
$DEVICE_TEMP_TABLE_SQL
) temp_device_table
insert overwrite local directory '$DEVICE_T_MOBILE_RESULT'
$DEVICE_T_MOBILE_SQL
insert overwrite local directory '$DEVICE_WIFI_RESULT'
$DEVICE_WIFI_SQL
set hive.map.aggr =true,进行聚合函数操作sum、count等操作时,会在map端先进行一次聚合操作。
可以通过设置hive.groupby.mapaggr.checkinterval来控制map端聚合的数目,默认是100000
hive.merge.mapfiles = TRUE 是否合并map-only job的输出文件,默认为true
hive.merge.mapredfiles = FALSE 是否合并map-reduce的输出文件,默认为false,建议开启,
降低文件数据过多对hdfs带来的压力
hive.merge.size.per.task=256000000 合并文件的大小,默认为256M
hive.exec.mode.local.auto=false,默认为false,建议开启。
处理小数据量作业时,使用本地模式可以使hive执行的更快些。满足如下job的条件才会触发本地作业
可用参数hive.mapred.local.mem,来设置local model下mapper和reduce task jvm heap size(在本地模式的最大内存量,以字节为单位,默认为0,不加限制,有hadoop自己控制)
order by 全局排序
sort by 不是全局排序,只能保证在同一reduce输出有序
distribute by 根据distribute by指定的内容将数据分到同一reduce
cluster by 除了具有distiribute by的功能外,还会对字段进行排序,可以看做sort by + distribute by
select关键字后面添加/+ MAPJOIN(tablelist) +/,tablelist中的表将会读入内存,必须是小表,最好不要超过10万以上。
hive总是按照从左到右的先后顺序执行,
例a表:大表,b表:小表,数据分布均与。
a表 b表
key key
10 10
10 20
10 20
20
20
20
a jon b on a.key = b.key,需要计算a.10 = b.10 4+3=7, a.20 = b.20 4+6=10,合计比较17次
b join a on b.key = a.key,代价 b.10=a.10 2+3=5,b.20 = a.20 3+6=9,合计比较14次
如果是千万级的大表,显然b表 join a表查询效率要高很多。
hive.groupby.skewindata=true,万能解决方法。有数据倾斜的时候尽心负载均衡,当选项设定为true,生成的查询计划会有两个MR JOB。第一个MR job中,Map的输出结果集合会随即分不到Reduce中,每个Reduce做部分聚合操作,并输出结果,这样处理的结果是相同的Group By key有可能分发到不同的Reduce中,从而达到负载均衡的目的;第二个MR job再根据预处理的数据结果按照Group By Key分不到Reduce中(这个过程可以保证相同的Group By Key被分不到同一个Reduce中),最后完成最终的聚合操作。
不合法的值直接过滤掉,或者把null的值加上一个随机数,把倾斜的数据分发到不同的reduce上。
可以先做一次distinct操作,在做count操作,值为null的值也可以直接过滤掉
例计算全站mau
select cast(count(1) as int)+1 from (select distinct id from iplog where log_date>='2013-11-09' and log_date<='2013-12-09' and id>0) t;
采用sum() group by 方式来替代count(distinct)完成计算
数据倾斜总结:http://www.alidata.org/archives/2109
hive优化:http://www.alidata.org/archives/595
hive参数优化:http://www.cnblogs.com/yshb/p/3147710.html