hive中,cluster by为什么会出现?有什么意义?有什么用处?有什么应用场景?


      
      前段时间,因为项目原因,了解了cluster by,顺路写了一篇博客: HIVE中,cluster by有什么意义。然后底下有人回复: 假如100个专业分了10个区,那么每一个区里都应该会有不同的专业。但反过来说,真正的mr 并没有完全按专业分区,如果完全的话那应该是100个区。问题是结果只有10个区,这么做意义的结果总结一下应该是:cluster by 的字段只是参考分区字段,而非严格的按此字段分区。是不是这样?求回复评价。 本想在评论下面回复,但是越写越乱,所以又写了一篇博客。

      首先,先说明一个误区,不要用cluster by 和 group by去作比较,要做比较也应该是和order by作比较。cluster by的分区 和 group by 的分区完全是两码事。
      

为什么会出现cluster by?

      cluster by是hive中的,mysql等数据库中是没有的,为什么hive会出现cluster by呢?

order by

      当需要对数据排序时,我们可以使用order by。但使用order by意味着对所有数据进行排序,即:无论有多少个map,无论有多少数据量,都只用一个reduce。这会消耗极大的时间,且数据量大时,对资源消耗也极为巨大。
      这种情况肯定是不能忍受的,但又没有什么好的解决办法,退而求其次,不要求全局有序,只要求局部有序,也是一种解决办法。于是:sort by出现了。

sort by

       使用sort by时,会有多个reduce。每个reduce端都会进行排序,但这时,每个reduce的数据是有序的,但数据全局上看依然是无序的。也就是局部有序,整体无序。

distribute by

       使用sort by时,数据是局部有序,整体无序。但这时候,哪些数据进入同一个reduce是随机的,不可把控的。所以可以使用 distribute by 来指定哪些数据进入同一个reduce。
       也就是说,我们可以指定哪些数据进入到同一个reduce中,然后这些数据进行排序。

cluster by

       等价于 distribute by + sort by

举个例子

       举个栗子:某学校对学生成绩进行排序。

select * from t_score order by grade
-- 因为使用了order by,只有一个reduce。 

distribute by 、 sort by

       假设学生太多,数据太多,无法使用order by进行全局排序

      这时候我们可以要求学生的成绩按照专业进行排序,不要求在全校内排序。即:

select * from t_score 
distribute by major sort by grade
-- 因为没有使用order by,所以这时可以有多个reduce。 

      但是,如果reduce的数量小于专业的数量,就会有多个专业在一个reduce中处理的情况,这时候,如果还是distribute by major sort by grade,就会乱序。即:多个专业分到一个区,且直接按照分数排序。
      对于这种情况,我们需要先按照专业排序,再按照分数排序。

select * from t_score 
distribute by major sort by major, grade
-- 因为没有使用order by,所以这时可以有多个reduce。 

其它写法

      在我印象里,之前是支持这种写法的:

select * from t_score 
cluster by major sort by grade

      但是刚才试了一下(2.几版本的hive),不支持这种写法。

疑问解答

      那位同学回复的内容是:假如100个专业分了10个区,那么每一个区里都应该会有不同的专业。但反过来说,真正的mr 并没有完全按专业分区,如果完全的话那应该是100个区。问题是结果只有10个区,这么做意义的结果总结一下应该是:cluster by 的字段只是参考分区字段,而非严格的按此字段分区。是不是这样?求回复评价。
      首先,假如100个专业分了10个区,那么每一个区里都应该会有不同的专业。但反过来说,真正的mr 并没有完全按专业分区,如果完全的话那应该是100个区。问题是结果只有10个区,这些说的都对。最后的问题是:cluster by 的字段只是参考分区字段,而非严格的按此字段分区。是不是这样?
      我认为不是的,cluster by是严格按照字段区分的,100个专业分了100个区,问题是你只有10个reduce,所以才会出现一个区里有不同的专业。 分区规则是根据分区字段的hash码与reduce的个数进行模除后,余数相同的分到一个区。

举个栗子

      因为在比较新的hive里执行
select * from t_score cluster by major sort by grade时,确报错。有点强迫症的我便想再举一个只用cluster by的栗子,然而想了半天愣是想不出来。按照字段分区,且只按照该字段排序,我确实想不出来有什么意义。
      再经过百度、问别人、想想之后,我想出了一个应用场景,或者说有什么作用。

解决数据倾斜

      distribute by可以实现打乱数据从而解决数据倾斜的效果,但是解决以后数据是无序的,使用cluster by可以在解决数据倾斜的效果之上实现局部有序。

方便查看输出文件

      hive可以将查询结果保存到hdfs上,数据量太大且只有一个文件时,查看和传输都很不方便。如果按照固定的大小或条数分开保存,又会出现数据不连贯的情况。
      这时候,使用cluster by,既可以生成多个文件,又可以保证数据局部有序且连贯。
      连贯的意思是:假设我看一个学校的学生的成绩,重点关注专业。当人为或使用其他办法(标准是:固定的大小或条数分开保存)分片保存数据时,就会出现某专业的学生出现在多个文件中,对查看数据很不友好。
      


版权声明:本文为weixin_42845682原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。