文章目录
前段时间,因为项目原因,了解了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,既可以生成多个文件,又可以保证数据局部有序且连贯。
连贯的意思是:假设我看一个学校的学生的成绩,重点关注专业。当人为或使用其他办法(标准是:固定的大小或条数分开保存)分片保存数据时,就会出现某专业的学生出现在多个文件中,对查看数据很不友好。