大きなファイルをソートするには?


35

Intel(R)Pentium(R)CPU G640 @ 2.80 GHzおよび8 GBのRAMを搭載したPCがあります。EXT3ファイルシステムを使用してScientific Linux 6.5を実行しています。

このセットアップでsort -u、200ギガバイトのファイルでできる最速の方法は何ですか?

ファイルを小さなファイル(8 GB未満)にsort -u分割し、それらをまとめてから、別のサイズにsort -u再度分割するなどの必要がありますか?または、ソートスクリプト、限られた量のRAMでこれほど大きなファイルを処理できるプログラムはありますか?


6
質問を編集して、投稿したコマンドを試すとどうなるかを説明してください。ディスク容量が不足していますか?コマンドは、十分な空き領域がある限り機能します/tmp
テルドン


1
選択した答えは、基本的に@terdonが言っていると言うが、また、この1つをチェック- stackoverflow.com/a/13025731/2801913。一部のシステムにはデフォルトでインストールされるparallelmoreutilsではなく、これのためにGNUが必要になりparallelます。
グレアム14年

1
ファイルをAmazon S3にアップロードし、数百のノードでElastic Map Reduceジョブをスピンアップしてソートできます。
アランシュトコ14年

2
sort(1)上のスペースが不足する可能性があります/tmp。もしそうなら、あなたは環境変数を使用した一時ファイルの別の領域を指定することができTMPDIR、またはフラグ-T=<tmpdir>
vonbrand

回答:


46

GNU sort(ほとんどのLinuxシステムのデフォルト)には--parallelオプションがあります。http://www.gnu.org/software/coreutils/manual/html_node/sort-invocation.htmlから:

'--parallel = n'

並行して実行されるソートの数をnに設定します。デフォルトでは、nは使用可能なプロセッサーの数に設定されますが、その後はパフォーマンスが低下するため、8に制限されます。また、n個のスレッドを使用すると、メモリnがlog n倍増加することに注意してください。nprocの呼び出しも参照してください。

CPUには2つのコアがあるため、次のことができます。

sort --parallel=2 -uo list-sorted.txt list.txt

プロセッサのハイパースレッディングが原因でより多くのコアがあるように見える場合があるため、実際のコア数を指定することをお勧めします。

niceプロセッサのスケジューリング優先度ioniceに影響を与えたり、I / Oスケジューリングに影響を与えたりするために実験することもできます。このような他のプロセスよりも優先順位を上げることができます。通常、バックグラウンドプロセスがリソースを過剰に使用しないようにするのに優れているため、これが大きな節約になるとは思いません。それでも、次のようなものと組み合わせることができます:

nice -n -20 ionice -c2 -n7 sort --parallel=2 -uo list-sorted.txt list.txt

また、Gillesがコメントしたように、単一のGNUソートコマンドを使用することは、アルゴリズムが既に大きなファイルを処理するように最適化されているため、ソートを分解する他の方法よりも高速になることに注意してください。それ以外の場合は、おそらく速度が低下します。


10
そして、あなたはsort直接呼び出すことは、あなたが石畳することができる何よりも優れていることに注意すべきです。GNUソートは、RAMよりもはるかに大きいファイルにうまく対処できるように設計されています。
ジル 'SO-悪であるのをやめる' 14年

RH6.5サーバーでは--parallel sortオプションが機能しません。Sort --versionは、coreutils 8.4から出てきたと考えています。並列バージョンにはどのバージョンが必要ですか?
-markus_b

3
superuser.com/questions/938558/sort-parallel-isnt-parallelizingも参照してください。実際に並列化されていないことに気付いた場合は、-S512Mのようなものを指定する必要があります。
アンハンマー

46

sortコマンドを使用するのがおそらく最速のオプションです。

ただし、おそらくロケールをCに修正する必要があります。

sort -uは一意の行を報告しませんが、同じように並べ替える各行セットの1つを報告します。Cロケールでは、2つの異なる行は必ずしも同じようにソートされませんが、GNUシステム上のほとんどのUTF-8ベースのロケールではそうではありません。

また、Cロケールを使用すると、UTF-8を解析して複雑なソート順を処理するオーバーヘッドが回避されるため、パフォーマンスが大幅に向上します。

そう:

LC_ALL=C sort -u file

また、一時ファイル(使用-Tまたは$TMPDIR環境変数)に高速ドライブ(または入力ファイルや出力ファイルがあるドライブとは異なるドライブ)を使用するか-S、一部のsort実装でサポートされているオプションをいじることにより、パフォーマンスを向上させることができます) 。

あるタイプの入力または低速ストレージの--compress-program場合、GNU のオプションsort(たとえばwith lzop)を使用すると、ストレージの使用に加えてパフォーマンスが向上する場合があります。


、正しい順序ではないという異議を唱えるための(ある程度)正しい注意

私は人間として、私が見てみたいことに同意ステファンをソート間にステファンステファニー、しかし:

  • コンピュータはたいステファンのための後ソートするé文字または(コードポイントまたはバイト値で)後のUTF-8エンコーディングの種類のバイトとして(少なくともU + 00E9として発現された場合)。これは、実装が非常に簡単な並べ替え順序であり、厳密な合計順序であり、当然のことです。
  • あなたのロケールのソート順は、多くの場合、人間にとっても満足できるものではないでしょう。たとえば、デフォルトのen_GB.utf8ロケールを使用しているシステムの場合:

    • StéphaneStéphane(1つはU + 00E9、もう1つはeU + 0301)は同じ並べ替えを行いません:

      $ printf '%b\n' 'Ste\u0301phane' 'St\u00e9phane' | sort -u
      Stéphane
      Stéphane
      
    • しかし、③、①、②はすべて同じようにソートされます(明らかにこれらのロケール定義のバグ)。

      $ printf '%s\n' ③ ① ② | sort -u
      ③
      

      ここでは、③ですが、同様に①または②である可能性があります

IMOのsort -u場合、一意の行が必要な場合は、LC_ALL = Cで常に必要になる可能性があります。そして、その結果のリストをユーザーのソート順でソートしたい場合は、sort再びパイプします:

LC_ALL=C sort -u | sort

LC_ALL=C sort | LC_ALL=C uniq -c | sort -k2

8
ロケールを設定するための+1:パフォーマンスに大きな影響を与える可能性があります
Adrian Pronk 14年

1
はい。250000行のファイルをソートすると、LC_ALLは物事を8倍高速化します。
ヤンヴルチンスキー

-1

ここではGBのRAMのカップルと定期的にマシンのTBスケールのデータをソートするためのbashスクリプトを使用する準備ができている: http://sgolconda.blogspot.com/2015/11/sort-very-large-dataset.html それは数をチェックマシンをコアとして使用し、すべてのコアを使用します。数値ファイルまたは文字列ファイルをソートできます。TBスケールデータで一意のレコードを検索するために使用できます。


これは良い提案ではありません。このスクリプトは非常に肥大化しており、入力ファイルを分割して、受け入れられた回答がGNUソートでは不要であると指摘した部分をソートします。
するThorbjörnRavnアンデルセン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.