zoukankan      html  css  js  c++  java
  • 海量数据排序——如果有1TB的数据需要排序,但只有32GB的内存如何排序处理?

    转载:https://blog.csdn.net/fx677588/article/details/72471357

    1、外排序 
      传统的排序算法一般指内排序算法,针对的是数据可以一次全部载入内存中的情况。但是面对海量数据,即数据不可能一次全部载入内存,需要用到外排序的方法。外排序采用分块的方法(分而治之),首先将数据分块,对块内数据按选择一种高效的内排序策略进行排序。然后采用归并排序的思想对于所有的块进行排序,得到所有数据的一个有序序列。

      例如,考虑一个1G文件,可用内存100M的排序方法。首先将文件分成10个100M,并依次载入内存中进行排序,最后结果存入硬盘。得到的是10个分别排序的文件。接着从每个文件载入9M的数据到输入缓存区,输出缓存区大小为10M。对输入缓存区的数据进行归并排序,输出缓存区写满之后写在硬盘上,缓存区清空继续写接下来的数据。对于输入缓存区,当一个块的9M数据全部使用完,载入该块接下来的9M数据,一直到所有的9个块的所有数据都已经被载入到内存中被处理过。最后我们得到的是一个1G的排序好的存在硬盘上的文件。

    2、1TB数据使用32GB内存如何排序 
      ①、把磁盘上的1TB数据分割为40块(chunks),每份25GB。(注意,要留一些系统空间!) 
      ②、顺序将每份25GB数据读入内存,使用quick sort算法排序。 
      ③、把排序好的数据(也是25GB)存放回磁盘。 
      ④、循环40次,现在,所有的40个块都已经各自排序了。(剩下的工作就是如何把它们合并排序!) 
      ⑤、从40个块中分别读取25G/40=0.625G入内存(40 input buffers)。 
      ⑥、执行40路合并,并将合并结果临时存储于2GB 基于内存的输出缓冲区中。当缓冲区写满2GB时,写入硬盘上最终文件,并清空输出缓冲区;当40个输入缓冲区中任何一个处理完毕时,写入该缓冲区所对应的块中的下一个0.625GB,直到全部处理完成。

    3、继续优化 
      磁盘I/O通常是越少越好(最好完全没有),那么如何降低磁盘I/O操作呢?关键就在第5和第6步中的40路输入缓冲区,我们可以先做8路merge sort,把每8个块合并为1路,然后再做5-to-1的合并操作。 
      再深入思考一下,如果有多余的硬件,如何继续优化呢?有三个方向可以考虑: 
      使用并发:如多磁盘(并发I/O提高)、多线程、使用异步I/O、使用多台主机集群计算。 
      提升硬件性能:如更大内存、更高RPM的磁盘、升级为SSD、Flash、使用更多核的CPU。 
      提高软件性能:比如采用radix sort、压缩文件(提高I/O效率)等。

  • 相关阅读:
    123我爱你
    cs231n学习笔记(一)计算机视觉及其发展史
    Problem B: 字符串类(II)
    Problem A: 字符串类(I)
    Problem E: 新奇的加法运算
    Problem D: 判断两个圆之间的关系
    Problem C: 质心算法
    Problem B: 我们来做个Student类吧!
    Problem A: 克隆人来了!
    Problem H: STL——表达式求值
  • 原文地址:https://www.cnblogs.com/scu-cjx/p/8628916.html
Copyright © 2011-2022 走看看