最近好像在搞一个高级的东西
最近入职了新公司,分享一些在工作中遇到的技术问题。
我们先了解一下 ODPS 提供的几种关于数据的排序方法。
order by:全局排序
order by 会对数据进行一次全局排序,所以说,只要ODPS的sql中指定了order by,那么所有的数据都会到同一个reducer进行处理(不管有多少map,也不管文件有多少的block只会启动一个reducer)。order by 只在一个reduce中进行,所以数据量特别大的时候效率非常低。建议在小的数据集中使用order by进行排序 即使设置了的值大于1, 使用order by,时ODPS在运行MR程序时也会设置为1覆盖 SET odps.sql.reducer.instances = 20; --仍然不会生效。
sort by:局部排序
sort by在每个reducer端都会做排序,为每个reduce产生一个排序文件。也就是说sort by能保证局部有序(每个reducer出来的数据是有序的,但是不能保证所有的数据是有序的,除非只有一个reducer)。使用sort by的好处是:执行了局部排序之后可以为接下去的全局排序提高不少的效率(其实就是做一次归并排序就可以做到全局排序了)。sort by 的数据在进入reduce前就完成排序。
distribute by:数据分发
distribute by是控制在map端如何拆分数据给reduce端的。hive会根据distribute by后面列,对应reduce的个数进行分发,默认是采用hash算法。sort by为每个reduce产生一个排序文件。在有些情况下,你需要控制某个特定行应该到哪个reducer,这通常是为了进行后续的聚集操作。distribute by刚好可以做这件事。因此,distribute by经常和sort by配合使用。
cluster by :
可以理解为distribute by + sort by 某个特定字段。但是排序只能是倒序排序,不能指定排序规则为asc 或者desc。
注意点:
● 使用distribute by的时候要注意热点问题。(如果字段对应字段分配reducer数量效果不均,会有长尾问题) ● 一般来说distribute by 只用指定一个字段即可,指定重复值越多的字段压缩率越高。● sort by 可以指定多个字段,但是要注意计算性能,指定重复值越多的字段压缩越高。● 比较常见的情况,如果有多个时间相关字段,可能重排的效果会打折扣甚至导致压缩负效果,因为一般日志都是按时间顺序排,重排会打乱时间字段。● 平均字段长度,唯一值个数是两个关键的参考值。sort by 优先选择重复值较多且字段平均长度长的,压缩效果会好一些。
总结
提供这几种排序方法有什么用呢?
也就是数据重排,就是根据数据的特征把具有相同列值字段通过排序放在一块,以提高压缩率。
为什么重排可以提高压缩率,因为在默认情况下,数据是按照写入时间顺序存储的,这样物理上相邻的数据其实相似性并不高。在列存储场景下,相邻数据越相似,压缩率越高。
其原理可以参照行程编码(RLC):主要技术是检测重复的比特或字符序列,并用它们的出现次数取而代之。