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.

dsg
fonte
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 #
serverfault.com/questions/152331/parallel-file-copy
Ciro Santilli新疆改造中心法轮功六四事件

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
OldWolf
fonte
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.

Linker3000
fonte
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.

diq
fonte
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.

yee379
fonte
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?)

ktf
fonte