用数据看hive的order distribute sort cluster by的区别

    技术2024-01-01  100

    文章目录

    1.distribute by hash分发到不同分区1.1实验1.2使用场景 2. sort by 局部排序2.1 设置reduce job数对sort by有效果2.2 直接sort by会出现数据分布不均匀的分区内排序2.3 sort by与distribute by 联合使用实现分区内有序 3.cluster by3.1 cluster by 等价于 distribute by+ sort by(distribute和sort字段相同)3.2 distribute by+sort by 比 cluster by 更加灵活 4.order by4.1 全局排序的特点4.2 使用场景 5.总结

    1.distribute by hash分发到不同分区

    分区规则是根据分区字段的hash码与reduce的个数进行模除后,余数相同的分到一个区。

    1.1实验

    hive (default)> select * from empt; OK empt.empno empt.ename empt.job empt.mgr empt.hiredate empt.sal empt.comm empt.deptno 7566 JONES MANAGER 7863 1980-12-17 2975.0 0 20 7499 NULL NULL NULL NULL NULL NULL NULL 7369 SMITH CLERK 7902 1980-12-17 800.0 0 20 7499 ALLEN SALESMAN 7968 1980-12-17 1600.0 300 20 set mapreduce.job.reduces=3; set hive.merge.mapredfiles=false; insert overwrite table empt select * from empt distribute by empno;

    [root@hadoop logs]# hdfs dfs -cat /hive/db/empt/000000_0 7566,JONES,MANAGER,7863,1980-12-17,2975.0,0,20 [root@hadoop logs]# hdfs dfs -cat /hive/db/empt/000001_0 7369,SMITH,CLERK,7902,1980-12-17,800.0,0,20 [root@hadoop logs]# hdfs dfs -cat /hive/db/empt/000002_0 7451,\N,\N,\N,\N,\N,\N,\N 7499,\N,\N,\N,\N,\N,\N,\N 7499,ALLEN,SALESMAN,7968,1980-12-17,1600.0,300,20 7566%3=0 在文件000000_0中 7396%3=1 在文件000001_0中 7499%3=2 在文件000002_0中

    1.2使用场景

    a.distribute by 和 order by 不能一起使用,因为前者是分桶,后者是全局排序,有冲突 hive (default)> select * from empt distribute by empno order by empno; FAILED: ParseException line 1:39 missing EOF at 'order' near 'empno' b.kylin构建cube的第二步中使用到distributed by Redistribute Flat Hive Table 重新分发数据 第一步产出在HDFS上面的数据,文件大小可能会存在分布不均匀的情况: 1.map task ==> 大的文件 ==> 慢 2.map task ==> 小的文件 ==> 快 INSERT OVERWRITE TABLE \`kylin_intermediate_ruozedata_user_click_cube_56d719e1_e45a_ec49_1538_d5c5313b82ee\` SELECT * FROM \`kylin_intermediate_ruozedata_user_click_cube_56d719e1_e45a_ec49_1538_d5c5313b82ee\` DISTRIBUTE BY DW_USER_CLICK_D_DAY,DW_USER_CLICK_D_PROVINCE_ID,DW_USER_CLICK_D_CITY_ID; 通过distributed by语法对数据进行重新分发 + mapreduce.job.reduces 最终达成的效果:使得最终的数据分布非常均匀,且毫无规律

    2. sort by 局部排序

    2.1 设置reduce job数对sort by有效果

    set mapreduce.job.reduces=1; set hive.merge.mapredfiles=false; insert overwrite table empt select * from empt sort by empno;

    [root@hadoop logs]# hdfs dfs -cat /hive/db/empt/000000_0 7369,SMITH,CLERK,7902,1980-12-17,800.0,0,20 7499,ALLEN,SALESMAN,7968,1980-12-17,1600.0,300,20 7499,\N,\N,\N,\N,\N,\N,\N 7566,JONES,MANAGER,7863,1980-12-17,2975.0,0,20

    2.2 直接sort by会出现数据分布不均匀的分区内排序

    set mapreduce.job.reduces=3; set hive.merge.mapredfiles=false; insert overwrite table empt select * from empt sort by empno;

    [root@hadoop logs]# hdfs dfs -cat /hive/db/empt/000000_0 empty [root@hadoop logs]# hdfs dfs -cat /hive/db/empt/000001_0 7499,\N,\N,\N,\N,\N,\N,\N 7499,ALLEN,SALESMAN,7968,1980-12-17,1600.0,300,20 7566,JONES,MANAGER,7863,1980-12-17,2975.0,0,20 [root@hadoop logs]# hdfs dfs -cat /hive/db/empt/000002_0 7369,SMITH,CLERK,7902,1980-12-17,800.0,0,20

    2.3 sort by与distribute by 联合使用实现分区内有序

    Hive要求DISTRIBUTE BY语句要写在SORT BY语句之前。 set mapreduce.job.reduces=3; set hive.merge.mapredfiles=false; # 默认分区内升序,此处使用降序 insert overwrite table empt select * from empt distribute by empno sort by empno desc;

    [root@hadoop logs]# hdfs dfs -cat /hive/db/empt/000000_0 7566,JONES,MANAGER,7863,1980-12-17,2975.0,0,20 [root@hadoop logs]# hdfs dfs -cat /hive/db/empt/000001_0 7369,SMITH,CLERK,7902,1980-12-17,800.0,0,20 # 分区内降序 [root@hadoop logs]# hdfs dfs -cat /hive/db/empt/000002_0 7499,\N,\N,\N,\N,\N,\N,\N 7499,ALLEN,SALESMAN,7968,1980-12-17,1600.0,300,20 7451,\N,\N,\N,\N,\N,\N,\N

    3.cluster by

    3.1 cluster by 等价于 distribute by+ sort by(distribute和sort字段相同)

    distribute by empno sort by empno 等价于 cluster by empno distribute by empno sort by empno asc 等价于 cluster by empno set mapreduce.job.reduces=3; set hive.merge.mapredfiles=false; # cluster by 后面可以加cluster by empno desc.默认是升序 asc,如果要降序 与 distribute by empno sort by empno desc 模式相同效果 insert overwrite table empt select * from empt cluster by empno

    3.2 distribute by+sort by 比 cluster by 更加灵活

    例如:distribute by 字段和sort by 字段可以不一样 ,这里按照empno进行分区,按照ename进行分区内排序 set mapreduce.job.reduces=3; set hive.merge.mapredfiles=false; insert overwrite table empt select * from empt distribute by empno sort by ename desc;

    [root@hadoop logs]# hdfs dfs -cat /hive/db/empt/000000_0 7566,JONES,MANAGER,7863,1980-12-17,2975.0,0,20 [root@hadoop logs]# hdfs dfs -cat /hive/db/empt/000001_0 7369,SMITH,CLERK,7902,1980-12-17,800.0,0,20 # 通过ename降序 [root@hadoop logs]# hdfs dfs -cat /hive/db/empt/000002_0 7499,ALLEN,SALESMAN,7968,1980-12-17,1600.0,300,20 7499,\N,\N,\N,\N,\N,\N,\N 7451,\N,\N,\N,\N,\N,\N,\N

    4.order by

    4.1 全局排序的特点

    全局排序,默认升序,即使想开3个reduce,最终还是一个reduce,因为是全局排序,如果有多个输出文件实现不了全局排序. hive (default)> set mapreduce.job.reduces=3; hive (default)> set hive.merge.mapredfiles=false; hive (default)> insert overwrite table empt select * from empt order by empno;

    # 一个hdfs输出文件,默认升序 [root@hadoop logs]# hdfs dfs -cat /hive/db/empt/000000_0 7369,SMITH,CLERK,7902,1980-12-17,800.0,0,20 7499,ALLEN,SALESMAN,7968,1980-12-17,1600.0,300,20 7499,\N,\N,\N,\N,\N,\N,\N 7566,JONES,MANAGER,7863,1980-12-17,2975.0,0,20

    4.2 使用场景

    (1) 数据量不太大(如10G) 或 对处理后的结果数据(数据量不大) 进行全局排序,可直接使用order by (2) 在实际生产中,数据量很大(比如100G),如果直接使用order by,会导致只有一个reduce处理,这么大的数据,会出现很慢的情况。 比如对全世界60多亿人的年消费金额进行降序排序找出Top10,可以采用先sort by 在局部排序中找到前10 ,再进行order by 全局排序中找到前10.简单来说,全局排序中的Top10一定出自于局部排序中的Top10. select * from (select * from consumer sort by consumer_amount desc limit 10) a order by consumer_amount desc limit 10; 注意:生产中不要使用 * 进行模糊匹配,特别是hive中使用列式存储parquent等格式,会对性能造成极大影响。

    5.总结

    1. order by 全局排序 不能和distribute by 一起使用 2. sort by 局部排序,一般要和distribute by 一起使用,如果没有分桶那么就是全局排序 3. distribute by 对查询的结果进行分布,但不是排序 4. cluseter by 对查询的结果进行分布,然后每个桶内只能是按照自然序排序
    Processed: 0.010, SQL: 9