Sincronização de vários clientes em tempo real com gerenciamento de conflitos

3

Eu preciso configurar uma sincronização entre meus computadores com um NAS na rede local. A configuração é um pouco complicada, portanto, presumo que não exista um produto de prateleira que faça o que eu preciso.

Detalhes:

Dispositivos que uso:

  • Desktop PC, dual-boot do Windows 10 / Arch Linux
  • Laptop (Arch Linux)
  • NAS (autoconstrução, FreeNAS em execução)

Eu usei rsync até agora para fazer backup no NAS (unidirecional, minha configuração de dupla inicialização usa o mesmo armazenamento para ambos os sistemas operacionais).

O problema é que eu gostaria de ter o Laptop na sincronização. Portanto, preciso fazer algum tipo de sincronização bidirecional.

Problemas que surgem aqui:

  1. Costumo salvar arquivos apenas alguns segundos antes do desligamento, por isso preciso monitorar as alterações dos arquivos em vez de executar periodicamente uma ferramenta de sincronização

    • Não consigo sincronizar meu laptop fora da rede local (e na rede local, uso o computador de mesa na maioria das vezes); a versão local (atualizada) pode estar desatualizada e gerar alguns conflitos.
  2. Eu quero usar apenas a rede local (provavelmente o compartilhamento de rede existente do NAS), não um ownCloud ou algo similar, porque temos uma largura de banda bastante limitada onde eu moro e tenho alguns arquivos enormes para manter sincronizado.

Minhas ideias

Eu encontrei esta pergunta: Como eu configuro o rsync e quaisquer outros scripts para imitar uma réplica viável mínima do DropBox? , e analisou uma solução usando o lsyncd (Live Syncing Daemon), que sincroniza diretórios locais com destinos remotos. Isso poderia resolver o problema 1, mas ainda preciso estar preparado para conflitos. Além disso, não consegui encontrar nenhum documento sobre o lsyncd no Windows, então presumo que não funcionará lá.

Também analisei o potencial de incorporar Unison em uma solução; parece fazer sincronizações bidirecionais. Talvez eu pudesse usá-lo junto com o lsyncd. Eu não tenho certeza sobre o tratamento de conflitos, no entanto. Eu encontrei uma dica que, com -batch , os conflitos são apenas ignorados. Mas como lidar com arquivos conflitantes a longo prazo (afinal, quero sincronizá-los)?

Então, minha pergunta é: como posso fazer isso?

    
por Qw3ry 30.10.2016 / 23:06

2 respostas

2

Dependendo do seu NAS - eu gosto muito da sincronização BitTorrent para isso. Ele é executado na maioria dos sistemas (incluindo sistemas raspberry pis e mips) com suporte de vários sistemas NAS de consumo (como meu Seagate). Basta escolher uma pasta para compartilhar, gerar uma chave e usar a chave para configurar o compartilhamento em cada sistema desejado. É inteligente o suficiente para detectar que você está em uma LAN, trabalha fora dele. A versão gratuita funciona bem o suficiente para as minhas necessidades - eu principalmente usá-lo para sincronizar downloads de um sistema que eu mantenho o tempo todo e backups de muitos arquivos pequenos que eu adiciono com pouca freqüência.

Ele fará o que você precisa - uma ou duas vias de sincronização, usando o lan, se necessário. Ele lida com conflito mantendo uma cópia dos arquivos excluídos (que eu desative para os meus casos de uso) e geralmente é executado bem o suficiente para que eu dificilmente note isso.

    
por 15.11.2016 / 15:29
2

Portanto, minha solução desenvolvida pelo próprio usuário requer um pouco mais de script do que a a do Journeyman Geek . Eu usei unison para a parte de sincronização e zenity para avisar sobre conflitos.

Scripts

O script bash (coloque isso em seus aplicativos de inicialização):

#!/bin/bash
if [ -z "$(arp | grep MAC_ADDRESS_OF_NAS)" ]; then
    zenity --warning --text="NAS not found. Aborting."
fi;
unison sync -batch=true -repeat=watch |& while read -r line; do
    if test -n "$(echo $line | grep skipped:)"; then
        zenity --warning --text="$line"; 
    fi;
done

A configuração uníssono (coloque isso como sync.prf em ~/.unison/ ):

root=/home/my-username/the-data-i-want-to-backup/
root=/mnt/NAS/some/sub/path/

# follow all symlinks
follow = Path *

# automatically do everything (if there are no conflicts)
auto = true

# for some reason unison fails if I sync the permissions
perms = 0
dontchmod = true

Explicação detalhada (e solução de problemas para derivadas)

  1. Primeiro, verifique se o NAS está localizado na rede local. Se o endereço MAC não aparecer na saída arp , presumo que não preciso sincronizar. Isso provavelmente precisa de mais ajustes, já que raramente ligo o meu laptop completamente, então o script não será iniciado quando eu me conectar à rede. Talvez eu adicione um cron job ou algum tipo de "conexão na rede"
  2. zenity pode ser usado para criar diálogos gráficos a partir de um script bash. Você provavelmente precisará instalá-lo. O uso básico é bastante simples.
  3. unison sync inicia a sincronização. Ele procura por um perfil de configuração chamado ~/.unison/sync.prf . Eu poderia substituir sync por outra coisa (tanto no nome do arquivo quanto no comando).
  4. Para pular arquivos conflitantes, eu especifico -batch=true . Eu não faço isso no arquivo de configuração porque eu quero executar unison sync manualmente se um conflito acontecer.
  5. Não preciso de uma ferramenta de terceiros para observar alterações: -repeat=watch faz exatamente o que eu quero. Sidenote: na verdade, ele inicia uma ressincronização completa em qualquer alteração, portanto, pode ser melhor, mas tudo bem para mim.
  6. A saída do unison -command é um pouco estranha, demorou um pouco para que isso funcionasse:
    • Se houver um conflito, a saída contém skipped: FILENAME
    • Isso parece acontecer no STDERR em vez de no STDOUT, então eu preciso canalizar com |&
    • Por algum motivo, não consegui descobrir que não funcionou com um simples grep para mim. Eu tentei algo como unison sync ... |& grep "skipped:" | xargs zenity --text="{}" , mas isso não seria executado até que o uníssono finalmente terminasse (funcionou bem sem -repeat= , e funcionou bem sem o grep )
  7. Por razões acima eu fiquei com um laço while para ler a entrada e usar o grep somente em cada linha
  8. No perfil de uníssono, observe que usei caminhos absolutos. Por algum motivo, não funcionou com ~/my/folder

Notas adicionais

  • Sou alguém que tende a super engenharia. Eu configurei um script me gerando o unison-profile. Caso você esteja interessado:

    #!/bin/bash
    
    HOME_DIR=$(cd ~; pwd)
    
    REPO_DIR="$(dirname "$(readlink -f $0)")"
    
    UNISON_PRF=$HOME_DIR/.unison/sync.prf
    
    # write sync script
    read -e -p "Local sync dir: [like ~/Data] " LOCAL_SYNC_DIR
    # make path absolute:
    LOCAL_SYNC_DIR="${LOCAL_SYNC_DIR/#\~/$HOME_DIR}"
    read -e -p "Remote sync dir: [like /mnt/NAS/Data/] " REMOTE_SYNC_DIR
    REMOTE_SYNC_DIR="${REMOTE_SYNC_DIR/#\~/$HOME_DIR}"
    
    rm "$UNISON_PRF"
    echo "root=$LOCAL_SYNC_DIR" > "$UNISON_PRF"
    echo "root=$REMOTE_SYNC_DIR" >> "$UNISON_PRF"
    cat "$REPO_DIR/sync.prf" >> "$UNISON_PRF"
    
    # user info
    echo "IMPORTANT: You need to put $REPO_DIR/unison/sync.sh to your startup applications for this to work properly!"
    
por 16.11.2016 / 11:37