Lorsque l’on analyse des logs serveur, il est fréquent de devoir dé-dupliquer de très gros fichiers.

A titre d’exemple, j’ai eu besoin récemment de dé-dupliquer un fichier de 51 millions de lignes (1,4 Go).

Avec Excel, cela semble compromis… (je n’ai pas essayé cela dit ^^).

Sur une console Linux, c’est très facile, on trie puis on déduplique

sort fichier.txt | uniq > fichier.dedup.txt

Cela fait le job, mais c’est un peu lent (12 minutes et 21 secondes sur ma machine).

Le principal défaut de cette commande, c’est qu’il y a un unique processus et donc l’utilisation d’un seul coeur du processeur. Un peu dommage puisque que j’en ai deux sur ma machine.

Heureusement, Linux est un modèle de modularité.

En quelques lignes de script shell, on peut parralléliser le traitement et faire une sorte de MapReduce (très à la mode en ce moment).

split -l 1000000 urls.txt urls.split.
 
for file in ls urls.split.*
do
	sort $file > $file.sorted &
done
wait
 
sort -m *.sorted | uniq > urls.sorted.txt.2

Le principe est simple, on découpe notre gros fichier en plusieurs fichiers. Chaque fichier va être trié en parallèle via des processus distincts. Une fois trié, on merge et on dé-duplique.

On augmente le nombre d’écritures sur le disque, mais on obtient une utilisation optimale du processeur.

Votre machine va chauffer un petit peu car le processeur va être utilisé à prêt de 100%, mais le traitement va être bien plus rapide (7 minutes 49 secondes sur ma machine, soit un gain de 37%).

Si ma machine disposait de 4 ou 8 coeurs, ce qui est de plus en plus courant, le gain aurait été bien plus important.

Si vous avez encore plus efficace, je suis preneur.

Merci Linux !