AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 410649
Accepted
Tomilov Anatoliy
Tomilov Anatoliy
Asked: 2017-12-14 06:10:27 +0800 CST2017-12-14 06:10:27 +0800 CST 2017-12-14 06:10:27 +0800 CST

diretório tar para enviar apenas blocos modificados de arquivos

  • 772

A estrutura de diretório profunda e complexa pode ser modificada: os arquivos podem ser movidos (o prefixo alterado) e simultaneamente o conteúdo dos arquivos pode ser alterado parcialmente.

Eu quero diminuir uma quantidade de dados para transmitir pela rede.

rsynctrabalha com blocos de dados de tamanho 4k (se bem me lembro).

Posso usar algum tipo de concatenação ( tar-like) preservando metainformações sobre a estrutura e os atributos do sistema de arquivos, que coloca o conteúdo do arquivo a partir de deslocamentos de vários bytes de 4k para cada próximo arquivo para habilitar as rsyncvantagens do algoritmo?

O problema que desejo resolver é a omissão de rsync: ele não consegue detectar se o conteúdo do arquivo foi alterado e o arquivo é movido ao mesmo tempo entre as sincronizações para usar blocos correspondentes de arquivos de destino para reduzir a transferência de dados.

rsync tar
  • 3 3 respostas
  • 1197 Views

3 respostas

  • Voted
  1. Best Answer
    roaima
    2017-12-14T13:38:13+08:002017-12-14T13:38:13+08:00

    Com base na sua sugestão em um comentário (que realmente deveria estar na sua pergunta), parece ser isso que você deseja

    cd /path/to/directory
    tar cf /var/tmp/directory.tar .
    rsync -azv /var/tmp/directory.tar remote:/var/tmp/directory.tar
    ssh remote 'cd /path/to/destination && tar xf /var/tmp/directory.tar'
    

    Você precisa de espaço suficiente para armazenar directory.tarem ambos os lados.


    Me perguntaram se essa solução aparentemente trivial pode funcionar na situação em que uma pequena quantidade, como um único byte, é adicionada (ou removida) do início do arquivo tar.

    Espero que este exemplo ilustre como rsyncé bom lidar com essas situações. Funciona melhor se você tiver um login de equivalência (chave de certificado) para o servidor remoto, para que nenhum tempo seja gasto digitando uma senha.

    # Generate some data
    dd iflag=fullblock bs=1M count=200 </dev/urandom >200M.dat
    
    # See how long it takes to transfer
    time rsync -av 200M.dat remote:
    
    # See how long it takes to transfer "nothing"
    time rsync -av 200M.dat remote:
    
    # Generate one byte of data and prepend it to another data file
    dd bs=1 count=1 </dev/urandom >1b.dat
    cat 1b.dat 200M.dat >200M1b.dat
    
    # Copy the new file across to the original target
    time rsync -av 200M1b.dat remote:200M.dat
    
    # Clean up
    rm 1b.dat 200M.dat 200M1b.dat
    ssh remote rm 200M.dat
    

    Se o algoritmo puder lidar com o único byte inserido no início do fluxo de dados, a transferência deve demorar apenas alguns instantes. Se não puder, você esperaria que o tempo de transferência fosse amplamente semelhante ao primeiro.

    • 2
  2. roaima
    2017-12-16T02:02:52+08:002017-12-16T02:02:52+08:00

    Aqui vai mais uma sugestão para você. A hrsyncferramenta , que encontrei no GitHub, parece ser muito boa em manter uma memória de arquivos quando você os renomeia ou os move entre os diretórios de uma árvore de origem.

    • Ele pode rastrear movimentos e edições em arquivos dentro da árvore de origem
    • É um script de shell e não requer privilégios administrativos para instalar no sistema de origem, embora colocá-lo /usr/local/bintenha vantagens
    • Requer que os sistemas locais e remotos tenham um sistema de arquivos capaz de lidar com hard links
    • Não é possível rastrear alterações em um arquivo em que esse arquivo é renomeado e substituído (ou seja, excluído e recriado, em vez de editado no local)

    Exemplo

    hrsync /path/to/directory/ remote:/path/to/destination/
    
    • 1
  3. Tomilov Anatoliy
    2017-12-15T01:20:47+08:002017-12-15T01:20:47+08:00

    Encontrei a solução usando bashapenas utilitários de linha de comando. É possível otimizar a solução: classificar os arquivos por tamanho em ordem crescente e colocar o máximo possível de arquivos pequenos em cada bloco (problema de mochila aqui =), mas seria engenharia excessiva):

    pack.bash:

    #! /usr/bin/env bash
    
    set -e
    
    [[ -d "$1" ]]
    [[ -d "$( dirname '$2' )" ]]
    
    BLOB="$2.blob"
    FSIZES="$2.sizes"
    OFFSET=0
    
    shopt -s globstar
    for f in "$1"/* "$1"/**/*
    do
        if [[ -f "$f" ]]
        then
            SIZE=$( stat -c %s "$f" )
            echo "$SIZE" >> "$FSIZES"
            COUNT=$(( ($SIZE + 4096 - 1) / 4096 ))
            dd if="$f" of="$BLOB" bs=4096 seek=$OFFSET count=$COUNT conv=notrunc
            OFFSET=$(( $COUNT + $OFFSET ))
        fi
    done
    
    cp --recursive --archive --attributes-only "$1" "$2.dir"
    XZ_OPT="-9e --threads=$(( $( nproc ) + 1 ))" tar cpJf "$2.tar.xz" -C "$2.dir" .
    rm --recursive "$2.dir"
    

    unpack.bash:

    #! /usr/bin/env bash
    
    set -e
    
    BLOB="$2.blob"
    FSIZES="$2.sizes"
    
    [[ -f "$BLOB" ]]
    [[ -f "$FSIZES" ]]
    
    mkdir --parents "$1"
    [[ ! "$( ls -A '$1' )" ]]
    
    tar xpJf "$2.tar.xz" -C "$1"
    
    SIZES=($( < "$FSIZES" ))
    
    i=0
    OFFSET=0
    shopt -s globstar
    for f in "$1"/* "$1"/**/*
    do
        if [[ -f "$f" ]]
        then
            SIZE=${SIZES[i]}
            dd if="$BLOB" of="$f" bs=4096 skip=$OFFSET count=$SIZE iflag=count_bytes
            OFFSET=$(( $OFFSET + ($SIZE + 4096 - 1) / 4096 ))
            i=$(( $i + 1 ))
        fi
    done
    
    • 0

relate perguntas

  • Como faço uma duplicata de uma árvore de diretórios com links simbólicos duplicados relativamente?

  • Em Solaris; encontrar, anexar a uma bola de alcatrão e comprimir a pergunta

  • bsdtar: Como evitar sobrescrever as informações do arquivo existente?

  • Problemas de exclusão de Rsync

  • rsync porta 22 e 873 uso

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Matriz JSON para bash variáveis ​​usando jq

    • 4 respostas
  • Marko Smith

    A data pode formatar a hora atual para o fuso horário GMT? [duplicado]

    • 2 respostas
  • Marko Smith

    bash + lê variáveis ​​e valores do arquivo pelo script bash

    • 4 respostas
  • Marko Smith

    Como posso copiar um diretório e renomeá-lo no mesmo comando?

    • 4 respostas
  • Marko Smith

    conexão ssh. Conexão X11 rejeitada devido a autenticação incorreta

    • 3 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Marko Smith

    comando systemctl não funciona no RHEL 6

    • 3 respostas
  • Marko Smith

    rsync porta 22 e 873 uso

    • 2 respostas
  • Marko Smith

    snap /dev/loop em 100% de utilização -- sem espaço livre

    • 1 respostas
  • Marko Smith

    chave de impressão jq e valor para todos no subobjeto

    • 2 respostas
  • Martin Hope
    EHerman Matriz JSON para bash variáveis ​​usando jq 2017-12-31 14:50:58 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Drux A data pode formatar a hora atual para o fuso horário GMT? [duplicado] 2017-12-26 11:35:07 +0800 CST
  • Martin Hope
    AllisonC Como posso copiar um diretório e renomeá-lo no mesmo comando? 2017-12-22 05:28:06 +0800 CST
  • Martin Hope
    Steve Como as permissões de arquivo funcionam para o usuário "root"? 2017-12-22 02:46:01 +0800 CST
  • Martin Hope
    Bagas Sanjaya Por que o Linux usa LF como caractere de nova linha? 2017-12-20 05:48:21 +0800 CST
  • Martin Hope
    Cbhihe Altere o editor padrão para vim para _ sudo systemctl edit [unit-file] _ 2017-12-03 10:11:38 +0800 CST
  • Martin Hope
    showkey Como baixar o pacote não instalá-lo com o comando apt-get? 2017-12-03 02:15:02 +0800 CST
  • Martin Hope
    youxiao Por que os diretórios /home, /usr, /var, etc. têm o mesmo número de inode (2)? 2017-12-02 05:33:41 +0800 CST
  • Martin Hope
    user223600 gpg — o comando list-keys gera uid [ desconhecido ] depois de importar a chave privada para uma instalação limpa 2017-11-26 18:26:02 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve