큰 파일을 정렬하는 방법?


35

2.80 GHz의 Intel® Pentium® CPU G640 및 8GB RAM이 장착 된 PC가 있습니다. EXT3 파일 시스템으로 Scientific Linux 6.5를 실행하고 있습니다.

이 설정에서 sort -u200 기가 바이트 파일 에서 가장 빠른 방법은 무엇 입니까?

파일을 더 작은 파일 (8GB보다 작은 파일) sort -u로 분할하고 함께 모은 다음 다른 크기로 sort -u다시 분할해야 합니까? 아니면 제한된 양의 RAM으로 파일을 처리 할 수있는 정렬 스크립트, 프로그램이 있습니까?


6
제발 편집 질문을하고 당신이 게시 명령을 시도 할 때 발생하는 설명합니다. 디스크 공간이 부족합니까? 에 충분한 여유 공간이있는 한 명령이 작동해야합니다 /tmp.
terdon


1
- 선택된 대답은 기본적으로 @terdon 말을하지만,이 하나의 체크 아웃되는 것을 말한다 stackoverflow.com/a/13025731/2801913을 . 일부 시스템에는 기본적으로 설치된 parallelmoreutils보다는 GNU가 필요 하다고 생각 parallel합니다.
Graeme

1
파일을 Amazon S3에 업로드 한 다음 수백 개의 노드로 Elastic Map Reduce 작업을 스핀 업하여 정렬 할 수 있습니다!
Alan Shutko

2
sort(1)공간이 부족할 수 있습니다 /tmp. 그렇다면 환경 변수를 사용하여 임시 파일을위한 다른 영역을 지정 TMPDIR하거나 플래그를 지정할 수 있습니다.-T=<tmpdir>
vonbrand

답변:


45

GNU sort(대부분의 Linux 시스템에서 기본값 임)에는 --parallel옵션이 있습니다. 에서 http://www.gnu.org/software/coreutils/manual/html_node/sort-invocation.html :

'-병렬 = n'

n과 병렬로 실행되는 정렬 수를 설정하십시오. 기본적으로 n은 사용 가능한 프로세서 수로 설정되지만 그 이후 성능이 저하되므로 8로 제한됩니다. 또한 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

또한 참고로 질은 더 빠른 알고리즘이 이미 큰 파일을 처리하도록 최적화로 분류 분해의 다른 어떤 방법보다 것 하나 GNU 정렬 명령을 사용하여 댓글을 달았습니다. 다른 것은 아마도 속도를 늦출 것입니다.


10
그리고 sort직접 통화하는 것이 다른 어떤 것보다 낫다 는 점에 유의해야 합니다. GNU 정렬은 RAM보다 훨씬 큰 파일에 잘 맞도록 설계되었습니다.
Gilles 'SO- 악마 그만해'

RH6.5 서버에서 --parallel sort 옵션이 작동하지 않습니다. Sort --version은 coreutils 8.4에서 나온 것으로 생각합니다. 병렬 버전에는 어떤 버전이 필요합니까?
markus_b

3
superuser.com/questions/938558/sort-parallel-isnt-parallelizing 도 참조하십시오 . 실제로 병렬화되지 않은 경우 -S512M과 같은 것을 지정해야 할 수도 있습니다.
unhammer

46

sort명령을 사용하는 것이 가장 빠른 옵션 일 것입니다.

그러나 로케일을 C로 수정하고 싶을 것입니다.

sort -u고유 한 행은보고하지 않지만 각 행 세트 중 하나는 동일하게 정렬됩니다. C 로케일에서 두 개의 다른 행이 반드시 같은 정렬을하지는 않지만 GNU 시스템의 대부분의 UTF-8 기반 로케일에서는 그렇지 않습니다.

또한 C 로케일을 사용하면 UTF-8을 구문 분석하고 복잡한 정렬 순서를 처리해야하는 오버 헤드를 피할 수 있으므로 성능이 크게 향상됩니다.

그래서:

LC_ALL=C sort -u file

임시 파일 (사용 -T또는 $TMPDIR환경 변수 사용)에 대해 더 빠른 드라이브 (또는 입력 및 / 또는 출력 파일이있는 것과 다른 드라이브)를 사용 하거나 -S일부 sort구현에서 지원 하는 옵션 을 사용하여 성능을 향상시킬 수도 있습니다. .

일부 유형의 입력 또는 느린 스토리지의 경우, --compress-programGNU 옵션 sort(예 :) lzop을 사용하면 스토리지 사용 외에도 성능이 향상 될 수 있습니다.


이제는 올바른 순서가 아니라는 것을 반대하는 사람들에게 (어느 정도는)주의 하십시오 .

나는 인간으로, 내가보고 싶은 것에 동의 스테판를 일종의 사이에 스테판스테파니 ,하지만 :

  • 컴퓨터 싶은 스테판을 보낸 후 일종의 é문자 또는 (코드 포인트 또는 바이트 값의 측면에서) 후의 UTF-8 인코딩 종류의 바이트로 (최소 U + 00E9으로 표현 될 때). 그것은 구현하기가 매우 간단하고 엄격한 총 주문 이며 놀라운 것은 아닙니다.
  • 로케일의 정렬 순서는 많은 경우 인간에게도 만족스럽지 않을 것입니다. 예를 들어 기본 en_GB.utf8 로케일이있는 시스템의 경우 :

    • StéphaneStéphane (하나는 U + 00E9, 다른 하나는 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

1
예. LC_ALL은 250000 줄로 파일을 정렬하면 속도가 8 배 빨라집니다.
Jan Vlcinsky

-1

여기 GB 램의 부부와 함께 정기적으로 컴퓨터에서 테라 바이트 규모의 데이터를 정렬 bash는 스크립트를 사용하기 준비 : http://sgolconda.blogspot.com/2015/11/sort-very-large-dataset.html 이 수를 확인 머신을 코어로 사용하고 모든 코어를 사용합니다. 숫자 또는 문자열 파일을 정렬 할 수 있습니다. TB 스케일 데이터에서 고유 레코드를 찾는 데 사용할 수 있습니다.


이것은 좋은 제안이 아닙니다. 이 스크립트는 엄청나게 부풀어 오르고 입력 파일을 분할하여 GNU 정렬에 허용되는 대답이 필요하지 않은 부분을 정렬합니다.
Thorbjørn Ravn Andersen
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.