Eu olhei para essa pergunta e essa pergunta , mas elas não parecem abordar os sintomas que estou vendo.
Eu tenho um arquivo de log grande (cerca de 600 MB) que estou tentando transferir através de uma rede celular. Por ser um arquivo de log, ele é apenas anexado (embora na verdade esteja em um banco de dados SQLite com apenas INSERT sendo executado, portanto, não é tão simples assim, mas com exceção da última página 4k (ou talvez uma poucos) o arquivo é idêntico a cada vez.É importante que apenas as alterações (e quaisquer somas de verificação que precisam ser transmitidas) sejam realmente enviadas, porque a conexão de dados é medida.
No entanto, quando executo um teste em uma conexão não-medida (por exemplo, ponto de acesso Wi-Fi gratuito), não vejo uma aceleração ou transferência de dados reduzida observada ou relatada. Em uma conexão WiFi lenta, vejo na ordem de 1 MB / s ou menos, relatando que a transferência levará quase 20 minutos. Em uma conexão WiFi rápida, vejo uma velocidade mais rápida uniforme, mas nenhum relatório de aceleração e uma segunda tentativa de transferência (que agora deve ser mais rápida porque os dois arquivos são idênticos) agora mostra qualquer diferença.
O comando (higienizado para remover informações confidenciais) que estou usando é:
rsync 'ssh -p 9999' --progress LogFile [email protected]:/home/michael/logs/LogFile
A saída que recebo no final é assim:
LogFile
640,856,064 100% 21.25MB/s 0:00:28 (xfr$1, to-chk=0/1)
Não há menção de qualquer tipo de aceleração.
Eu suspeito que o problema pode ser um dos seguintes:
- Estou faltando alguma opção de linha de comando. No entanto, reler a página do manual parece sugerir que as transferências delta estão ativadas por padrão: só vejo opções para desativá-las.
- Estou usando o rsync over ssh (mesmo em uma porta não padrão) devido ao servidor estar atrás de um firewall que permite apenas o ssh. Não vi nada explicitamente dizendo que transferências delta não funcionariam se o daemon rsync não estiver sendo executado. Tentei usar a notação "::" em vez de ":", mas a página de manual não é muito clara sobre o que é um "módulo" e meu comando é rejeitado por especificar um módulo inválido.
Eu excluí o seguinte:
- transferências delta não executadas em uma rede local. Descartado porque estou tentando realizar a transferência pela Internet
- sobrecarga devido ao cálculo da soma de verificação. Vi esse comportamento em uma conexão Wifi rápida e lenta e a taxa de transferência não parece estar vinculada à computação.
but with the exception of the last 4k page (or maybe a few) the file is identical each time.
Você realmente confirmou isso comcmp
? Ou melhor, comxdelta
ou algo assim? Se você realmente deseja minimizar o tamanho da transferência, mantenha as versões antiga e nova localmente, para poder calcular um diff binário mínimo localmente (com algo diferente de rsync) e enviá-lo sem precisar enviar somas de verificação pela conexão medida. Fazer isso no nível do registro do banco de dados em vez do nível do arquivo binário provavelmente é ainda melhor, como sugere derobert.rsync --stats
e também-v -v
obter estatísticas ainda mais detalhadas. O Rsync informará a quantidade de dados correspondentes a inigualáveis.Respostas:
Sumário
Os bancos de dados tendem a manter muitos metadados, dados organizacionais etc. É muito improvável que uma inserção seja um anexo simples, como seria com um arquivo de texto. O teste do SQLite mostra que ele se comporta dessa maneira, nos modos WAL e não WAL. Isso faz com que o rsync precise sincronizar muito mais dados do que você esperaria. É possível reduzir um pouco essa sobrecarga usando uma baixa
--block-size
(ao custo de mais sobrecarga de computação e transferência de somas de verificação).Uma abordagem melhor é provavelmente despejar novos registros como um despejo SQL, compactá-lo e transferi-lo. Como alternativa, parece haver várias soluções de replicação para SQLite, você pode usar uma delas.
O roaima sugere no mínimo que você provavelmente poderia fazer um dump SQL completo, compactá-lo usando
gzip --rsyncable
e depois sincronizá-lo novamente. Vale a pena testar, suponho, para ver se é um delta pequeno o suficiente.Detalhes
O que você está tentando deve funcionar. Eu adicionaria pessoalmente
--partial
às suas opções de rsync, para o caso de detectar de alguma forma o arquivo crescente como uma transferência parcial. Você também pode obter melhores estatísticas de transferência com--stats
.A segunda coisa a verificar é se o SQLite está realmente tocando apenas algumas páginas - honestamente, não ficaria surpreso se estivesse escrevendo páginas em todo o arquivo. Uma maneira rápida de verificar seria usar
cmp -l
em duas versões - veja se há alterações nas páginas além das poucas finais. Lembre-se de quersync
a idéia de uma "página" / bloco é diferente da do SQLite; você pode mudar via rsync--block-size
. Reduzi-lo pode ajudar.Edit: Eu fiz um teste rápido com SQLite. Mesmo com 32 mil páginas, adicionando várias entradas de log rabiscadas em todas as páginas. Detalhes abaixo.
Editar 2 : parece ser melhor no modo WAL, embora você ainda tenha uma quantidade enorme de sobrecarga, provavelmente do ponto de verificação.
Editar 3 : também é melhor quanto mais dados você adicionar por transferência - acho que provavelmente rabisca certos blocos repetidamente. Portanto, você está transferindo o mesmo conjunto de blocos, independentemente de ter gravado neles uma ou cem vezes.
BTW: Para minimizar a transferência, você provavelmente pode fazer muito melhor que o rsync. Por exemplo, um despejo de SQL de novos registros desde a última transferência
xz --best
(ou mesmogzip
) seria provavelmente um pouco menor.Teste rápido de SQLite
Esquema:
Programa Perl:
Havia muito mais mensagens de log de exemplo (2076).
Verificando quais páginas foram alteradas:
fonte