Qual é a melhor maneira de executar uma cópia paralela no Unix?


17

Rotineiramente, tenho que copiar o conteúdo de uma pasta em um sistema de arquivos de rede para o meu computador local. Existem muitos arquivos (1000s) na pasta remota, todos relativamente pequenos, mas devido à sobrecarga da rede, uma cópia regular cp remote_folder/* ~/local_folder/leva muito tempo (10 minutos).

Acredito que é porque os arquivos estão sendo copiados seqüencialmente - cada arquivo aguarda até que o anterior seja concluído antes do início da cópia.

Qual é a maneira mais simples de aumentar a velocidade dessa cópia? (Presumo que seja para executar a cópia em paralelo.)

O zíper dos arquivos antes da cópia não necessariamente acelera o processo, pois eles podem ser salvos em discos diferentes em servidores diferentes.


Fechar os arquivos antes de copiar agilizará enormemente as coisas, porque não haverá mais "você conseguiu esse arquivo", "sim, eu recebi", "aqui está o próximo", "tudo bem", ... São esses "reviravoltas" que atrasam você.
David Schwartz

Provavelmente, é a velocidade do disco, e não a velocidade da rede, que é o seu fator limitante, e, se for o caso, fazer isso por arquivo em paralelo tornará a operação mais lenta , não mais rápida, porque você forçará o disco a procurar constantemente para frente e para trás entre arquivos.
Joel Coehoorn

Embora o zíper possa não ser uma boa ideia (executar algo de compactação acima de 1000s de arquivos pode demorar um pouco), o tar pode ser viável.
21413 Rob Rob

@JoelCoehoorn ainda, há casos em que esse não é o caso: por exemplo, eixos múltiplos + arquivos pequenos (ou simplesmente leituras aleatórias). Nesse cenário, "cp paralelo" ajudaria.
CAFxX #

Respostas:


8

Contanto que você limite os comandos de cópia em execução, provavelmente poderá usar um script como o postado pelo Scrutinizer

SOURCEDIR="$1"
TARGETDIR="$2"
MAX_PARALLEL=4
nroffiles=$(ls "$SOURCEDIR" | wc -w)
setsize=$(( nroffiles/MAX_PARALLEL + 1 ))
ls -1 "$SOURCEDIR"/* | xargs -n "$setsize" | while read workset; do
  cp -p "$workset" "$TARGETDIR" &
done
wait

1
Nota de aviso: este script quebra com nomes de arquivos que contêm espaços ou caracteres brilhantes.
slhck

@ OldWolf - Você pode explicar como esse script funciona? Por exemplo, qual parte faz a paralelização?
dsg

3
@dsg: O &final do cpcomando permite que o whileloop continue e inicie o próximo comando cp sem esperar. O xargscomando passa os nomes de arquivos em grupos de 4 (MAX_PARALLEL) para o whileloop.
RedGrittyBrick

Não funcionou para mim. Não tenho certeza se é possível acelerar cp. Obviamente, você pode acelerar o cálculo através do multithreading. Mas não acho que o mesmo vale para o enfrentamento dos dados no disco rígido.
Adobe


3

Uma maneira seria usar o rsync, que copiará apenas as alterações - novos arquivos e as partes alteradas de outros arquivos.

http://linux.die.net/man/1/rsync

A execução de qualquer forma de operação de cópia paralela provavelmente inundará sua rede e a operação de cópia será interrompida ou sofrerá gargalos no disco de origem ou de destino.


2

Honestamente, a melhor ferramenta é a gsutil do Google. Ele lida com cópias paralelas com recursão de diretório. A maioria dos outros métodos que eu já vi não consegue lidar com a recursão de diretório. Eles não mencionam especificamente o sistema de arquivos local para cópias do sistema de arquivos local em seus documentos, mas funciona como um encanto.

É outro binário para instalar, mas provavelmente um que você já pode executar considerando toda a adoção do serviço em nuvem atualmente.


2

Rsync paralelo usando find:

export SOURCE_DIR=/a/path/to/nowhere
export DEST_DIR=/another/path/to/nowhere

# sync folder structure first
rsync -a -f'+ */' -f'- *' $SOURCE_DIR $DEST_DIR

# cwd
cd $SOURCE_DIR

# use find to help filter files etc. into list and pipe into gnu parallel to run 4 rsync jobs simultaneously
find . -type f | SHELL=/bin/sh parallel --linebuffer --jobs=4 'rsync -av {} $DEST_DIR/{//}/'

em uma LAN corporativa, o rsync único faz cerca de 800 Mbps; com 6-8 trabalhos, sou capaz de superar os 2,5 Gbps (às custas de alta carga). Limitado pelos discos.


0

Há muitas coisas que se deve considerar, dependendo da topologia que você possui. Mas antes de começar a pensar em soluções complexas, você pode simplesmente tentar dividir a tarefa em dois trabalhos e verificar se o tempo necessário reduzirá significativamente:

Na próxima vez, tente:

  cp remote_folder/[a-l]* ~/local_folder/ &
  cp remote_folder/[!a-l]* ~/local_folder/ &
  wait
  wait

(você pode substituir [al] * por algo que corresponda a cerca da metade dos arquivos - talvez [0-4] * - dependendo do conteúdo da pasta)

Se o tempo não melhorar drasticamente, pode ser mais importante verificar se é necessário copiar todos os arquivos (qual é a proporção de arquivos alterados para todos os arquivos?)

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.