海量数据排序——如果有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效率)等。
海量数据排序——如果有1TB的数据需要排序,但只有32GB的内存如何排序处理?的更多相关文章
- sql 排序函数ROW_NUMBER分页返回数据
分页从数据库返回一张表的某些条数据 假设我需要查询 系统表 sys.all_columns中的数据,每次查询10条 第一次查询第1-10条数据 第二次查询第11-20条数据 第三次查询第21-30条数 ...
- java学习-排序及加密签名时数据排序方式
排序有两种 1. 类实现comparable接口调用List.sort(null)或Collections.sort(List<T>)方法进行排序 jdk内置的基本类型包装类等都实现了Co ...
- Java:集合,对列表(List)中的数据(整型、字符串、日期等)进行排序(正序、倒序)的方法;字符串按照整型排序的方法
1. 要求 对List列表中的数据进行排序(正序.倒序),列表中的数据包括:整型(Integer).字符串(String).日期(Date)等.对于字符串,要求允许对它按照整型进行排序. 2. 实现思 ...
- c# 对List<T> 某字段排序,取TOP条数据
//排序的对象里的字段数据准备 try { cmr.v4 = Double.Parse(cmr.v3) - Double.Parse(cmr.v2); } catch (Exception e) { ...
- 使用Python在2M内存中排序一百万个32位整数
译言网 | 使用Python在2M内存中排序一百万个32位整数 使用Python在2M内存中排序一百万个32位整数 译者:小鼠 发表时间:2008-11-13浏览量:6757评论数:2挑错数:0 作者 ...
- 《剑指Offer》第1题(Java实现):在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
一.题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该 ...
- 实现把dgv里的数据完整的复制到一张内存表
/// <summary> /// 方法实现把dgv里的数据完整的复制到一张内存表 /// </summary> /// <param name="dgv&qu ...
- 史林枫:sqlserver数据库中数据日志的压缩及sqlserver占用内存管理设置
使用sqlserver和IIS开发.net B/S程序时,数据量逐渐增多,用户也逐渐增多,那么服务器的稳定性就需要维护了.数据库如何占用更小内存,无用的日志如何瞬间清空? 今天在给一个客户维护网站的时 ...
- CPU缓存是位于CPU与内存之间的临时数据交换器,它的容量比内存小的多但是交换速度却比内存要快得多。CPU缓存一般直接跟CPU芯片集成或位于主板总线互连的独立芯片上
一.什么是CPU缓存 1. CPU缓存的来历 众所周知,CPU是计算机的大脑,它负责执行程序的指令,而内存负责存数据, 包括程序自身的数据.在很多年前,CPU的频率与内存总线的频率在同一层面上.内存的 ...
随机推荐
- WPF实例,以getFiles()获取文件夹,treeview的应用
读取电脑硬盘根目录添加到TreeView控件 foreach (DriveInfo item in System.IO.DriveInfo.GetDrives()) { if(item.ToStrin ...
- 洛谷1578:[WC2002]奶牛浴场——题解
https://www.luogu.org/problemnew/show/P1578#sub 由于John建造了牛场围栏,激起了奶牛的愤怒,奶牛的产奶量急剧减少.为了讨好奶牛,John决定在牛场中建 ...
- BZOJ2006 [NOI2010]超级钢琴 【堆 + RMQ】
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 552 MB Submit: 3446 Solved: 1692 [Submit][Sta ...
- 解决jsp两种提交方式乱码 的方法
解决中文乱码 ---post提交方式 需要在处理页面添加request.setCharacterEncoding("utf-8"); 制定请求的编码,调用一下request.ge ...
- bzoj2431: [HAOI2009]逆序对数列(DP)
f[i][j]前i个数有j个逆序对的数量 f[i][j]=sigma(f[i-1][j-k]){1<=k<=i} 维护一个前缀和即可 #include<iostream> #i ...
- JQuery仿淘宝滚动加载图片
用 JQuery 制作随着显示页面的滚动条的滚动动态加载图片,适用于图片太多的页面,在访问网页时,可以先只加载第一屏要显示的图片,当用户进行向下滚动查看页面的时候,动态去加载这些图片,好处是减少页面第 ...
- navicat for mysql无法连接数据库和连接数据库慢的问题
首先在自己虚拟机上登录mysql: mysql -uroot -p 然后赋予权限 GRANT ALL PRIVILEGES ON *.* TO root@'%' IDENTIFIED BY '1234 ...
- Codeforces Round #392 (Div. 2) A B C 水 模拟 暴力
A. Holiday Of Equality time limit per test 1 second memory limit per test 256 megabytes input standa ...
- [ 转载]Tomcat7 catalina.out 日志分割
http://m.blog.csdn.net/blog/mark_qi/8864644 最近由于工作需要,tomcat 的catalina.out文件的不断扩大,导致系统磁盘空间边变小,而且管理也难于 ...
- bzoj1529 [POI2005]ska Piggy banks 并查集
[POI2005]ska Piggy banks Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1508 Solved: 763[Submit][Sta ...