¿Cómo ordenar archivos grandes?


35

Tengo una PC con Intel (R) Pentium (R) CPU G640 @ 2.80 GHz y 8 GB de RAM. Estoy ejecutando Scientific Linux 6.5 con el sistema de archivos EXT3.

En esta configuración, ¿cuál es la forma más rápida que puedo hacer sort -uen un archivo de 200 gigabytes?

¿Debería dividir el archivo en archivos más pequeños (más pequeños que 8 GB), sort -ujuntarlos y luego dividirlos nuevamente en un tamaño diferente, sort -unuevamente, etc.? ¿O hay algún script de clasificación, programas que puedan manejar archivos tan grandes con mi cantidad limitada de RAM?


66
Por favor, editar su pregunta y explicar lo que sucede cuando se intenta el comando informados. ¿Te quedas sin espacio en disco? El comando debería funcionar siempre que tenga suficiente espacio libre en su /tmp.
terdon


1
La respuesta elegida básicamente dice lo que dice @terdon, pero también echa un vistazo a esta: stackoverflow.com/a/13025731/2801913 . Necesitará GNU parallelpara esto, creo, en lugar de las más utilidades parallelque se instalan por defecto en algunos sistemas.
Graeme

1
¡Puede cargar el archivo en Amazon S3, luego girar un trabajo de Elastic Map Reduce con unos cientos de nodos para ordenarlo!
Alan Shutko

2
sort(1)podría quedarse sin espacio en /tmp; si es así, puede designar otra área para archivos temporales con la variable de entorno TMPDIR, o marcar-T=<tmpdir>
vonbrand

Respuestas:


46

GNU sort(que es el predeterminado en la mayoría de los sistemas Linux), tiene una --parallelopción. De http://www.gnu.org/software/coreutils/manual/html_node/sort-invocation.html :

'--paralelo = n'

Establezca el número de clases ejecutadas en paralelo a n. De forma predeterminada, n está configurado para el número de procesadores disponibles, pero limitado a 8, ya que hay ganancias de rendimiento decrecientes después de eso. Tenga en cuenta también que el uso de n subprocesos aumenta el uso de memoria en un factor de log n. Ver también invocación nproc.

Como su CPU tiene 2 núcleos, puede hacer:

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

Es mejor especificar el número real de núcleos, ya que puede parecer que hay más debido a que el procesador tiene hiperprocesamiento .

También puede experimentar nicepara influir en la prioridad de programación del procesador e ioniceinfluir en la programación de E / S. Puede aumentar la prioridad sobre otros procesos como este, no creo que esto le brinde grandes ahorros, ya que generalmente son mejores para asegurarse de que un proceso en segundo plano no use demasiados recursos. Sin embargo, puede combinarlos con algo como:

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

Tenga en cuenta también que, como comentó Gilles , usar un solo comando de clasificación GNU será más rápido que cualquier otro método para desglosar la clasificación ya que el algoritmo ya está optimizado para manejar archivos grandes. Cualquier otra cosa probablemente ralentizará las cosas.


10
Y debe tener en cuenta que llamar sortdirectamente es mejor que cualquier otra cosa que pueda improvisar. GNU sort está diseñado para hacer frente a archivos que son mucho más grandes que la RAM.
Gilles 'SO- deja de ser malvado'

La opción --parallel sort no funciona en mis servidores RH6.5. Ordenar --version piensa que proviene de coreutils 8.4. ¿Qué versión necesito para la versión paralela?
markus_b 01 de

3
Consulte también superuser.com/questions/938558/sort-parallel-isnt-parallelizing : puede que tenga que especificar algo como -S512M si observa que no está realmente en paralelo.
Martillo

46

Usar el sortcomando probablemente será la opción más rápida.

Pero probablemente querrás arreglar la configuración regional en C.

sort -uno informa líneas únicas, sino una de cada conjunto de líneas que las clasifican de la misma manera. En la configuración regional C, 2 líneas diferentes no necesariamente ordenan lo mismo, pero ese no es el caso en la mayoría de las configuraciones regionales basadas en UTF-8 en sistemas GNU.

Además, el uso de la configuración regional C evita la sobrecarga de tener que analizar UTF-8 y procesar órdenes de clasificación complejas, por lo que mejoraría drásticamente el rendimiento.

Asi que:

LC_ALL=C sort -u file

También puede mejorar el rendimiento utilizando una unidad más rápida (o una unidad diferente de aquella en la que se encuentran los archivos de entrada y / o salida) para los archivos temporales (usando -To $TMPDIRvariable de entorno), o jugando con la -Sopción admitida por algunas sortimplementaciones) .

Para algún tipo de entrada o para almacenamiento lento, el uso de la --compress-programopción de GNU sort(por ejemplo con lzop) podría mejorar el rendimiento además del uso de almacenamiento.


Ahora solo una nota para aquellos que objetan (con razón hasta cierto punto) que no será el orden correcto :

Estoy de acuerdo en que, como humano, me gustaría ver a Stéphane clasificarse entre Stefan y Stephanie , pero:

  • Una computadora querría que Stéphaneé clasifique después desde (al menos cuando se expresa como U + 00E9) como un carácter o los bytes de su codificación UTF-8 después (en términos de punto de código o valor de byte). Es un orden de clasificación que es muy simple de implementar y es un orden total estricto y no tiene sorpresa.
  • El orden de clasificación de su localidad probablemente no sea satisfactorio en muchos casos, incluso para un humano. Por ejemplo, en mi sistema con la configuración regional predeterminada en_GB.utf8:

    • Stéphane y Stéphane (uno con U + 00E9, el otro con eU + 0301) no ordenan lo mismo:

      $ printf '%b\n' 'Ste\u0301phane' 'St\u00e9phane' | sort -u
      Stéphane
      Stéphane
      
    • pero ③, ①, ② todos ordenan lo mismo (obviamente un error en esas definiciones locales):

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

      Aquí, es ③, pero bien podría haber sido ① o ②

Entonces, en mi opinión, es probable que siempre desee sort -ucon LC_ALL = C, si desea líneas únicas. Y si desea que la lista resultante se ordene en el orden de clasificación del usuario, sortvuelva a canalizarla :

LC_ALL=C sort -u | sort

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

8
+1 para establecer la configuración regional: puede tener un gran efecto en el rendimiento
Adrian Pronk

1
Sí. ordenando el archivo con 250000 líneas, el LC_ALL acelera las cosas 8 veces.
Jan Vlcinsky

-1

Aquí hay un script bash listo para usar para ordenar los datos de escala de TB en una máquina normal con un par de RAM de RAM: http://sgolconda.blogspot.com/2015/11/sort-very-large-dataset.html Comprueba el número de núcleo de su máquina como y utiliza todos los núcleos. Puede ordenar archivos numéricos o de cadena. Se puede utilizar para buscar registros únicos en datos de escala TB.


Esta no es una buena sugerencia. El script está inmensamente hinchado y divide el archivo de entrada para ordenar las partes que la respuesta aceptada señala que no es necesario con GNU sort.
Thorbjørn Ravn Andersen
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.