O que são bons algoritmos de compressão para sincronização delta?

0

Ao sincronizar arquivos grandes em um link lento, geralmente é útil usar a compactação delta para reduzir a largura de banda usada. Também é útil compactar arquivos, pois eles ocupam muito menos espaço.

No entanto, muitos algoritmos de compactação têm o efeito colateral indesejado de alterar grandes porções da saída compactada quando apenas uma pequena alteração foi feita na origem.

Então, quais são alguns algoritmos / utilitários de compactação que criam blobs compactados semelhantes a partir de arquivos de origem similares?

    
por Kevin Cox 26.08.2013 / 19:19

3 respostas

2

Você pode considerar o uso do argumento --rsyncable para gzip . Isso reduz um pouco a compactação porque redefine o algoritmo de compactação no início de cada arquivo em seu tarball.

Note, no entanto, que você também pode usar a opção -z com o rsync para compactar os dados transmitidos. Se você estiver confortável com os arquivos descompactados na origem e no destino, isso pode ser suficiente para as suas necessidades.

Usamos isso para sincronizar um backup de banco de dados MySQL compactado com cerca de 20 GB. Usando o gzip --rsyncable, muitas vezes podemos transferir apenas uma fração do arquivo compactado via rsync se já tivermos o instantâneo do dia anterior. Eu não tentei transferir o arquivo tar descompactado e usar a opção -z do rsync, então não posso comentar sobre sua eficiência relativa.

    
por 26.08.2013 / 19:44
0

Uma solução é compactar manualmente um arquivo bloco a bloco. Do teste simples com os seguintes arquivos de script são apenas ligeiramente (~ 0.1%) maiores com blocos de 1MiB. Ele funciona para algoritmos que suportam concatenação (gzip e bzip2 para nomear dois). Também é um pouco mais lento, mas trivial para paralelizar.

#!/bin/bash

alg="${2:-gzip}"

size=$(stat -c %s "$1")
cur=0
block=$((1024*1024)) # 1M blocks.

while [ $cur -lt $size ]; do
    #echo $alg $size $block $cur >&2
    tail -c +$cur "$1" | head -c $block | $alg
    cur=$((cur+block))
done

Desta forma, as alterações só podem afetar o bloco alterado.

    
por 26.08.2013 / 19:20
0

Você pode querer usar o rdiff . É semelhante ao rsync , mas não requer uma conexão bidirecional com o servidor.

A maneira como você usaria isso é

  1. No computador de origem: rdiff signature file.ext file.ext.sig Isso cria um arquivo de assinatura contendo os hashes para os blocos que futuros diffs usarão. mantenha o arquivo .sig na máquina de origem.
  2. Compacte o arquivo normalmente e envie para o destino
  3. Descompacte o arquivo no destino
  4. O tempo passa
  5. No computador de origem: rdiff delta file.ext.sig file.ext file.ext.delta isso cria um arquivo delta que contém apenas as alterações nas quais os hashes não corresponderam do arquivo de assinatura.
    • Você provavelmente fará outro rdiff signature file.ext file.ext.sig para atualizar o arquivo de assinatura.
  6. Envie o arquivo delta para o destino, o arquivo delta já está compactado
  7. No destino: rdiff patch file.ext file.ext.delta file.ext isso atualizará a cópia de destino do arquivo para corresponder à cópia de origem. Dependendo da compilação do rdiff, o segundo argumento e o quarto argumento podem precisar de nomes de arquivo diferentes.
por 26.08.2013 / 21:00