Escalabilidade de 'sort -u' para arquivos gigantescos


23

Qual é o limite de escalabilidade razoável de 'sort -u'? (nas dimensões "comprimento da linha", "quantidade de linhas", "tamanho total do arquivo"?)

Qual é a alternativa do Unix para arquivos que excedem isso na dimensão "quantidade de linhas"? (É claro que posso implementar facilmente um, mas me perguntei se há algo que pode ser feito com poucos comandos padrão do Linux.)


Para aqueles que possam querer busca binária nele ou saber como: unix.stackexchange.com/q/247508/9689
Grzegorz Wierzowiecki

2
Existem situações em que um uniqantes da sort -uajuda. BTW, para dados ASCII LC_ALL=C sortacelera GNU sortum lote terrível (veja esta resposta )
Walter Tross

Respostas:


39

O sortque você encontra no Linux vem do pacote coreutils e implementa uma mesclagem R-Way Externa . Ele divide os dados em pedaços que podem ser manipulados na memória, os armazena em disco e os mescla. Os pedaços são feitos em paralelo, se a máquina tiver os processadores para isso.

Portanto, se houver um limite, é o espaço livre em disco que sortpode ser usado para armazenar os arquivos temporários a serem mesclados, combinados com o resultado.


3
Observe que a classificação GNU pode compactar esses arquivos temporários para compactar ainda mais (e aumentar o desempenho com discos lentos).
Stéphane Chazelas

1
@ StéphaneChazelas Obrigado pela atualização. Fiquei me perguntando se a classificação era inteligente o suficiente para remover arquivos de bloco quando um é totalmente mesclado (o que poderia acontecer facilmente se a fonte já estiver parcialmente classificada) como uma otimização de espaço. Eu não tenho o tempo para mergulhar no código fonte estes dias :-(
Anthon

3
Além da memória, há também outro limite que se aplica à fase de mesclagem: o número de arquivos que podem ser abertos simultaneamente. Normalmente, esse é um limite imposto pelo sistema operacional. A classificação GNU também lida com isso, mesclando recursivamente o número de arquivos que podem ser abertos ao mesmo tempo!
Diomidis Spinellis

@ StéphaneChazelas Se eu estivesse projetando uma ferramenta específica para classificar arquivos muito grandes, eu armazenaria as linhas como um índice no arquivo original. A classificação GNU faz isso ou simplesmente usa um algoritmo de compressão convencional?
usar o seguinte comando

3
@ Random832 e que está destinado a ser capaz de substituir o arquivo sobre si mesmo ( sort -o file file)
Stéphane Chazelas

1

Não posso falar de implementações específicas do fornecedor, mas a UNIX sortimplementação divide arquivos grandes em arquivos menores, classifica esses arquivos e combina os arquivos menores classificados em uma saída classificada agregada.

A única limitação é o espaço em disco para os arquivos menores criados intermediariamente por sort, mas os arquivos podem ser redirecionados para um diretório arbitrário configurando a variável de ambiente TMPDIR.


3
O que exatamente você chama de implementação de classificação UNIX ? É o original do Unix versão 3? A página de manual diz que não é possível classificar arquivos maiores que 128 KB.
Stéphane Chazelas

O que você entende pelo Unix versão 3? A versão de 1973? A implementação original da classificação UNIX foi aprimorada ao longo dos anos e no IIRC, a versão Solaris é ainda muito mais rápida que a versão GNU. Obviamente, há 25 anos, o tipo foi aprimorado para entender caracteres de vários bytes e o que me lembro de uma discussão da USENET foi que isso foi feito com eficiência no Solaris. BTW: man largefilelista sortcomo arquivos grandes reconhecidos.
Schily

2
Então, você está realmente falando da versão específica do fornecedor Oracle sort? Ou qualquer derivado de alguma versão da classificação AT&T Unix? Ou qualquer versão certificada para Unix sort(como GNU sortno OS / X)?
Stéphane Chazelas

A qualidade das sortimplementações modernas em relação aos caracteres de vários bytes pode variar, o fato de sortusar arquivos intermediários divididos é comum a todas as implementações do UNIX baseadas no código original. BTW: a versão Solaris é OSS como "OpenSolaris", consulte sourceforge.net/p/schillix-on/schillix-on/ci/default/tree/usr/…
schily

25 anos atrás, o UTF-8 ainda não foi inventado? O suporte para localidades UTF-8 foi adicionado no Solaris 7 ( 1 , 2 ). Você está se referindo a algum outro conjunto de caracteres multibyte?
Stéphane Chazelas

1

Com base em https://blog.mafr.de/2010/05/23/sorting-large-files/ e /unix//a/88704/9689 :

split -n l/20 input input-
for inpf in input-* ; do
    sort --parallel="$(nproc --all)" "${inpf}" > sorted-"{$inpf}"
done
sort -m sorted-input-* > sorted-input

Atualizar:

Das respostas acima, vemos que sortjá faz o que mencionou o trecho - ou seja, a fusão externa do R-Way . Então, afinal de contas, apenas:

sort --parallel="$(nproc --all)" -u input > output

Deve ser suficiente.

Minhas suposições atuais (sem verificar o código) sobre limites são:

  • o comprimento máximo da linha é limitado pela quantidade de memória física. A classificação precisa encaixar pelo menos dois na memória
  • quantidade de linhas - não conheço
  • tamanho do arquivo - obviamente por sistema de arquivos
  • quantidade de arquivos abertos em paralelo - dependendo do sistema operacional (Obrigado Diomidis Spinellis por apontar isso!)

(Esta resposta está marcada como wiki da comunidade - sinta-se incentivado a melhorá-la! :))


2
O GNU sortclassifica em paralelo por padrão (desde 2010 após a página à qual você está vinculando), --parallelé necessário reduzir o número de threads simultâneos em vez de permitir sortdeterminar o melhor. A classificação já faz uma divisão e mesclagem internamente de uma maneira mais eficiente. Duvido que essa divisão extra ajude.
Stéphane Chazelas
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.