大数据面试-排序

对一个很大的整数数组进行排序

简单分治

通常遇到很大的整数数组,都是不能直接放入道内存中的。比较直观的思路是借鉴归并排序的方式分而治之。将数组进行切分,直到数组的大小是可以接受的范围。我们对数组直接进行排序,然后再一步一步的回退进行合并。

但是这种方式,在最后的合并阶段,通常还是需要把大量的数值读入道内存中进行比较的。且这种全局有序性的排序(order by)最后都会把任务丢到一个节点上去做合并,该节点压力会很大。因此这种方式一般不被采用。

如何优化

还是回到分治的思路上,没法子太大了只能拆分。如果我们确保分区之间也是有序的,就可以简单化后续的合并(partition0 > partition1 > partition2 ......)。那么我们如何对数组进行分组呢?

如果我们采用hash的方式进行分区,可能会带来两个问题:破坏了分区间的有序性和可能会发生数据倾斜。

分区间有序

为了实现分区间有序,我们需要指定分区间的barrier,在barrier之中的,才被分到该分区。例如:[0-10000),[10000-20000)....采用这样的方式我们可以保证对所有分区排序完成后,分区之间也是有序的,即我们简单拼接便可以完成整体排序。但是这样划分无法避免数据倾斜的问题。

均分数据

提到数据倾斜,肯定就有小伙伴说这就好办了,增加随机前缀或者后缀,然后重新散列就行了。但是在这里是不可以的,因为前缀或后缀会破坏分区间的有序性。注意,当我们分区完成后,在排序之前,分区中的数据也是无序的。这样我们无法对该倾斜分区在保证分区间有序的前提下进行再拆分。这时候我们应该怎么办呢?

最后的方案

其实我们的目标就是让我们的数据尽可能的均分在分区之中,我们可以通过调整barrier的范围来完成。例如我们在10000-15000的数据量比较大,我们可以调整barrier到[0-80000),[80000-120000),[120000,160000)...从而将数据尽可能的均分。如果我们知道了大致的数据分布,我们就可以较好的处理划分的问题。所以我们可以先对数据进行采样,然后我们对采样的数据进行排序,再根据采样的结果来作为我们划分barrier的依据。通过这种办法我们可以较好的避免数据倾斜。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值