轉載: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效率)等。