web-dev-qa-db-fra.com

Comment la commande UNIX sort peut-elle trier un très gros fichier?

La commande UNIX sort peut trier un très gros fichier comme ceci:

sort large_file

Comment l'algorithme de tri est-il implémenté?

Comment se fait-il qu'il ne provoque pas une consommation excessive de mémoire?

96
yjfuk

Détails algorithmiques de la commande UNIX Sort indique que Unix Sort utilise un algorithme de tri de fusion R-Way externe. Le lien entre dans plus de détails, mais en substance, il divise l'entrée en plus petites portions (qui tiennent dans la mémoire), puis fusionne chaque partie à la fin.

106
Matthew

La commande sort stocke les données de travail dans des fichiers disque temporaires (généralement dans /tmp).

42
grawity

AVERTISSEMENT: Ce script démarre un Shell par bloc, pour les très gros fichiers, cela peut être des centaines.


Voici un script que j'ai écrit à cet effet. Sur une machine à 4 processeurs, les performances de tri ont été améliorées de 100%!

#! /bin/ksh

MAX_LINES_PER_CHUNK=1000000
ORIGINAL_FILE=$1
SORTED_FILE=$2
CHUNK_FILE_PREFIX=$ORIGINAL_FILE.split.
SORTED_CHUNK_FILES=$CHUNK_FILE_PREFIX*.sorted

usage ()
{
     echo Parallel sort
     echo usage: psort file1 file2
     echo Sorts text file file1 and stores the output in file2
     echo Note: file1 will be split in chunks up to $MAX_LINES_PER_CHUNK lines
     echo  and each chunk will be sorted in parallel
}

# test if we have two arguments on the command line
if [ $# != 2 ]
then
    usage
    exit
fi

#Cleanup any lefover files
rm -f $SORTED_CHUNK_FILES > /dev/null
rm -f $CHUNK_FILE_PREFIX* > /dev/null
rm -f $SORTED_FILE

#Splitting $ORIGINAL_FILE into chunks ...
split -l $MAX_LINES_PER_CHUNK $ORIGINAL_FILE $CHUNK_FILE_PREFIX

for file in $CHUNK_FILE_PREFIX*
do
    sort $file > $file.sorted &
done
wait

#Merging chunks to $SORTED_FILE ...
sort -m $SORTED_CHUNK_FILES > $SORTED_FILE

#Cleanup any lefover files
rm -f $SORTED_CHUNK_FILES > /dev/null
rm -f $CHUNK_FILE_PREFIX* > /dev/null

Voir aussi: " Tri plus rapide de gros fichiers avec un script Shell "

13
Adrian

Je ne connais pas le programme, mais je suppose qu'il se fait au moyen d'un tri externe (la plupart du problème est conservé dans des fichiers temporaires tandis qu'une partie relativement petite du problème est conservée en mémoire à la fois). Voir Donald Knuth's The Art of Computer Programming, Vol. 3 Sorting and Searching, Section 5.4 pour une discussion très approfondie du sujet.

11
pico
#!/bin/bash

usage ()
{
    echo Parallel sort
    echo usage: psort file1 file2
    echo Sorts text file file1 and stores the output in file2
}

# test if we have two arguments on the command line
if [ $# != 2 ]
then
    usage
    exit
fi

pv $1 | parallel --pipe --files sort -S512M | parallel -Xj1 sort -S1024M -m {} ';' rm {} > $2
11
Sergio

Examinez attentivement les options de tri pour accélérer les performances et comprendre son impact sur votre machine et votre problème. Les paramètres clés sur Ubuntu sont

  • Emplacement des fichiers temporaires -T nom_répertoire
  • Quantité de mémoire à utiliser -SN% (N% de toute la mémoire à utiliser, mieux c'est, mais évitez la surabonnement qui provoque l'échange sur le disque. Vous pouvez l'utiliser comme "-S 80%" pour utiliser 80% de la RAM disponible, ou "-S 2G" pour 2 Go de RAM.)

Le questionneur demande "Pourquoi aucune utilisation élevée de la mémoire?" La réponse à cela vient de l'histoire, les anciennes machines Unix étaient petites et la taille de la mémoire par défaut est petite. Ajustez ce paramètre aussi grand que possible pour votre charge de travail afin d'améliorer considérablement les performances de tri. Définissez le répertoire de travail sur un emplacement de votre appareil le plus rapide disposant de suffisamment d'espace pour contenir au moins 1,25 * la taille du fichier en cours de tri.

5
Fred Gannett