海量数据处理中一类常见的问题就是排序问题,即对海量数据中的数据进行排序,例如,一个文件中有9亿条不重复的9位整数,对这个文件中数字进行排序。
针对这个问题,最容易想到的方法是将所有数据导入到内存中,然后使用常规的排序方法,例如插入排序、快速排序、归并排序等各种排序方法对数据进行排序,最后将排序好的数据存入文件。但这些方法却不能在此适用,由于数据量巨大,在32位机器中,一个整数占用4个字节,而9亿条数据以供占用9亿* 4byte,大约需要占用3.6G内存,对于32位机器而言,很难将这么多数据一次载入到内存,更不谈进行排序了,所以此种方法一般不可行,需要考虑其它方法。
方法一,数据库排序法。将文本文件导入到数据库中,让数据库进行索引排序操作后提取数据到文件。该种方法岁半操作简单、方便,但是运算速度较慢,而且对数据库设备要求比较高。
方法二,分治法。通过hash将9亿条数据分为20段,每段大约5000万条,大约占用500万*4byte=200M空间,在文件中依次搜索0~5000万,50000001~1亿……将排序的结果存入文件。该方法要装满9位整数,一共需要20次,所以一共要进行20次排序,需要对文件进行20次读操作。该方法虽然缩小了每次使用的内存空间大小,但是编码复杂,速度也慢。
方案三,位图法。考虑到最大的9位整数为999999999,由于9亿条数据是不重复的,可以把这些数据组成一个队列或数组,让它有0~999999999(一共10亿个数)元素数组下标表示数值,结点中用0表示没有这个数,1表示存在这个数,判断0或1只用一个bit存储就够了,而声明一个可以包含9位整数的bit数组,一共需要10亿/8,大约120M内存,把内存中的数据全部初始化为0 ,读取文件中的数据,并将数据放入内存。比如读到一个数据为341245909这个数据,那就先在内存中找到341245909这个bit,并将bit值置为1 ,遍历整个bit数组,将bit为1的数组下标存入文件,最终得到排序后的内容。
此类排序问题的求解方法一般都是采用上述方法。而海量数据处理中与此类似的问题还有如下几种:
(1) 一年的全国高考考生人数为500万,分数使用标准分,最低100分,最高900分,不存在成绩为小数的情况,把这500 万考生的分数排序。
(2) 一个包含n个正整数的文件,每个正整数小于n,n等于1000万,并且文件内的正整数没有重复和关联数据,输出整数的升序排列。
原文地址:http://www.jobcoding.com/big-data/sort-problem/