chown de ambas as extremidades da lista de arquivos muito longa

1

Eu tenho uma lista de arquivos em um NFS que contém mais de 2 milhões de nós. Eu tenho que executar algumas alterações de permissões de arquivo, alterações de proprietário, etc. Quando executo comandos como chmod e chown (mesmo rm ou mv ), os processos demoram um pouco para serem concluídos, uma vez que cada tem que visitar todos os nós no sistema de arquivos.

Eu gostaria de obter alguma quase-forma de paralelização sobre isso, já que eu compartilhei o acesso através do NFS. Existe uma maneira de dividir (shard?) Uma lista de arquivos para que executar chown,chmod,rm,mv , etc em muitos hosts possa concluir o trabalho total mais rapidamente? Imagine 2 anfitriões começando pelos dois extremos e encontrando-se no meio do negócio.

    
por Neurax 22.12.2017 / 22:08

2 respostas

2

Conheça o parallel ( sudo apt install parallel ):

  

GNU parallel é uma ferramenta shell para executar trabalhos em paralelo usando um   ou mais computadores. Um trabalho pode ser um único          comando ou um pequeno script que deve ser executado para cada uma das linhas na entrada. A entrada típica é uma lista          de arquivos, uma lista de hosts, uma lista de usuários, uma lista de URLs ou uma lista de tabelas. Um trabalho também pode ser um comando          que lê de um tubo. O GNU paralelo pode então dividir a entrada em blocos e canalizar um bloco em cada comando          em paralelo.
  (…)
  Para cada linha de entrada, o GNU parallel executará command com a linha como argumentos. Se nenhum comando for dado,          a linha de entrada é executada. Várias linhas serão executadas em paralelo. O paralelo GNU pode ser usado como um          substitua xargs ou cat | bash .

Exemplo

find . -type f -print0 | parallel -0 chmod +w

Isso localizará recursivamente todos os arquivos no diretório atual e executará chmod +w , executando vários processos - um processo por núcleo da CPU por padrão - simultaneamente.

Para mais informações, consulte a man parallel , especialmente a lista impressionante de exemplos. Há também uma lista de reprodução com vídeos de exemplo no youtube.

    
por dessert 22.12.2017 / 22:19
0

Ficarei surpreso se o fator limitante não for o servidor. Então, eu imagino que a solução de sobremesa é razoável - possivelmente com a adição de -j200 e -X para executar mais trabalhos paralelos no host local e inserir mais de 1 argumento em cada linha.

Mas, supondo que você tenha clientes preguiçosos, isso pode ser uma maneira de fazer isso:

doit() {
  chmod +w ""
  # do other stuff
}
export -f doit
cat 2millionfilelist.txt |
  parallel --env doit -S nfsclient1,nfsclient2,nfsclient3 doit

Isso define uma função (adaptar-se à sua própria necessidade). Esta função é então copiada para cada um dos 3 nfsclients e executada com um único argumento de 2millionfilelist.txt. Isso é feito em paralelo, e o padrão é executar 1 job por cpucore em cada um dos 3 clientes.

Agora, o GNU Parallel se conectará aos nfsclients usando ssh para cada um dos arquivos. Então, o acima é provavelmente altamente ineficiente. Mas podemos fazer melhor que isso.

doitwrap() {
  doit() {
    chmod +w ""
    # do other stuff
  }
  export -f doit
  parallel doit
}
export -f doitwrap
cat 2millionfilelist.txt | parallel --env doitwrap -S nfsclient1,nfsclient2,nfsclient3 --pipe -N1000 doitwrap

doit faz o mesmo que antes, mas agora temos um wrapper, que lê a entrada padrão e executa doit na máquina local. Então, agora só precisamos distribuir o 2millionfilelist.txt uniformemente para os três clientes.

O GNU Parallel também pode fazer isso. Transferimos o doitwrap para cada um dos três trabalhadores e depois o executamos lá. Então passamos 2millionfilelist.txt em blocos de 1000 linhas para os 3 trabalhadores.

    
por Ole Tange 23.12.2017 / 19:39