hive中常用的几个排序

order by   #全局排序,因为是全局排序,所以job是一个reduce,reduce的个数参数设置对其无效

sort by    #一个reduce时为全局排序,多个reduce时,每个reduce各自排序,为了提高全局排序的性能,可以先用sort by做局部排序,然后再做全局排序

distribute by #hash 分组,根据key和reduce个数进行数据分发,默认使用hash的方式

cluster by #distribute by + sort by(注意和hive.enforce.bucketing参数的应用)

结合两个例子来看排序的应用:

1)cdnjob的优化思路

熟悉map slot的分配规则的同学应该知道,text gz的文件是不支持split的,因此这种情况下最多只有一个map(不管数据量多大),

这样在做数据处理时,如果文件很大而且计算逻辑比较复杂(比如cdn的报表,需要做各种聚合计算和ip地址的解析),效率就会比较低下。

一个思路就是建一个中间表,对原始表进行distribute by,对中间表进行复杂的计算,这样就可以使用多个map,提高运算效率。

2)solr测试的思路

测试hive2solr时,需要模拟一个文件和多个文件的写入情况。

默认使用的sql是



insert into table xxx  select * from data_for_sol;



这是一个hdfs操作,不涉及mapred,不太好模拟多个文件的写入情况。

可以在后面套一个 distribute by ,并合理设置reduce的数量(mapred.reduce.tasks),这样就会生成多个reduce的文件。



insert into table xxx select * from data_for_solr distribute by session_id;



注意:reduce slot的分配由下面几个情况决定

1)sql类型(比如order by只有一个reduce)

2)参数



mapred.reduce.tasks;



每个任务reduce的默认值,默认为-1,-1 代表自动根据作业的情况来设置reduce的值,优先级高于下面两个设置。



hive.exec.reducers.bytes.per.reducer



根据reduce的输入数据(map端的输出数据,不管是否压缩),大小判断reduce的个数,默认1G

hive.exec.reducers.max reduce的最大数量,默认999个

计算方法:



  reducers = (int) ((totalInputFileSize + bytesPerReducer - 1) / bytesPerReducer);   reducers = Math.max(1, reducers);   reducers = Math.min(maxReducers, reducers);      关于map/reduce slot的分配规则以后有机会再说。


转载于:https://blog.51cto.com/caiguangguang/1427493