Restic: Implementar compressão

Criado em 15 nov. 2014  ·  167Comentários  ·  Fonte: restic/restic

Este é um problema de rastreamento para fins de rastreamento de discussões e outros problemas / PRs relacionados à solicitação de implementação de compactação.

As seguintes questões / PRs estão relacionadas a este tópico (e podem, portanto, ser fechadas em favor deste):

  • PR # 2441
backend backup feature suggestion tracking

Comentários muito úteis

Acho que já houve discussão suficiente sobre a adição de compactação. Posso ver que é um recurso altamente antecipado. Tratarei disso a seguir, depois de terminar o novo código do arquivador (consulte # 1494).

Por favor, não adicione mais comentários, obrigado!

Todos 167 comentários

Ao implementar isso, adicione benchmarks e, especialmente, dê uma olhada no uso de memória com -benchmem e benchcmp!

lz4, lzo, lzma, null. bz2 é bastante lento.

snappy é rápido com compressão moderada

Se a compactação for feita por bloco, deve-se tomar cuidado para não deixar backups restic abertos a ataques de marca d'água / impressão digital.

Este é essencialmente o mesmo problema que discutimos relacionado à impressão digital do processo de desduplicação do CDC:
Com o CDC "ingênuo", pode-se verificar a existência de um arquivo de "texto simples conhecido" no backup se o tamanho dos blocos individuais puder ser observado por um invasor, usando o CDC no arquivo em paralelo e comparando a quantidade resultante de pedaços e indivíduos comprimentos de pedaços.
Conforme discutido anteriormente, isso pode ser um pouco atenuado adicionando um valor secreto ao algoritmo do CDC, como feito no sótão.

Com o CDC salgado, presumo que a compactação ocorreria em cada bloco individual, depois de dividir o arquivo problemático em blocos. Os pedaços Restic estão na faixa de 512 KB a 8 MB (mas não uniformemente distribuídos - certo?).

  • O invasor sabe que o algoritmo do CDC usa um salt secreto, portanto, o invasor gera um intervalo de blocos consistindo dos primeiros 512 KB a 8 MB do arquivo, um para cada comprimento de bloco válido. O invasor também é capaz de determinar o comprimento dos pedaços compactados.
  • O invasor então compacta esse pedaço usando o algoritmo de compactação.
  • O invasor compara os comprimentos dos fragmentos resultantes com o primeiro fragmento nos conjuntos de backup restic.
  • SE um comprimento de bloco correspondente for encontrado, o invasor repetirá o exercício com o próximo pedaço, e o próximo pedaço, e o próximo pedaço, ... e o próximo pedaço.
  • Acredito que com arquivos suficientemente grandes, e considerando o fato de que o algoritmo do CDC é "tendencioso" (na falta de palavras melhores) para gerar blocos de cerca de 1 MB, isso seria suficiente para determinar se um determinado grande arquivo existe no backup.

COMO sempre, um fluxo de consciência paranóico e altamente anticientífico.

Pensamentos?

Interessante. Não entendo como o ataque que você descreve depende se a compressão é usada, é mesmo necessário? Este ataque não funciona com e sem compressão?

No momento, estou pensando em como implementar o # 56. O que você acha de agrupar vários blobs em um único arquivo?

O funcionamento exato da implementação do CDC não está claro para mim:

  • Você divide em limites de bytes exatos ou os blocos de 512 KB - 8 MB são "arredondados" para um múltiplo de alguma coisa?
  • (A verdadeira questão é: há (15 * 512 * 1024) / (16 por causa do AES-CTR) tamanho de bloco possível ou menos?)
  • Também estou curioso para saber como seria viável reconstruir a semente dados pedaços suficientes de um arquivo conhecido - não muito viável, estou supondo?

Para responder à sua primeira pergunta:
Com o CDC propagado, a "impressão digital" depende do (conteúdo + a semente secreta), mas a diferença é que quando a compressão é feita _após_ a fragmentação, e assumindo que você pode distinguir blocos individuais uns dos outros, você tem uma impressão digital / marca d'água (a taxa de compressão de um determinado bloco) que depende exclusivamente do conteúdo, neste cenário um texto simples conhecido.

Exemplo:
Se o arquivo de marca d'água contiver 64 MB (8-128 chunks) de "AAAA", 64 MB de "ABCABCABCABC", então 64 MB de dados aleatórios, os primeiros 16-256 chunks seriam muito pequenos (porque essas sequências compactam muito bem , onde os pedaços de 8-128 seriam compactados de maneira bastante inadequada).
O invasor também seria capaz de trabalhar para trás, começando com o último (24º - 384º) trecho e compactar 512 KB-8 MB até que o invasor encontre um tamanho que seja compactado exatamente com o mesmo trecho. Assim que for encontrado, os "próximos" 512 KB-8 MB do texto simples original são compactados para descobrir qual comprimento é compactado para o comprimento do penúltimo bloco (23º - 383º), e assim por diante, até que o invasor encontre o pequenos pedaços que são o resultado das strings "AAAA".
Isso não permite que um adversário confirme positivamente se um arquivo com marca d'água está armazenado no backup, mas acho que estatisticamente pode criar resultados bastante claros, com dados suficientes.

Vejo algumas soluções em potencial, talvez você tenha mais ideias:

  • Permite desligar a compressão e / ou desduplicação para certos diretórios (provavelmente o mais fácil de implementar)
  • Randomizar dicionários de compressão (não pensei muito sobre isso, mas parece uma ideia interessante)
  • Impedir que os invasores aprendam os comprimentos de pedaços compactados individuais, por exemplo, preenchendo (potencialmente muito caro) ou agrupando vários pequenos pedaços e preenchendo o restante (mais complexidade, mas mais eficiente)

Obrigado pela sua explicação, eu entendo seu cenário agora.

Provavelmente, não haverá a opção de desligar a desduplicação no restic, porque isso é muito difícil de fazer, dada a estrutura atual do programa, o restic foi desenvolvido em torno do CDC. Adicionar suporte à compressão é de baixa prioridade agora e não é um objetivo para a versão alfa.

Sua terceira ideia será implementada em # 56 (agrupando vários pedaços), estou trabalhando nisso agora. E provavelmente adicionarei mais documentação a doc/Design.md sobre como o chunker funciona.

Obrigado novamente por trazer este cenário!

Não tenho certeza se sigo @cfcs - o tamanho compactado não é exatamente como um hash incrivelmente ruim? Dado um tamanho de arquivo compactado, o número de entradas possíveis que geram esse tamanho de arquivo é infinito. Mas provavelmente eu simplesmente não entendo.

Qualquer forma. Eu só queria te mostrar descaradamente uma biblioteca deflate / gzip modificada que fiz. Pode ser do seu interesse que eu coloquei em um modo de compactação de tempo constante , que permite uma taxa de transferência de aproximadamente 150 MB / s / core em QUALQUER dado, o que o torna quase invisível em cenários de backup. Também existe um pacote gzip paralelo que compacta arquivos maiores em múltiplos núcleos.

@klauspost : Lembre-se de que estamos discutindo os tamanhos compactados de pedaços individuais em vez de arquivos. Um arquivo de 100 GB com um tamanho médio de bloco de 1 MB terá cerca de 100 x 1024 blocos, cada um vazando a taxa de compactação de um determinado trecho do arquivo. Isso resulta em muito mais dados estatísticos do que o tamanho de um único arquivo compactado, tornando possível comparar um texto simples conhecido a um arquivo compactado e em partes, mesmo que o salt CDC (e, portanto, as bordas de alinhamento exatas dos pedaços) seja desconhecido.

151 foi mesclado, portanto, isso provavelmente não é um problema agora.

Na minha opinião, esse vazamento de informações é de pouca importância, considerando que temos um chunker semeado (por meio do polinômio por repo personalizado) e blob compactação (em que um invasor não pode ver pedaços individuais, mas apenas grupos de pedaços e o número de pedaços em um grupo, por meio do comprimento do cabeçalho de texto não criptografado). Acho que é uma boa ideia oferecer a desativação da compactação completamente por questões de velocidade ou privacidade, mas o padrão (quando isso for implementado) provavelmente será "ativar".

@klauspost Com certeza vou olhar sua biblioteca, obrigado por apontá-la!

Concordo com suas observações acima, @ fd0 , mas gostaria de acrescentar que acho que pode haver outro caso de uso importante para desabilitar seletivamente a compactação para arquivos / diretórios / dispositivos específicos, por exemplo, ao fazer backup de formatos multimídia que já arquivos binários compactados com alta entropia que não compactam bem ou ao fazer backups incrementais de volumes criptografados.

@cfcs - ok - a partir do seu texto, pensei que você

Em relação aos arquivos não compactáveis, é por isso que mencionei o modo somente Huffman de tempo constante que coloquei em deflate, como o nome indica, ele compacta todos os dados na mesma velocidade e tem fallback automático para armazenar dados descompactados. Portanto, a sobrecarga máxima é de cerca de 0,04% se o conteúdo for compactado.

Aqui estão alguns benchmarks . O mais aplicável para backups é provavelmente na "Compactação Média", que é de 10 GB de conteúdo misto - compactável e não compactável.

Padronizar para gzip Huffman apenas e ter a opção de especificar um nível de compactação que consome mais CPU pode fazer sentido.

Na minha opinião, pode ser valioso ativar / desativar seletivamente a compactação separadamente para dados e objetos de árvore. Especialmente os objetos de árvore grandes devem ter uma compactação realmente boa.

Eu olhei alguns "pontos" onde poderia fazer sentido inserir compressão. O local mais transparente e versátil seria em algum lugar entre o repositório e o backend.

Eu olhei brevemente como modificar Repository.Encrypt e Repository.DecryptTo , mas não temos tipos, e os tamanhos variados tornariam as coisas uma bagunça.

Minha proposta é implementar compactação e _encriptografia_ como um "back-end", que grava em um back-end subjacente. Isso tornará a compactação e a criptografia transparentes para o repositório.

O motivo pelo qual precisamos separar a criptografia é que os dados criptografados não são compactados (como você provavelmente sabe).

repository.Repository

O algoritmo de compactação só pode ser definido na inicialização e tudo, exceto a configuração, é considerado compactado com esse algoritmo.

repositório.Config

A configuração não pode ser compactada. Adicionamos uma string que indica o tipo de descompressão a ser usado para tudo. Vazio ("") não está compactado. Caso contrário, é a última parte do nome do pacote da biblioteca de compactação usada.

Observe que os níveis de compressão podem ser alterados entre cada execução / tipo. Não há problema em ter um repo onde alguns snapshots / tipos estão deflate nível 0 (armazenamento) e alguns no nível 9 (melhor compactação) - desde que o descompressor seja o mesmo.

type Config struct {
    Version           uint        `json:"version"`
    ID                string      `json:"id"`
    ChunkerPolynomial chunker.Pol `json:"chunker_polynomial"`
+   Compression       string
}

A compressão é adicionada como parâmetro de criação:

-func CreateConfig(r JSONUnpackedSaver) (Config, error) {
+func CreateConfig(r JSONUnpackedSaver, compression string) (Config, error) {

O backend é substituído após LoadConfig / CreateConfig. Aqui está um exemplo de como poderia ser:

// SearchKey finds a key with the supplied password, afterwards the config is
// read and parsed.
func (r *Repository) SearchKey(password string) error {
    key, err := SearchKey(r, password)
    if err != nil {
        return err
    }

-   r.key = key.master
-   r.keyName = key.Name()
    r.Config, err = LoadConfig(r)
+   r.be, err = FindCompressor(r.Config.Compression, Encryption(key, r.be))
    return err
}

Implementação de compressão

O compressor pode implementar compressão seletiva / ajustável para alguns tipos. Por ser visto como um "backend", o tamanho compactado nunca ficará visível para o repositório. O compressor deve ser sumétrico com todas as configurações.

Problemas

HELPME / FIXME: Arquivos "compactados" parecem um problema, pois a criptografia é reiniciada em cada arquivo. Se a criptografia for movida para o back-end, a criptografia será para todo o blob, não para cada arquivo. Presumo que seja um problema e não tenho uma boa solução.

TODO: Encontre uma boa maneira de enviar parâmetros / configurações ao compressor. Não é necessário para uma primeira implementação.

TODO: Nós nos importamos com os tamanhos do disco? Se o acima for implementado, o repositório não saberá disso.

Obrigado por compartilhar suas idéias, aqui estão as minhas:

Acho que a compressão e a criptografia precisam estar integradas uma à outra, vou pensar sobre isso. No momento, não gosto da ideia de abstrair completamente a camada de compactação / criptografia uma da outra. Como você já descreveu, devemos ter cuidado para não fazer coisas estúpidas, por exemplo, compactar dados criptografados. Além disso, devemos oferecer uma opção para desabilitar a compressão em favor da velocidade e / ou questões de segurança. Com relação à criptografia: pode haver um modo não criptográfico para o restic mais tarde, mas por enquanto a criptografia não é opcional.

Além disso, os arquivos compactados são um nível de abstração em si (por exemplo, as coisas podem ser reembaladas), o que não funciona com a abstração de criptografia.

Acho que o objeto Repository é muito complexo e precisa de uma revisão geral antes de lidar com isso. Eu realmente não tenho um bom plano pronto para isso agora.

Em relação aos diferentes algoritmos e opções de compressão: Acho que deveríamos selecionar um algoritmo (incluindo um conjunto de parâmetros) para os dados e talvez um segundo para comprimir as estruturas da árvore JSON, mas é só. Para todas as coisas opcionais (por exemplo, diferentes algoritmos e / ou parâmetros de compressão configuráveis), gostaria de ter uma boa consideração ponderando o benefício em relação à complexidade adicionada e quantidade de código adicional.

Por favor, não me interpretem mal, eu gostaria de adicionar recursos ao restic, mas especialmente para mudanças que modificam o formato do disco, preciso de argumentos muito bons. No caso geral de adicionar compactação, posso ver o benefício, mas a complexidade e as alterações no formato do disco devem ser gerenciáveis.

você precisará de diferentes algoritmos e parâmetros (e não apenas por repo, mas até mesmo por execução de backup), não há compactação "melhor para cada caso de uso".

apenas como um exemplo prático:

eu faço backups do servidor da minha empresa para o servidor de backup em casa. dsl uplink com ~ 700kbit / s.
para isso eu quero a melhor compactação (como lzma + alto nível). a CPU tem muito tempo livre à noite enquanto espera a conexão ruim para aceitar o próximo pacote.

para o mesmo repositório eu também faço backup do meu laptop quando estou em casa, lá eu tenho uma conexão sem fio "N". claro que eu não quero diminuir a conexão usando lzma + alto nível lá, mas eu quero algo muito rápido que não desacelere - como lz4. Eu ainda quero compressão, porém, não usar lz4 levaria cerca de 2x o espaço.

Eu quero lzma aqui, mas lz4 ali (reformulado :-))

Isso é tudo bikeshedding imho ... Vamos escolher um padrão razoável e não expor muita configuração, que só irá introduzir muita complexidade para pouco ganho, imho.

Acho que o objeto Repository é muito complexo e precisa de uma revisão geral antes de lidar com isso. Eu realmente não tenho um bom plano pronto para isso agora.

É justo. Comecei a procurar em repository.go e encontrei todos os lugares em que você inseriria uma etapa de compactação / descompactação, e a complexidade adicionada não era uma boa coisa. Ao implementá-lo como uma interface backend , você poderia repentinamente remover toda a criptografia e torná-la parte de uma cadeia de back-end. Você pode fazer um teste genérico que garanta a simetria das partes do backend, incluindo compressão e criptografia.

Com relação à criptografia: pode haver um modo não criptográfico para o restic mais tarde, mas por enquanto a criptografia não é opcional.

É por isso que o encadeamento de back-end o torna tão bom. Você apenas deixa a criptografia (ou cria um back-end de passagem) e funciona perfeitamente.

No caso geral de adicionar compactação, posso ver o benefício, mas a complexidade e as alterações no formato do disco devem ser gerenciáveis.

Esta foi a maneira menos intrusiva que posso ver. Se houver uma maneira de corrigir o problema do 'arquivo compactado', os repositórios descompactados permanecerão totalmente compatíveis com versões anteriores; o cliente antigo poderá operá-los como antes junto com os novos.

Repos compactados obviamente não, mas podemos alterar version para 2 somente se o repo for compactado, isso fará com que os clientes mais antigos falhem. A verificação deve obviamente ser alterada para if cfg.Version > RepoVersion { , mas isso não tem problemas de compatibilidade.

Isso é tudo bikeshedding imho ... Vamos escolher um padrão razoável e não expor muita configuração, que só irá introduzir muita complexidade para pouco ganho, imho.

Aceita. A maioria dos algoritmos (lzma / deflate) tem bastante flexibilidade no mesmo formato de descompactação.

Para testar a compressibilidade, existe o DataSmoke: https://github.com/Bulat-Ziganshin/DataSmoke

Além disso, o pcompress escolhe uma boa variedade de algoritmos de compressão: https://github.com/moinakg/pcompress

A biblioteca de abstração de compressão squash tem uma boa lista de algoritmos e um benchmark: https://quixdb.github.io/squash/

Há um benchmark de compressão de texto aqui: http://mattmahoney.net/dc/text.html

Uma abordagem fácil é sempre filtrar dentro das funções crypto/crypto.go Encrypt / Decrypt.

gzip-compression-v1.patch.txt é o diff da prova de conceito que pode ser aplicado ao head.

Obrigado por tentar @mappu , mas antes de implementar isso, precisamos concordar com uma estratégia. As perguntas abertas (do topo da minha cabeça) são pelo menos:

  • Quando a compressão é aplicada? (Dados? Metadados / JSON?)
  • Qual algoritmo devemos implementar? Acho que @klauspost tem algumas sugestões para nós :)
  • Como armazenamos isso em um repositório sem interromper os clientes?

Quando a compressão é aplicada? (Dados? Metadados / JSON?)

Dados obviamente sim.
Metadados / json, talvez seja inútil, mas acho que poderia ajudar para grandes arquivos de metadados, uma vez que os dados JSON são principalmente ASCII e se beneficiariam da fase de codificação aritmética / huffman (o gzip tem).

Como os dados / metadados são sempre criptografados, acho que adicionar à rotina de criptografar / descriptografar é uma maneira simples de pegar todos os usos, sem isso "Comecei a procurar no repository.go e encontrei todos os lugares em que você inseriria uma etapa de compressão / descompressão, e a complexidade adicional não era uma coisa boa. " de @klauspost .
Além disso, como os blobs são armazenados com o nome hash (texto simples) e não hash (texto cifrado) {{obviamente necessário para desduplicação, caso contrário, o IV aleatório destruiria desduplicação}}, é seguro fazer isso sem prejudicar a desduplicação.

Qual algoritmo devemos implementar? Acho que @klauspost tem algumas sugestões para nós :)

não me importo Embora eu concorde com @ThomasWaldmann que deve ser configurável. Pelo menos para um caso de uso --best e --fast .

Eu sugeriria o gzip apenas porque é puro go, está na biblioteca padrão golang e recebe atenção de desempenho do Google. xz é uma compressão lenta muito mais forte. lz4 é uma compressão rápida muito mais fraca. O gzip é equilibrado e facilmente ajustado, mesmo que não alcance nenhum dos extremos.

Como armazenamos isso em um repositório sem interromper os clientes?

O repositório deve ser compatível apenas em uma direção. Acho que não há problema se o antigo restic não puder ler o novo repo, desde que o novo restic possa ler o antigo repo.

Talvez você possa adicionar byte de tag após o MAC. Ausente - sem compressão (restic antigo). Então, o byte também pode indicar qual algoritmo de compressão foi usado. 0x01 gzip 0x02 lz4 ou assim.

Parece que o mesmo (ou pior) problema que no sótão está presente (nenhum tipo de compressão / byte (s) de parâmetro usado no formato atual).

No sótão (borg), tive sorte, pois o formato antigo era apenas gzip e o formato gzip pode ser detectado nos primeiros 2 bytes. Portanto, mantive o gzip sem bytes adicionais (igual aos antigos repositórios) e adicionei bytes de tipo (para nenhuma ou outra compactação) que nunca são ambíguos com os primeiros 2 bytes do gzip.

Obviamente, você não pode fazer assim se o formato antigo for apenas dados brutos e arbitrários.

Não. Mas existem outras formas de sinalizar essa informação. por exemplo, se IV no início do trecho criptografado é exatamente "NEWFORMAT" (1 :: 2 ^ xyz chance de colisão), analise como um novo formato. Não é tão "limpo", mas acho bom na prática.

como é feito com EXTENDEDPROTOCOL no handshake de bloqueio nmdc.

Oh não, nós não faremos algo feio como isso, e não precisamos fazer. Se decidirmos implementar isso, os arquivos do pacote têm um campo type para cada blob. Este é um uint8 , e no momento definido apenas para data e tree , podemos facilmente adicionar compressed data e compressed tree . https://github.com/restic/restic/blob/master/doc/Design.md#pack -format

No momento, não considero esse recurso de alta prioridade.

Adicionar novos tipos de blob ao formato do pacote é OK para compactação de dados, mas não fornece compactação de índice. Como os índices podem ficar grandes e o JSON tem uma boa taxa de compactação e talvez o índice não tenha cache local, acho importante compactar os índices também.

É importante que o new-restic funcione com o antigo repo, para permitir uma atualização fácil. Deve ser uniforme (preferencial) ou ter uma ferramenta restic upgrade-repo (não preferencial).

Então, que tal isso?

Todos os comandos restic já carregam e descriptografam config .

  • se o primeiro config byte for { (é o primeiro byte do objeto json), então o repositório inteiro está no formato antigo (descompactado)
  • caso contrário, o primeiro config byte é {tag byte} e o repositório inteiro é um novo formato. {tag byte} no início dos dados descriptografados indica o formato de compressão. exemplo 0x00 descompactado 0x01 gzip

Obrigado pela proposta. Acho desnecessário compactar o config, pois este é apenas um arquivo muito pequeno e sempre pode ficar no formato JSON, e podemos adicionar campos conforme necessário, por exemplo, se os arquivos de índice estão compactados ou não.

Acabei de encontrar o restic ontem enquanto procurava uma boa solução de backup. Uma das minhas principais preocupações é limitar a quantidade de espaço que meus dados ocupam. Principalmente se estou enviando dados para lugares pelos quais pago, como o S3. Dedup definitivamente vai ajudar, mas eu meio que esperava que a compressão fosse parte integrante de uma solução de backup ... Em https://github.com/restic/restic/issues/21#issuecomment -185920429 você ( @ fd0 ) diz isso é uma prioridade baixa, você poderia explicar por quê? Existe um roteiro que eu possa ver em qualquer lugar?

Além disso, +1. ;)

No momento, estou trabalhando na remoção de dados de backup antigos (# 518). Não é fácil obter a compactação certa e segura ao mesmo tempo, e preciso pensar um pouco mais sobre como integrar isso ao formato do repositório.

Implementaremos a compactação (afinal de contas esse é o problema), mas ainda não foi feito. restic é um projeto bastante novo, por favor, tenha paciência conosco :)

Este problema está relacionado ao # 116. Por causa da criptografia, não podemos compactar o backup com outras ferramentas, não é? Que prioridade você tem entre a compactação e tornar a criptografia opcional? (Aposto pela compressão primeiro!)
_Desculpe fazer pressão sobre isso, você está certo que o formato do repositório deve ser tomado com cuidado! _

Isso é fácil de responder: a compactação será implementada primeiro.

Isso ocorre porque não tenho planos no momento para tornar a criptografia opcional. Acho que é muito difícil acertar também. Precisamos pensar sobre integridade, pois isso é algo que não deveria ser opcional, mas (pelo menos no momento) está fortemente acoplado à criptografia.

@ fd0 Obrigado por responder à minha pergunta. Faz-me desejar que minhas habilidades de desenvolvimento ajudem nisso. Mas eu mal toquei em ir, e a maior parte do meu outro xp está em scripts webdev ou sysadmin.

Eu concordo totalmente que você precisa ter certeza de que a compressão é feita "de maneira correta e segura". Se isso atrasar as coisas, que seja. :sorriso:

Implementei a compressão rápida no restic aqui: https://github.com/viric/restic/tree/snappy

É apenas uma proposta. Basicamente, adicionei compressão / descompressão rápida para blobs em pacotes e uso um pouco do byte do tipo blob como marca. Também adicionei um campo nos índices de pacote: PLength (comprimento do texto simples), que até então não era armazenado, mas calculado como "bloblength - crypto.Extension".

Percebi que, para alguns dos meus backups, não só ocupa menos espaço, mas também funciona mais rápido (menos dados para manipular).

Todos os testes de repouso passam bem. Ele pode funcionar em repositórios anteriores do restic, mas o restic normal (o do master) não pode lidar com os novos blobs.

Usei o snappy (https://github.com/golang/snappy) porque pensei que afetaria menos o objetivo de velocidade de @ fd0.

Adicionou $ 50 de recompensa para compressão no master

Bountysource

Conforme mencionado acima, deve haver uma forma automatizada e não configurável de evitar a tentativa de compactar arquivos não compactáveis, como mídia, criptografados ou já compactados. O problema é agravado por alguns formatos de contêiner como PDF, cujo conteúdo às vezes é compactável, às vezes não.

Seria mais fácil usar apenas algum algoritmo que lidasse com isso de forma transparente, como o modo de compressão de tempo constante mencionado no primeiro comentário de @klauspost.

Caso contrário, haveria a necessidade de listas de tipos de arquivos: uma lista negra que nunca deve ser compactada, uma lista branca sempre deve ser compactada, uma heurística para o resto que tenta compactar uma pequena fração do arquivo e desiste se a redução do tamanho não for acima de um determinado limite.

Não tenho certeza de como isso seria mapeado no bloco, e não no nível do arquivo.

Eu argumentaria contra adicioná-lo ao passo de criptografia / descriptografia.
Não queremos misturar diferentes tipos de dados, já que alguns deles podem ser previsíveis, e os comprimentos de pacote / blob resultantes podem vazar informações sobre o texto simples dos dados imprevisíveis / secretos.
Acho que deve ser por arquivo, mesmo que isso o torne "menos agradável". Isso, no entanto, vem com a vantagem de não ter que fazer descompactação perdida de toneladas de arquivos de pacote (onde apenas um blob em cada matéria) para ler um arquivo.

@teknico

Conforme mencionado acima, deve haver uma forma automatizada e não configurável de evitar a tentativa de compactar arquivos não compactáveis, como mídia, criptografados ou já compactados.

Meu pacote deflate modificado implementa o salto de dados já compactados e faz isso a uma taxa de aproximadamente 250 MB / s por núcleo. O deflate Go 1.7 suporta apenas nos níveis de compressão mais rápidos.

Snappy e LZ4 oferecem suporte à funcionalidade de salto semelhante.

Seria mais fácil usar apenas algum algoritmo que lida com isso de forma transparente, como o modo de compressão de tempo constante.

Definitivamente deveria ser uma opção. No Go 1.7 (agora chamado de HuffmanOnly e meu equivalente), esse modo oferece suporte a ~ 200 MB / s por núcleo, independentemente da entrada. No entanto, a compressão é severamente prejudicada em comparação com a "melhor velocidade", que normalmente opera a 80 MB / s / núcleo.

@cfcs

Acho que deve ser por arquivo, mesmo que isso o torne "menos agradável".

Geralmente eu concordo. Terei que ler sobre o restic. O tamanho binário de cada tamanho de pacote disponível não é criptografado?

@klauspost Parece que algumas de suas melhorias foram mescladas no modo Go 1.7 DEFLATE "BestSpeed", correto? Talvez esse seja um padrão razoável.

A vantagem de usar o formato DEFLATE é que existem muitos compressores diferentes disponíveis que produzem fluxos de bits compatíveis, portanto, é completamente transparente para o descompressor.

Devido à natureza de como o restic funciona (divida os arquivos em blobs, só lida com os blobs depois), a maneira mais fácil de adicionar compactação é no nível do blob. Talvez pudéssemos adicionar algumas heurísticas para decidir se um blob deve ou não ser compactado, mas essa pode ser a segunda etapa.

Blobs são combinados em arquivos de pacote, que são armazenados no repositório. Um arquivo pack contém vários blobs (criptografados separadamente), seguidos por um cabeçalho (criptografado), seguido pelo comprimento do cabeçalho (não criptografado). Os invasores sem a chave de descriptografia só veem o texto cifrado, o comprimento do cabeçalho e o comprimento do arquivo. Portanto, com base no tamanho do arquivo de pacote e no comprimento do cabeçalho, os invasores podem calcular o tamanho médio de um blob em um arquivo de pacote específico, mas é só isso. Os arquivos de índice também contêm todos os dados (tamanho, tamanho criptografado e, posteriormente, talvez o tamanho compactado), mas esses também são criptografados. Não vejo nenhum risco aqui.

Uma heurística de teste "compressível" é sujeita a erros e bastante cara. Eu estimaria que seria difícil obter muito acima de 200 MB / s / core - essa é a velocidade da consulta do pedido 1 no pacote de desduplicação no AMD64.

Além disso, dependeria muito do compressor usado. O Snappy não seria capaz de compactar dados de base 64 aleatórios, mas deflacionar, por exemplo, então eu deixaria essa parte para o compressor - temos isso integrado para Snappy, LZ4 e deflate.

@ fd0 desculpe, eu quis dizer por blob, não por arquivo.
A menos que escolhamos um algoritmo leve, a compressão, sendo um tanto pesada para a CPU, provavelmente se tornará um gargalo (próximo ao AES, que no futuro provavelmente será cuidado pelo AES-NI).

@ fd0 - Fiz uma "estimativa de compressibilidade" rápida: https://play.golang.org/p/Ve5z3txkyz - estima a previsibilidade e a entropia de dados arbitrários. Embora, como mencionei, deva ser o compressor a decidir.

O borg 1.1 terá 2 "decisores de compressão":

  1. decidir por arquivo com base na correspondência de padrão de caminho ( *.zip , *.mp3 , /htdocs/photos/* , ...)
  2. se indeciso, decida por bloco, use lz4 como teste de compressibilidade - se comprimir, comprima novamente com a compressão desejada (lz4, zlib, lzma), se não, não comprima.

@klauspost hm, esse teste não é tão ruim na minha máquina:

BenchmarkCompressibility-4           100      10345544 ns/op     810.84 MB/s

O código de referência está aqui: https://gist.github.com/908c23123dda275a479cf931f2784f5d

Lz4 não tem um codificador de entropia, então ele vai falsos negativos muitas vezes
provavelmente?

Acho que precisamos de três modos (globalmente):

  • Comprimir todos os blobs de dados com um compressor de tempo linear (padrão)
  • Sem compressão
  • Compactação máxima (para pessoas com muita potência de CPU, mas apenas pequena largura de banda)

Eu gostaria de sempre compactar objetos de árvore (JSON), então devemos selecionar um algoritmo adequado para texto ASCII.

Caso contrário, vou trabalhar com @viric para construir um protótipo, então podemos raciocinar sobre uma implementação concreta.

Pensamentos?

@klauspost hm, esse teste não é tão ruim na minha máquina

Eu sempre me esqueço de como o novo compilador Go pode ser insanamente bom. Pelo menos o dobro do que eu esperava.

Acho que precisamos de três modos (globalmente):

Deflate faz todos os 3 muito bem, embora existam compressores mais eficientes (principalmente LZMA). Esvaziar sem compressão é obviamente desnecessário, mas é claro que é rápido e com sobrecarga mínima, portanto, uma abordagem de esvaziamento geral pode ser usada, com a possibilidade de especificar outras posteriormente.

Comecei a olhar para outro aumento de velocidade , que estaria entre o nível 1 e o Huffman, tanto em termos de velocidade quanto de compressão. No entanto, o tempo é um pouco precioso no momento e eu ainda preciso testar um backport de algumas das alterações finais do

Se você deseja apenas um algoritmo de compressão único, deve dar uma olhada no novo contendor zstd: https://github.com/facebook/zstd

Foi desenvolvido pelo mesmo desenvolvedor que lz4 e tem uma taxa de compressão melhor do que gzip, embora seja mais de 3 vezes mais rápido: https://code.facebook.com/posts/1658392934479273/smaller-and-faster-data-compression-with -zstandard /

zstd parece muito promissor, embora eu não tenha conseguido encontrar uma implementação em Go.

O site oficial http://facebook.github.io/zstd/#other -languages ​​links para esta implementação Go: https://github.com/DataDog/zstd

Ou você quer dizer uma implementação Go pura?

Sim, significava uma implementação Go pura. No momento, o restic não depende de nenhum código C e, idealmente, gostaria de mantê-lo assim.

Existe alguma previsão para implementar a compressão?

A implementação da compactação depende da alteração do formato do repositório (o planejamento / ideias estão em # 628), o que requer muito cuidado. Portanto, não, não há uma data definitiva quando a compressão é adicionada;)

Existe algo que podemos fazer ou contribuir para ajudar a que isso aconteça?

Acho que não, desculpe: wink :, só precisa de tempo.

Então, pensei que posso usar minha bancada de teste do # 790 mais uma vez. No meu build do restic, removi toda a criptografia e fiz um backup completo novamente. Ele veio no mesmo tamanho que o criptografado - sem surpresas aqui. Mas então eu compactei o repositório e o que encontrei foi:

35G backup-unencrypted
6.4G    backup-unencrypted.tgz2

Que diferença! Para comparação, aqui está o tamanho de um único despejo de banco de dados compactado:

1.7G    single-backup.sql.gz

Eu tenho 29 desses acima. Economia de cerca de 100 vezes em comparação com backups regulares!

Como encontrei todos os lugares onde a criptografia foi adicionada, acho que posso adicionar uma compressão configurável muito simples com uma implementação de gzip , com a possibilidade de usar um mecanismo de compressão diferente no futuro. Alguma objeção?

(Provavelmente darei a mim mesmo duas semanas de noites para ter sucesso ou fracassar.)

Obrigado pela sua pesquisa e postando os resultados aqui! Eu esperava resultados semelhantes. Para ser honesto com você: não vou mesclar nada que remova a criptografia, ou mesmo que torne isso opcional. Isso é algo que podemos fazer mais tarde, mas deve ser cuidadosamente planejado.

Adicionar compactação pode parecer fácil no início, mas não é. Precisamos ter muito cuidado para não tornar o repouso acidentalmente vulnerável a ataques inesperados (isso aconteceu com o protocolo TLS várias vezes consecutivas (sim, estou ciente de que esta é uma situação diferente)).

O mais importante em todo o projeto não é o código: é o formato do repositório. Os usuários confiam em nós com seus dados e dependem da capacidade de restaurá-los depois de usar o restic por um longo tempo, portanto, a estabilidade do formato do repositório é de extrema importância. Portanto, para oferecer suporte à compactação, primeiro precisamos decidir (e implementar) a próxima versão do formato do repositório. A discussão está aqui: https://github.com/restic/restic/issues/628

Eu posso ver que você está muito ansioso para implementar isso (e até mesmo contribuir com código), mas por favor, não perca tempo nisso até que concordemos com o formato do repositório e tenhamos discutido todos os ângulos desse problema. Obrigado!

Quanto à criptografia removida, não vou propor a fusão. Fiz isso apenas para ver se a compressão funcionaria. E sim, isso teve que ser planejado cuidadosamente (ninguém quer perder repentinamente a capacidade de verificar um repositório com a criptografia desabilitada).

Como usamos json.Unmarshal podemos adicionar quantas novas chaves quisermos à configuração. Se eles não forem encontrados no JSON, eles apenas manterão seus valores padrão.

A escolha do algoritmo não é o ponto principal, entendido: mas apenas para referência futura, Brotli parece um forte candidato.

Pelo que eu sei, a compactação Brotli é muito lenta (iirc 60 vezes gzip), por isso é recomendada para dados que são lidos com muita frequência em comparação a serem gravados e compactados, o que provavelmente não é comum em backups. Mas sim, não vamos entrar em detalhes ainda :)

Isso oferece uma boa visão geral dos diferentes algoritmos de compressão.

O Brotli é sempre mais rápido ou tem uma compressão melhor. Depende do nível de compressão.

@ibib Como você chega a essa conclusão? Parece-me que brotli parece mais lento do que a maioria dos outros (nos conjuntos de dados mistos), embora não alcance taxas de compressão particularmente surpreendentes. Talvez seja melhor para tipos específicos de dados estruturados?

Conforme listado nas comparações no benchmark Squash, existem três parâmetros a serem seguidos:

  • Taxa de compactação alcançada: O quão bem ele é compactado é importante para economizar espaço em disco (e E / S para o backend).

  • Velocidade de compressão: é importante porque faremos essa operação toda vez que adicionarmos um bloco, então realmente queremos algo que possa acompanhar o AES-NI e I / O geral para não se tornar um gargalo. Provavelmente não queremos escolher um algoritmo que comprima mais lentamente do que descompacta, pois temos o caso de uso oposto de navegadores da web que esses novos algoritmos (como zstd , lz4 , brotli ) são otimizados para (temos "comprimir frequentemente, descomprimir raramente" em oposição a "comprimir uma vez, descomprimir frequentemente").

  • Velocidade de descompressão: A velocidade de descompressão só é relevante quando estamos restaurando. Se concordarmos com uma restauração lenta, podemos aceitar uma velocidade de descompressão lenta. Por outro lado, também temos metadados que não queremos descompactar lentamente, o que pode até justificar dois algoritmos diferentes.

Parece que density está entre os mais rápidos, embora não seja particularmente eficiente em termos de taxa de compressão. Em termos de não ser um gargalo, parece que isso nos levará (na média) a uma taxa de compressão de 2: 1 quase de graça. Se quisermos 4: 1, teremos que escolher um algoritmo diferente, mas acabaremos parados esperando por ele.

Também temos dois (pelo menos?) Tipos diferentes de dados: Os índices; e os blocos de dados. Os dois são usados ​​de maneira diferente e acho que poderia ser discutido se faria sentido escolher algoritmos diferentes para eles. Pessoalmente, acho que devemos nos ater a um algoritmo (qualquer que seja nossa escolha) para que a reimplementação do Restic (em uma nova linguagem ou qualquer outra) não seja excessivamente difícil. E para que não nos exponhamos a bugs de dois algoritmos de compressão empolgantes, uma vez que são difíceis de testar em casos extremos.

Eu tenho que discordar de suas escolhas recomendadas. Os backups podem ser executados em segundo plano em um momento conveniente (talvez com um bom 10). Restaurá-los acontece sob pressão de tempo. A compensação relevante que vejo é entre o tamanho do bloco e a taxa de compressão. Blocos muito pequenos não compactam bem e aumentam a sobrecarga de metadados. Blocos muito grandes reduzem a taxa de desduplicação. Para a maioria dos algoritmos de compactação, as configurações de nível mais alto não melhorarão as taxas de compactação para entradas pequenas.

Além disso, taxas de compressão mais altas permitem que os usuários mantenham mais versões de seus dados no mesmo espaço.

Lembre-se de que meus testes com o snappy resultaram em: 1) backup menor (comprime, normal) e 2) backup e restauração mais rápidos (menos cifragem de dados, HMAC e transferência). Usando um laptop muito barato.

@cfcs referi- me à comparação de gzip e brotli
image
Aqui o brotli tem sempre a compressão mais rápida e melhor.

@Crest Isso é justo, provavelmente temos diferentes casos de uso - eu simplesmente não uso restic da mesma forma que você. Eu faço backups do meu laptop e quero que ele termine rapidamente para que eu possa sair com meu laptop. Suponho que você esteja falando sobre backups de servidores ou outras máquinas constantemente conectadas onde a taxa de backup não é tão importante. Da mesma forma, nunca preciso restaurar todos os meus dados sob pressão de tempo; se houver uma pressão de tempo (porque você o usa em contextos profissionais?), posso restaurar seletivamente os dados de que preciso e fazer o resto mais tarde.

Você fez uma observação muito boa sobre as "entradas muitas vezes pequenas";

@viric O efeito ao qual você está se referindo é considerado nos benchmarks de Squash na seção chamada Transfer + Processing :-)

@ibib ah,

@ibib, você pode

Tenho feito alguns testes com brotli e zstd, e percebi que meus resultados não correspondem em nada aos do benchmark squash. Então eu entendi que aquele benchmark tem 1,5 anos.

zstd funciona muito bem para mim. Razão rápida + alta, e seu "nível" permite um intervalo muito grande entre a razão rápida e alta. Grande coisa.

Brotli funciona muito devagar para mim, sem melhor taxa de compressão do que um zstd muito mais rápido. E brotli parece focado em pequenos arquivos de textos em inglês (inclui um dicionário de inglês). Para compressão html ou similar.

Mais comparações recentes que encontrei: https://github.com/inikep/lzbench

Então eu joguei meu test bed mais uma vez contra zbackup com compressão LZMA.

35G backup-unencrypted
6.4G    backup-unencrypted.tgz
2.5G    zbackup

Impressionante, não é?

Basta dizer que o zbackup tem seu próprio conjunto de limitações e desvantagens.

Então, de acordo com o link @viric lzbench, o compressor mais adequado é aquele que não retarda os backups (alta velocidade de compressão ?,> 200 MB / seg), que na verdade tem uma boa taxa de compressão (> = 50), certo?

Portanto, eu filtrei os resultados da tabela ordenada por proporção.

Também fiz uma pesquisa _rápida_ por implementações Go (é por isso que as mantive na tabela). Rasurado significa que não encontrei nenhuma implementação, o que eliminou quase tudo. Como foi apenas uma busca rápida, mantenho os resultados. Exceção para zstd que é apenas um invólucro.

| Nome do compressor | Compressão | Descompactar. Compr. tamanho | Razão |
| --------------- | ----------- | ----------- | ----------- | ----- |
| zstd 1.1.4 -1 | 242 MB / s | 636 MB / s | 73654014 | 34,75 |
| lagarto 1.0 -30 | 258 MB / s | 867 MB / s | 85727429 | 40,45 |
| densidade 0,12,5 beta -3 | 253 MB / s | 235 MB / s | 87622980 | 41,34 |
| gipfeli 2016-07-13 | 233 MB / s | 451 MB / s | 87931759 | 41,49 |
| enérgico 2011-12-24 -9 | 257 MB / s | 1263 MB / s | 90360813 | 42,63 |
| enérgico 2011-12-24 -6 | 295 MB / s | 1268 MB / s | 92090898 | 43,45 |
| quicklz 1.5.0 -1 | 346 MB / s | 435 MB / s | 94720562 | 44,69 |
| lagarto 1.0 -20 | 284 MB / s | 1734 MB / s | 96924204 | 45,73 |
| enérgico 2011-12-24 -3 | 352 MB / s | 1222 MB / s | 97255186 | 45,89 |
| lzrw 15-Jul-1991 -4 | 243 MB / s | 392 MB / s | 100131356 | 47,24 |
| lzo1x 2.09 -1 | 394 MB / s | 551 MB / s | 100572537 | 47,45 |
| lz4 1.7.5 | 452 MB / s | 2244 MB / s | 100880800 | 47,60 |
| fastlz 0.1 -2 | 243 MB / s | 469 MB / s | 100906072 | 47,61 |
| lzo1y 2.09 -1 | 397 MB / s | 556 MB / s | 101258318 | 47,78 |
| lzo1x 2.09 -15 | 406 MB / s | 549 MB / s | 101462094 | 47,87 |
| densidade 0,12,5 beta -2 | 480 MB / s | 655 MB / s | 101706226 | 47,99 |
| lzf 3.6 -1 | 251 MB / s | 565 MB / s | 102041092 | 48,14 |
| mal-humorado 1.1.4 | 327 MB / s | 1075 MB / s | 102146767 | 48,19 |
| blosclz 2015-11-10 -9 | 220 MB / s | 696 MB / s | 102817442 | 48,51 |
| enérgico 2011-12-24 -0 | 384 MB / s | 1221 MB / s | 103072463 | 48,63 |
| lzo1x 2.09 -12 | 418 MB / s | 550 MB / s | 103238859 | 48,71 |
| lagarto 1.0 -10 | 360 MB / s | 2625 MB / s | 103402971 | 48,79 |
| fastlz 0.1 -1 | 235 MB / s | 461 MB / s | 104628084 | 49,37 |
| lzrw 15-Jul-1991 -3 | 226 MB / s | 449 MB / s | 105424168 | 49,74 |
| lzf 3,6 -0 | 244 MB / s | 550 MB / s | 105682088 | 49,86 |
| lzo1x 2.09 -11 | 424 MB / s | 560 MB / s | 106604629 | 50,30 |
| lz4fast 1.7.5 -3 | 522 MB / s | 2244 MB / s | 107066190 | 50,52 |
| tornado 0.6a -1 | 233 MB / s | 334 MB / s | 107381846 | 50,66 |
| memcpy | 8657 MB / s | 8891 MB / s | 211947520 | 100,00 |

LZ4 parece o compressor mais adequado?

acho que você deseja lz4 (> = 1.7.0 r129) e zstd (> = 1.3.0), se houver. também os usamos para borgbackup.

MAS zstd é muito ajustável com um único inteiro, da velocidade lz4 para melhor
do que a compressão xz. Isso deixaria os usuários felizes de densa mais lenta
compressão e aqueles de compressão rápida. Sem mencionar que zstd
descomprime muito rápido, independentemente do esforço de compressão.

lz4 é bastante restrito.

No sábado, 16 de dezembro de 2017 às 09:50:49 AM-0800, TW escreveu:

acho que você quer lz4 e zstd, se houver. também os usamos para borgbackup.

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente ou visualize-o no GitHub:
https://github.com/restic/restic/issues/21#issuecomment -352199097

-
(Escriu-me xifrat si saps PGP / Write cifrado se você conhece PGP)
Chave PGP 7CBD1DA5 - https://emailselfdefense.fsf.org/

Bem ... de acordo com https://github.com/restic/restic/issues/21#issuecomment -250983311 de manter a dependência de repouso livre, zstd não é uma opção, por enquanto. Além disso, existem alguns tópicos sobre questões de patentes / licenciamento.

Quanto às taxas de compressão xz e altas, mesmo para as configurações de compressão mais baixas, de acordo com a tabela, a compressão mais rápida é de cerca de 15 MB / seg.

Se o requisito de backup rápido for reduzido, digamos,> = 30 MB / s, poderíamos adicionar:

| Nome do compressor | Compressão | Descompactar. Compr. tamanho | Razão |
| --------------- | ----------- | ----------- | ----------- | ----- |
| xz 5.2.3 -9 | 1,70 MB / s | 56 MB / s | 48745306 | 23,00 |
| xz 5.2.3 -6 | 1,89 MB / s | 58 MB / s | 49195929 | 23,21 |
| xz 5.2.3 -3 | 4,18 MB / s | 55 MB / s | 55745125 | 26,30 |
| zstd 1.1.4 -8 | 30 MB / s | 609 MB / s | 61021141 | 28,79 |
| zling 2016-01-10 -2 | 32 MB / s | 136 MB / s | 61917662 | 29,21 |
| xz 5.2.3 -0 | 15 MB / s | 44 MB / s | 62579435 | 29,53 |
| zling 2016-01-10 -0 | 38 MB / s | 134 MB / s | 63407921 | 29,92 |
| zstd 1.1.4 -5 | 88 MB / s | 553 MB / s | 64998793 | 30,67 |
| lzfse 08/03/2017 | 48 MB / s | 592 MB / s | 67624281 | 31,91 |
| libdeflate 0.7 -6 | 64 MB / s | 609 MB / s | 67928189 | 32,05 |
| brotli 2017-03-10 -2 | 98 MB / s | 289 MB / s | 68085200 | 32,12 |
| zstd 1.1.4 -2 | 185 MB / s | 587 MB / s | 70164775 | 33,10 |
| tornado 0.6a -4 | 91 MB / s | 197 MB / s | 70513617 | 33,27 |
| libdeflate 0.7 -3 | 96 MB / s | 602 MB / s | 70668968 | 33,34 |
| xpack 2016-06-02 -1 | 98 MB / s | 506 MB / s | 71090065 | 33,54 |
| tornado 0.6a -3 | 119 MB / s | 188 MB / s | 72662044 | 34,28 |
| libdeflate 0.7 -1 | 117 MB / s | 570 MB / s | 73318371 | 34,59 |
| lagarto 1.0 -42 | 90 MB / s | 938 MB / s | 73350988 | 34,61 |
| zstd 1.1.4 -1 | 242 MB / s | 636 MB / s | 73654014 | 34,75 |

Existem várias implementações de deflate, mas não tenho certeza se eles são comparáveis.
Esquerda xz para referência
zstd parece tão promissor. Que pena que não há implementação Go

@viric zstd não é exatamente a velocidade lz4.

mas se quisermos ter apenas um compressor em vez de vários, o zstd é mais flexível.

Perdoe meu atraso. Alguns comentários:

Velocidade de compressão: é importante porque faremos essa operação toda vez que adicionarmos um bloco, então realmente queremos algo que possa acompanhar o AES-NI e I / O geral para não se tornar um gargalo. Provavelmente não queremos escolher um algoritmo que comprima mais lentamente do que descompacta, pois temos o caso de uso oposto de navegadores da web para o qual esses novos algoritmos (como zstd, lz4, brotli) são otimizados (temos "comprimir frequentemente, descomprimir raramente" em oposição a "comprimir uma vez, descomprimir frequentemente").

Não, não é necessário compactar em velocidades AES aceleradas por hardware. A compressão é sobre o tempo de troca por tamanho. É totalmente esperado que os backups compactados levem mais tempo.

Por exemplo, em vez de usar o restic em meus backups pessoais, continuo usando o Obnam, porque em um dos pequenos servidores em que os armazeno, se não estivessem compactados, não caberiam. Os backups já demoram horas e são executados em segundo plano, então nem percebo.

Eu não me importo se os backups compactados do Restic demorarem mais. Na verdade, eu espero que eles façam isso, e é a troca que preciso fazer. Sem esse tipo de compressão, o restic não seria útil para mim.

Velocidade de descompressão: A velocidade de descompressão só é relevante quando estamos restaurando. Se concordarmos com uma restauração lenta, podemos aceitar uma velocidade de descompressão lenta. Por outro lado, também temos metadados que não queremos descompactar lentamente, o que pode até justificar dois algoritmos diferentes.

As restaurações são feitas com muito menos frequência do que os backups, portanto, a velocidade de descompactação não é tão importante. Alguém mencionou que muitas vezes são feitas sob pressão de tempo: isso é verdade, mas não significa que as restaurações precisam ser tão rápidas quanto os backups, ou perto disso.

Também temos dois (pelo menos?) Tipos diferentes de dados: Os índices; e os blocos de dados. Os dois são usados ​​de maneira diferente e acho que poderia ser discutido se faria sentido escolher algoritmos diferentes para eles.

Pode não ser necessário (ou necessariamente uma boa ideia) compactar os índices. Sendo índices, parece improvável que eles compactuem bem em primeiro lugar, já que todo o seu propósito é armazenar dados únicos.

Pessoalmente, acho que devemos nos ater a um algoritmo (qualquer que seja nossa escolha) para que a reimplementação do Restic (em uma nova linguagem ou qualquer outra) não seja excessivamente difícil. E para que não nos exponhamos a bugs de dois algoritmos de compressão empolgantes, uma vez que são difíceis de testar em casos extremos.

Eu entendo essas preocupações, mas acho que seria um erro. No mínimo, o formato repo deve permitir vários algoritmos de compactação para que os mais novos possam ser adicionados no futuro. Provavelmente deve haver módulos plugáveis ​​para compressão para que os usuários possam selecionar aqueles que desejam usar, por exemplo, eu poderia imaginar pacotes Debian como restic-xz , restic-zstd , etc. que os usuários poderiam instalar se quisessem usar esses algoritmos. A compactação dos dados de backup deve ser abstraída para que o restic entregue a uma função de compactação alguns dados e os obtenha de volta compactados, e o restic não deve se importar com o que acontece no meio; o mesmo para a descompressão.

Se o requisito para backup rápido for reduzido, digamos,> = 30 MB / s, poderíamos adicionar

Isso me parece razoável. Lembre-se de que os backups locais são apenas um tipo; os backups de rede têm menos probabilidade de serem obstruídos pela velocidade de compactação.

Mas, novamente, isso deve ser ajustado pelos usuários para que eles possam selecionar a solução apropriada para suas necessidades.

Adicionou 10 $ de recompensa por uma: cerveja: :)
image

🍺 ++

Aqui está um link para o BountySource se alguém quiser contribuir
badge
https://api.bountysource.com/badge/issue?issue_id=6096108

Gostaria de saber se isso pode ser implementado de uma maneira configurável pelo usuário de forma que a escolha de velocidade vs tamanho seja deixada para o usuário decidir. Eu preferiria uma compressão mais alta como padrão.

Vamos decidir quando chegaremos lá. Para o registro: estou bem em dar ao usuário um pouco de controle em termos de velocidade versus tamanho.

1 para restic que precisa de uma implementação de compressão. Estou usando o restic para fazer backup de imagens de VM para backblaze e adoraria poder compactá-las antes de fazer o upload. No meu caso de uso, eu trocaria uma quantidade quase infinita de tempo / CPU para reduzir o tamanho dos dados transferidos / armazenados. Eu percebo que a velocidade é uma preocupação mais para alguns, no entanto. Ter uma arquitetura plugável onde vários algoritmos podem ser selecionados é fundamental.

Fico feliz em ajudar no teste, pois isso é analisado mais detalhadamente.

@ fd0 Já faz um tempo desde que trabalhei na base de código do Restic. É possível dar uma orientação rápida sobre uma boa abordagem e onde devo olhar?

@klauspost Não é tanto adicionar compactação em um nível técnico, isso é bastante fácil de fazer, mas como lidamos com a atualização do formato repo de uma forma compatível com versões anteriores. No momento, estou ocupado reescrevendo a parte do arquivador (para que coisas feias como # 549 desapareçam), depois disso, gostaria de adicionar compactação e, em seguida, mudar para o repo v2.

Qual é a sua opinião sobre qual algoritmo de compressão devemos usar? Estou pensando em oferecer suporte a três modos:
1) Sem compressão
2) Compressão "tempo linear" (não adiciona muita carga à CPU)
3) "Compressão máxima"

Talvez o primeiro e o segundo modo sejam iguais, ainda não tenho certezah

Seria incrível poder usar algo como zstd, mas como código Go nativo. Damian deu a entender que pode não dar muito trabalho portar a versão Java ou C: https://twitter.com/dgryski/status/947259359628738560, há algo que eu possa fazer para que você se interesse em tentar isso? :)

Eu olhei as especificações do formato zstd, e para mim não é trivial implementar (bem). As fontes Java são apenas descompactação.

Para uma compressão rápida, o LZ4 deve funcionar muito bem. A porta Go é excelente. zstd seria melhor, mas eu iria com um pacote testado e aprovado, a menos que você queira usar a implementação cgo.

Para mid-of-the-road, desinflar compressão ainda é boa velocidade / compressão. Bem testado, etc.

A alta compressão é um pouco mais complicada. No entanto, parece que há uma implementação LZMA (2) Go nativa no pacote

Dei uma olhada na fonte para encontrar o lugar natural para inserir a etapa de compressão. O que fazia sentido para mim era ter compressão aqui e descompressão aqui . Mas vejo o desafio de identificar e controlar a compressão.

Você também pode dar uma olhada em um "estimador de compressibilidade" que fiz. Ele fornecerá uma estimativa rápida de quão compactável é um blob de dados. Normalmente opera a> 500 MB / s, portanto, pode ser usado para rejeitar rapidamente dados difíceis de compactar.

Você também pode dar uma olhada em um "estimador de compressibilidade" que fiz. Ele fornecerá uma estimativa rápida de quão compactável é um blob de dados. Normalmente opera a> 500 MB / s, portanto, pode ser usado para rejeitar rapidamente dados difíceis de compactar.

Adoro o estimador de compressibilidade! Evitar tentativas de compactar dados não compactáveis ​​ganharia muita velocidade.

O Zstd tem algo assim integrado: [1]

Zstd passa mais rápido sobre dados incompressíveis. Espere algo> 1 GB / s

Embora eu não tenha encontrado nenhum benchmark explícito disso.

O pacote xz parece um bom negócio para o lzma. Fiz alguns testes rápidos com as configurações padrão:

| algoritmo | nível | insize | descomunal | millis | mb / s | proporção |
| ----------- | ------- | ------------ | ----------- | ---- ---- | -------- | -------- |
| lz4 | - | 1000000000 | 625968314 | 5454 | 174,85 | 62,60% |
| flatekp | 1 1000000000 | 391051805 | 12367 | 77,11 | 39,11% |
| flatekp | 5 | 1000000000 | 342561367 | 20164 | 47,3 | 34,26% |
| flatekp | 9 1000000000 | 324191728 | 43351 | 22 32,42% |
| lzma2 | | 1000000000 | 291731178 | 149437 | 6,38 | 29,17% |
| lzma | | 1000000000 | 291688775 | 161125 | 5,92 | 29,17% |

Compromisso de velocidade / compressão muito razoável. Todos têm desempenho de núcleo único no enwik9 - corpo de texto compactável médio. Obviamente, não tive tempo para testar uma imagem VM completa ou algo como o corpus de 10 GB com mais conteúdo misto.

Não parece que o lzma2 oferece muito em sua implementação atual sobre o lzma padrão. Como você está lidando com blocos pequenos, a diferença deve ser bem pequena.

Zstd tem algo parecido com isso embutido

Sim, assim como lz4 e deflate, no entanto, não o vi tão rápido quanto uma função dedicada.

zstd é realmente impressionante, sem dúvida. Benchmarks usando a implementação cgo:

| nível | insize | descomunal | millis | mb / s | proporção |
| ------- | ------------ | ----------- | -------- | ------- - | -------- |
| 1 1000000000 | 358512492 | 5100 | 186,96 | 35,85% |
| 2 | 1000000000 | 332265582 | 6264 | 152,24 | 33,23% |
| 3 | 1000000000 | 314403327 | 8099 | 117,75 | 31,44% |
| 4 1000000000 | 310346439 | 8588 | 111,04 | 31,03% |
| 5 | 1000000000 | 305644452 | 12739 | 74,86 | 30,56% |
| 6 1000000000 | 292551252 | 18531 | 51,46 | 29,26% |
| 7 1000000000 | 287414827 | 23212 | 41,08 | 28,74% |
| 8 1000000000 | 282783804 | 27811 | 34,29 | 28,28% |
| 9 1000000000 | 280432907 | 31752 | 30,03 | 28,04% |

Perdoe-me se perdi algo, mas não vi essas perguntas respondidas antes.

  1. Parece que estamos falando sobre compactação no nível do bloco, não no nível do arquivo, correto?
  2. Nesse caso, isso obviamente limita a eficácia, pois os dados duplicados em vários blocos de um único arquivo serão armazenados e compactados para cada bloco.
  3. No entanto, isso obviamente depende do tamanho do bloco também.
  4. Então, qual é o tamanho médio do pedaço? Parece que esse é um fator importante na utilidade da compactação.
  5. Se o tamanho do bloco for relativamente pequeno, talvez devêssemos considerar a compactação de pré-fragmentação de arquivo completo para arquivos altamente compactáveis ​​(por exemplo, usando o estimador de @klauspost ). Por exemplo, um arquivo de texto de 50 MB (por exemplo, arquivos de log, arquivos grandes no modo Org, etc.) provavelmente será altamente compactável como um único arquivo. Mas se for fragmentado primeiro e, em seguida, cada fragmento for compactado individualmente, sem compartilhar um índice, isso limitará muito a eficácia da compactação (IIUC).

Obrigado.

Se compactássemos arquivos inteiros, isso poderia interferir no algoritmo de eliminação de duplicação, possivelmente tornando-o menos eficiente.

Fora isso, não vamos esquecer que qualquer compressão, ao mesmo tempo que oferece enormes vantagens em termos de espaço , nos abre para um ataque de canal lateral. A partir do tamanho dos dados compactados, pode-se fazer uma estimativa fundamentada do conteúdo dos dados. Acho que isso foi mencionado antes, mas ainda assim.

@alphapapa

Parece que estamos falando sobre compactação no nível do bloco, não no nível do arquivo, correto?

Sim, no nível do pedaço.

Nesse caso, isso obviamente limita a eficácia, pois os dados duplicados em vários blocos de um único arquivo serão armazenados e compactados para cada bloco. No entanto, isso obviamente depende do tamanho do bloco também. Então, qual é o tamanho médio do pedaço? Parece que esse é um fator importante na utilidade da compactação.

Nosso objetivo é 1 MiB, mas pode chegar a 8 MiB.

Se o tamanho do bloco for relativamente pequeno, talvez devêssemos considerar a compactação de pré-fragmentação de arquivo completo para arquivos altamente compactáveis ​​(por exemplo, usando o estimador de @klauspost ). Por exemplo, um arquivo de texto de 50 MB (por exemplo, arquivos de log, arquivos grandes no modo Org, etc.) provavelmente será altamente compactável como um único arquivo. Mas se for fragmentado primeiro e, em seguida, cada fragmento for compactado individualmente, sem compartilhar um índice, isso limitará muito a eficácia da compactação (IIUC).

No início, gostaria de integrar a compactação no nível do bloco e ver como isso funciona em cenários da vida real. Podemos revisitar essa ideia mais tarde.

@klauspost Muito obrigado por cgo é muito mais importante para o projeto como um todo. E usar um estimador de compressibilidade é uma ótima ideia, eu adoro isso.

Os lugares que você mencionou para adicionar compactação / descompactação parecem bons, mas precisamos rastrear os metadados para isso em outro lugar. Acho que provavelmente adicionaremos significado aos bits no byte no cabeçalho do pacote, consulte http://restic.readthedocs.io/en/latest/100_references.html#pack -format. Essa é a parte que precisa ser feita com muito cuidado.

Então, deixe-me terminar com o # 1494, então veremos se isso será resolvido.

@sanmai re: canais laterais: Eu
Várias soluções foram sugeridas, eu pessoalmente ficaria satisfeito com:

  • ter opções de configuração para whitelisting / blacklisting uso de compressão (semelhante ao que temos para inclusão de arquivo)

Outra ideia era tentar esconder os limites dos pedaços nos packfiles, o que teoricamente tornaria tudo mais difícil, mas acho que você ainda seria capaz de cronometrar as gravações na rede e canais secundários, como em que extensão do sistema de arquivos o pedaço foi escrito e assim por diante podem ser usados ​​para inferir os limites, então acho que o mais seguro / fácil seria apenas aconselhar a não compactação de dados confidenciais.

Isso seria incrível! : cerveja: + $ 10

Apenas jogando para fora, mas deixando de lado lzma ou qualquer um dos algoritmos de compressão mais gerais, que tal apenas codificação de comprimento de execução ou zero-squashing? Ou isso não seria suficientemente útil para um número suficiente de pessoas?

(Eu tenho um cachorro nesta caçada, muitas vezes estou fazendo backup de arquivos WAV enormes com muito silêncio.)

+ $ 15

Apenas jogando para fora, mas deixando de lado lzma ou qualquer um dos algoritmos de compressão mais gerais, que tal apenas codificação de comprimento de execução ou zero-squashing? Ou isso não seria suficientemente útil para um número suficiente de pessoas?

Também é útil para fazer backup de unidades VM com espaço quase vazio / arquivos esparsos (não tenho certeza se o restic já suporta backup / restauração de arquivos esparsos)

@bherila restic ainda não suporta o arquivamento / restauração de arquivos esparsos, os arquivos serão armazenados no repositório como se eles contivessem apenas muitos zeros. Esses grandes blocos de zeros são desduplicados, portanto, não ocuparão muito espaço no repo. Para restaurar, porém, você acabará com um arquivo regular (não esparso) sem "buracos".

Só queria verificar, já existe algum tipo de compressão? Fiz backup de vários computadores, incluindo um com 50 GB de dados, e recebo um número muito menor no servidor:

# du -shc /home/restic/
40G     /home/restic/
40G     total

@Alwaysin Provavelmente é a desduplicação , a menos que alguns arquivos tenham sido excluídos, é claro.

@rawtaz obrigado, eu não sabia sobre desduplicação, deve ser isso!

@iluvcapra esmagamento de grandes blocos repetidos já é implementado por meio de desduplicação, conforme mencionado por @rawtaz.

@klauspost você viu isso? https://github.com/mvdan/zstd

Sim, mas honestamente, um decodificador de stream é a parte fácil. Concluí a decodificação / decodificação FSE e tenho um codificador Huffman pronto. Uma vez que a decodificação de Huffman é feita, um decodificador de fluxo zstd é bastante simples, com o codificador completo sendo a parte final.

LZ4 é perfeitamente suficiente e também seria uma vitória rápida.

Por que não adicionar lz4 e criar outro PR para oferecer suporte a zstd?

Por que não adicionar lz4 e criar outro PR para oferecer suporte a zstd?

@ dave-fl porque precisamos ter muito cuidado ao modificar o formato do repositório. Deve ser feito de maneira compatível com as versões anteriores. A parte mais importante de todo o projeto é o formato repo, não a implementação. As pessoas dependem de nós para não bagunçar o formato para que possam restaurar seus dados :)

Acho que não podemos esperar muito com a compressão. Acabei de fazer alguns testes em alguns repositórios de backups de servidores, exatamente não ganhei nada quando gzip o repositório! Como @Alwaysin , já ganhei 30% com deduplicação.

Sobre a forma compatível com versões anteriores, você quer dizer que a Restic deve ler os dois formatos ou ferramentas para migrar do antigo para o novo? Quando o Restic não está na v1.0.0, acredito que não há problema em apenas migrar.

Acabei de fazer alguns testes em alguns repositórios de backups de servidores, exatamente não ganhei nada quando gzip o repositório!

Uhm, isso é esperado: todos os dados no repo são criptografados, portanto, dificilmente são compactáveis. Se a compactação for usada, ela deve ser feita nos dados antes de criptografá-los.

Não vejo como usar o LZ4 torna as coisas incompatíveis com versões anteriores. A compressão é compressão. Por que não oferecer suporte a vários formatos?

Você está certo, eu não pensei nisso.
No entanto, quando eu gzip o código-fonte não ganho mais do que 30%, a desduplicação já é muito eficiente em um diretório grande com muitas duplicatas. Mas é claro que com os dois pode ser impressionante.
Com o zpaq que faz compressão e desduplicação eu ganho um pouco mais, nem tanto.
Estou muito aberto para testar um branch com compressão, não importa se não é compatível!

Não vejo como usar o LZ4 torna as coisas incompatíveis com versões anteriores. A compressão é compressão. Por que não oferecer suporte a vários formatos?

O que acontecerá se 2 clientes estiverem usando o mesmo repo, mas 1 deles usar uma versão mais antiga do restic que não suporta compressão? Esse recurso precisa ser projetado cuidadosamente, tendo em mente todos os casos esquemáticos possíveis.

Eu prefiro nenhuma compactação em vez de uma solução parcialmente funcional que pode quebrar backups anteriores.

Acho que já houve discussão suficiente sobre a adição de compactação. Posso ver que é um recurso altamente antecipado. Tratarei disso a seguir, depois de terminar o novo código do arquivador (consulte # 1494).

Por favor, não adicione mais comentários, obrigado!

@dimejo O que você está dizendo não tem nada a ver com o que eu propus. A escolha de implementar zstd ou lz4 afetaria os dois casos.

Ouso dizer que a versão CGO do zstd parece um tanto portátil :)

Verifiquei como seria viável escrever uma implementação golang do zstd, muito brevemente, com base na especificação .

zstd principalmente todos os algoritmos internos, mas (opcionalmente) depende da soma de verificação de erros, e há uma grande porta para isso . já que bits opcionais são, bem, opcionais, você não teria que implementar essas partes para obter suporte zstd para um leitor / gravador em repouso. zstd suporta o conceito de "dicionários" para otimizar a compactação - não tenho certeza de como isso interagiria com o restict, mas seria uma área de pesquisa interessante para compactar partes específicas do arquivo, por exemplo, JSON ou fluxos de metadados. caso contrário, essa implementação também pode ser ignorada, pois é opcional.

Onde fica mais complicado, é claro, é onde a codificação de entropia entra em ação. Zstd usa uma nova abordagem chamada Entropia de Estado Finito (FSE, uma variação de [ANS] (https://en.wikipedia.org/wiki/Asymmetric_numeral_systems#, dos quais também existe apenas uma implementação C. outros bits de codificação de entropia são implementados com a codificação huffman , da qual existem várias implementações, incluindo duas na biblioteca padrão: uma em compress.flate e outra em net.http2.hpack , que é bastante estranho.

Pelo que eu posso dizer, todo o resto é cola em cima disso ... Algumas árvores huffman, sequências, frames e blocos. Existem propriedades interessantes na forma como os blocos e quadros são construídos também que podem ser mapeados em blobs restic, o que pode tornar possível compactar o repositório como um todo, mantendo os blobs separados dentro, embora eu não tenha examinado isso em detalhes . Também pode tornar o acoplamento entre o formato do repositório e a compactação inaceitável.

zstd é muito mais complicado do que gzip ou xzip, com cerca de 70k linhas de código (de acordo com cloc) em comparação com 36k e 12k, respectivamente. isso inclui testes, entretanto, que são numerosos: quando aqueles são ignorados, a implementação em si é quase comparável ao gzip (~ 34k).

Portanto, em resumo, é apenas uma questão de tempo antes que isso seja implementado em go. Acredito que tal mecanismo também poderia alavancar o paralelismo de golang porque os "quadros" zstd são independentes uns dos outros. não está claro para mim, no entanto, como os quadros são usados: a maioria dos streams que testei tinha apenas um ( zstd /etc/motd ) ou dois ( zstd isos/Fedora-Workstation-Live-x86_64-27-1.6.iso ) quadros (como encontrado por binwalk -R "\x28\xb5\x2f\xfd" ), então talvez não haja esse ganho lá, porque os blocos são inter-relacionados e menos paralelizáveis ​​...

de qualquer forma, tudo discutível, a menos que alguém aqui queira realmente se sentar e transportar isso, mas achei que deveria compartilhar o que descobri ao ler a coisa ... considerando que zstd é uma expansão do LZMA parte da família de compressores LZ77, deveria ser inviável portar ...

Alguma atualização sobre compressão? Eu sei que muitas pessoas querem esperar por zstd , mas o que haveria de errado em implementar lz4 ou lzo ou lzma ?

Se houvesse uma atualização, este problema seria atualizado.

Entretanto, vamos tentar respeitar o pedido do autor:

Por favor, não adicione mais comentários, obrigado!

@ fd0 , só queria salientar que parece haver uma implementação Go pura do algoritmo zstd https://github.com/klauspost/compress/tree/master/zstd . Eu não tentei fazer isso sozinho. Mas isso me empolgou com a possibilidade de suporte à compressão no restic.

Não sei as coisas do Go zstd (velocidade? Qualidade do código? Manutenção?), Mas as coisas do C zstd são tudo o que uma ferramenta de backup precisa, pois suporta uma ampla gama de compactação rápida / pequena a lenta / alta.

Se ainda não tivéssemos todos os outros algoritmos de compressão (lz4, zlib, lzma) no borgbackup e começássemos a adicionar compressão agora, acho que poderíamos viver apenas com zstd e nenhum.

Por uma questão de gosto / preferência, o padrão pode ser nenhum (como era antes) ou um nível zstd muito rápido (que no geral ainda torna a maioria dos backups mais rápidos, pois há menos dados para transferir).

Olá,
na minha opinião, a compressão não é um recurso obrigatório para o Restic. Eu comparei o backup dos meus dados feito com Duplicati (com compressão) e restic (sem compressão) e o espaço total usado foi muito semelhante.
Preciso descansar apenas para obter um backup incremental rápido e confiável. Não há necessidade de quebrar a broca ...
A restauração também é importante e o restic é adequado para recuperação de desastres. Duplicati é um pesadelo porque se você perder o banco de dados local, a tarefa de reparo leva dias ...

Obrigado @ fd0 e obrigado a todos os contribuidores!

@filippobottega se você não viu uma grande diferença em seu experimento que significa:

  • que seus dados não eram (muito) compactáveis ​​(mas este não é o caso em geral), ou
  • aquele duplicado tinha alguma eficiência de armazenamento pior não relacionada à compressão (por exemplo, devido a formato de armazenamento diferente, granularidade, algoritmos, qualquer que seja ...), então a economia de compressão foi compensada por perdas em outras áreas.

ambos não significam que a compressão é inútil.

@ThomasWaldmann Não vejo grande diferença pelo primeiro motivo.
Os dados hoje já estão compactados de várias maneiras: docx, xlsx, pptx, zip, 7z, jpeg, tif e assim por diante são todos formatos compactados. E também as imagens ISO contêm arquivos compactados. Por esta razão, eu acho que a compressão não tem sentido em repouso.

@filippobottega Sua visão é um pouco limitada sobre quais dados as pessoas estão usando para fazer backup. E quanto aos dumps SQL, código-fonte, conjuntos de dados, imagens brutas e assim por diante? A eliminação da duplicação está fazendo um ótimo trabalho na redução do tamanho delta entre os backups, mas não faz nada para reduzir o tamanho original do conjunto de dados. No caso de formatos não compactados, isso pode significar muitos gigabytes. Sem mencionar que armazenar um formato descompactado e, em seguida, compactar + desduplicar pode produzir resultados melhores do que desduplicar os arquivos já compactados.

Despejos de SQL foram meu primeiro pensamento, mas o restic também faz backup do meu servidor de e-mail e aparentemente melhora a compactação geral com base em alguns instantâneos RAR que tirei ao passar do Duplicati para o restic.

Eu posso ver o caso de uso para tornar a compactação opcional e ter uma lista padrão de tipos de arquivo, mas a compactação me pouparia uma quantia razoável.

@mrschyte

Sua visão é um pouco limitada sobre quais dados as pessoas estão usando para fazer backup.

Agora, agora, não há necessidade de ir para o lado pessoal. A perspectiva dele é tão válida quanto a sua e vale a pena considerar. Descobri que a maioria dos dados dos quais faço backup já está compactada devido aos formatos de arquivo.

E quanto aos dumps SQL

Você realmente armazena seus dumps SQL descompactados? Eu gz todos os meus antes de salvá-los, porque não tenho necessidade de armazená-los crus.

código-fonte, conjuntos de dados, imagens brutas e assim por diante

Acho que o único caso de uso válido para backup compactado é com arquivos grandes e descompactados com muitas repetições _que estão sendo usados ​​ativamente e, portanto, ainda não estão armazenados compactados_. Na minha experiência (que inclui anos de gerenciamento de dados de outras pessoas), muito poucos dados se enquadram nesta categoria. Pelo menos, não o suficiente para fazer uma grande diferença nesses casos.

no entanto, não faz nada para reduzir o tamanho original do conjunto de dados.

Indiscutivelmente, esse não é um trabalho de programa de backup. Não deve tocar nos dados originais.

Sem mencionar que armazenar um formato descompactado e, em seguida, compactar + desduplicar pode produzir resultados melhores do que desduplicar os arquivos já compactados.

Muitos algoritmos de compressão dependem da duplicação para fazer seu trabalho (veja os dicionários de flate), então não estou convencido por isso _ em geral_, embora concorde que isso esteja certo pelo menos algumas vezes.

(Não estou dizendo que a compactação em RESTIC é _macia_ quando feita corretamente, estou apenas argumentando que não precisa ser uma prioridade - especialmente em comparação com problemas de desempenho persistentes - e devemos respeitar as restrições de tempo de @ fd0 e desejos em relação à visão.)

@mholt Eu concordaria em geral, no entanto, fazer um backup de root (por meio de algum despejo ou até mesmo iterar o conteúdo de /), resulta em uma boa taxa de compactação para mim. Não é essencial , pois o total usado já é pequeno, mas consigo uma economia em torno de 50%, e é sempre bom ter de graça para o usuário final.

Faça este teste.

  1. pegue o dump SQL ou algum outro arquivo descompactado. Comprima e então
    use o Restic para fazer o backup.
  2. remova uma tabela do banco de dados SQL, faça um segundo despejo e, em seguida, compacte-a,
    em seguida, use o restic para fazer o backup.

Eu acredito que você vai descobrir isso porque a compressão é feita ANTES
Com a desduplicação, você derrotará quase inteiramente o algoritmo de desduplicação do Restics.
No entanto, se o Restic puder lidar com a compressão DEPOIS de desduplicar você
deve obter uma produção geral muito menor.

Na indústria de armazenamento corporativo, com ferramentas como DataDomain, é sempre
recomendado para alimentar os dados para o dispositivo de armazenamento em um descompactado
formate e deixe o dispositivo fazer a desduplicação e, em seguida, a compactação. o
a ordem geral de aplicação dessas ferramentas é a desduplicação,
compressão e, em seguida, criptografia. Pense nisso por um segundo ... você
realmente quero gastar todo o excesso de CPU compactando os mesmos dados múltiplos
vezes apenas para ser desduplicado e essencialmente descartado de qualquer maneira? Seu
geralmente aceito que é melhor reduzir o conjunto de dados por meio da desduplicação primeiro
antes de gastar a tarefa potencialmente pesada de fazer a compressão.

Na sexta-feira, 2 de agosto de 2019 às 13h29, Brandon Schneider [email protected]
escreveu:

@mholt https://github.com/mholt Eu concordaria em geral, mas fazendo
um backup raiz (por meio de algum despejo ou até mesmo iterando o conteúdo de /),
produz uma boa taxa de compressão para mim. Não essencial , como o total
usado já é pequeno, mas obtenho cerca de 50% de economia, e isso é sempre bom
ter de "graça" no que diz respeito ao usuário final.

-
Você está recebendo isto porque está inscrito neste tópico.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/restic/restic/issues/21?email_source=notifications&email_token=AC3I762ZVGTTJL4TF3ODZILQCRVIXA5CNFSM4AXPP352YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD3OMAGA#issuecomment-517783576 ,
ou silenciar o tópico
https://github.com/notifications/unsubscribe-auth/AC3I767IQQD3CZBIWM37C6TQCRVIXANCNFSM4AXPP35Q
.

Você realmente armazena seus dumps SQL descompactados? Eu gz todos os meus antes de salvá-los, porque não tenho necessidade de armazená-los crus.
Indiscutivelmente, esse não é um trabalho de programa de backup. Não deve tocar nos dados originais.

Parece que esse tipo de visualização impede o armazenamento eficiente de dados? A ideia de que cada programa e operação de exportação devem implementar seu próprio formato de compactação ad hoc é algo que estou tentando afastar, porque impede que a desduplicação / compactação / etc funcione em qualquer coisa, exceto em um escopo predefinido por arquivo (ou tarball de diretório) . A compactação de arquivos individualmente perde a capacidade de encontrar semelhanças entre diferentes arquivos / despejos / etc e, subsequentemente, você perde todos os benefícios da desduplicação. Manter as coisas descompactadas permite que um sistema de arquivos (zfs, btrfs, etc) faça tudo isso para você, e melhor, pois pode compactar e desduplicar em pastas, instantâneos, etc. e abstrair tudo, mantendo a compatibilidade com ferramentas que precisam funcionar com os dados descompactados.

A compactação pode ser vista como apenas uma otimização adicional na desduplicação do Top Restic, mas eles parecem incompatíveis entre si se feitos separadamente ... Sugerir que se deve compactar e pré-processar os arquivos antes de fazer o backup leva tudo de volta para um fluxo de trabalho onde você também pode apenas use rsync / rclone em vez disso, então por que usar o restic em primeiro lugar?

Parece que esse tipo de visualização impede o armazenamento eficiente de dados? A ideia de que cada programa e operação de exportação devem implementar seu próprio formato de compactação ad hoc é algo que estou tentando afastar, porque impede que a desduplicação / compactação / etc funcione em qualquer coisa, exceto em um escopo predefinido por arquivo (ou tarball de diretório) . A compactação de arquivos individualmente perde a capacidade de encontrar semelhanças entre diferentes arquivos / despejos / etc e, subsequentemente, você perde todos os benefícios da desduplicação. Manter as coisas descompactadas permite que um sistema de arquivos (zfs, btrfs, etc) faça tudo isso para você, e melhor, pois pode compactar e desduplicar em pastas, instantâneos, etc. e abstrair tudo, mantendo a compatibilidade com ferramentas que precisam funcionar com os dados descompactados.

Não se trata apenas do armazenamento eficiente de dados, mas também dos fluxos de trabalho existentes. Quero um produto de backup para fazer backup de meus dados de maneira confiável e eficiente, não para impor fluxos de trabalho em outros aspectos do sistema. É muito mais importante que os backups (que são retidos, potencialmente indefinidamente) sejam armazenados de forma eficiente, enquanto os dados de trabalho ativos devem ser armazenados no melhor formato para como são usados ​​ativamente.

Agora, há casos em que faz sentido compactar antes de armazenar, especialmente com dados muito compactáveis ​​em sistemas de armazenamento lentos, mas esta é mais a exceção do que a regra na minha experiência.

+1 compressão realmente me ajudaria! No trabalho como engenheiro de software, faço backup de toda a minha pasta pessoal, que contém muito código-fonte descompactado (e em linguagens dinâmicas, como ruby ​​ou python, quase sempre é código-fonte - até mesmo a maioria das dependências).

Em casa, faço backup de todo o /, novamente incluindo muitas coisas que se beneficiam da compactação, como binários, arquivos de manual, arquivos de recursos, etc.

Claro que eu poderia compactar todos eles e fazer muitas transformações antes de fazer o backup, mas isso prejudicaria muito a conveniência de apenas executar um comando muito simples e ser capaz de obter um backup, bem como facilmente restaurar coisas.

Claro que existem muitas classes de arquivos que não são compactados bem, mas ninguém está dizendo que eles deveriam ser forçados a compactar. Existem muitas abordagens para resolver isso - lista de permissões de quais tipos de arquivos devem ser compactados, lista de proibições de arquivos que não devem ser, ou mesmo a mais simples: tente compactar e, se o tamanho resultante não melhorar, armazene descompactado (acredito que ZFS usa essa abordagem quando a compactação em disco está ativada).

No final das contas, a compactação é um exemplo do clássico equilíbrio entre espaço e tempo: você quer pagar mais cpu ou mais armazenamento? No meu caso, o armazenamento domina meus custos, então acho que seria ótimo se meu quad-core esquentasse um pouco mais, e então minha conta de hospedagem de arquivos fosse menor.

Finalmente, eu faço backup de um pouco mais de 4 TB para um provedor de nuvem e minha velocidade de upload é fraca de qualquer maneira, assim como uma compactação bônus tornaria meu processo de backup mais rápido, não mais lento - minha CPU pode mais do que acompanhar minha conexão VDSL ruim .

Sim, posso apenas concordar com todos os outros aqui. A compressão é muito importante e não vejo realmente nenhum argumento por que o Restic não deveria tê-la.

@mholt , concordo totalmente com você. Toda palavra.
Na minha cadeia de ferramentas, a compactação vem antes da desduplicação restic porque, por exemplo, eu uso o TFS como controle de origem e todas as fontes já estão compactadas em backups SQL e as imagens de aplicativos são compactadas em arquivos de configuração msi ou arquivos 7z. Eu só preciso de uma maneira rápida e simples de obter o delta diário e enviá-lo para a nuvem para implementar um plano seguro de recuperação de desastres.
Acho que @ fd0 precisa concentrar seu tempo para resolver problemas do que tentar adicionar outra complexidade ao produto.

Apenas fazendo uma pequena comparação que fiz entre borg usando compressão auto,zstd e restic (sem compressão), primeiro em / , depois em /home , excluindo coisas como imagens de VM e imagens do docker (já que eu também não faço backup delas em um backup do mundo real). A máquina de teste foi minha máquina de desenvolvimento de software diário, que contém muitos arquivos binários, algumas imagens compactadas e arquivos de áudio, mas também uma boa quantidade de código-fonte de texto simples, que deve compactar muito bem:

/ : 1053136 arquivos, 92,9 GiB

  • borg, nenhum: 17:27 min, 64,1 GiB
  • borg, zstd: 19:29 min, 40,6 GiB
  • restic: 09:45 min, 62,4 GiB

/home : 221338 arquivos, 58,3 GiB

  • borg, zstd: 09:06 min, 30,7 GiB
  • restic: 04:36 min, 39,4 GiB
    Omiti o borg sem compressão aqui, uma vez que é praticamente o mesmo que o restic no que diz respeito ao espaço de armazenamento.

Em primeiro lugar, gostaria de aplaudir o Restic por ser quase exatamente duas vezes mais rápido naquele caso de teste. Além de o borg ser mais lento, pode ser interessante notar que a compactação adiciona apenas cerca de 2 minutos à duração geral do backup (+ 11%), mas reduz significativamente os dados a serem armazenados no caso / (-35 %). No caso do meu diretório inicial, a economia de armazenamento é de cerca de 20%.

(O teste foi realizado em um disco externo para esse caso. Ao fazer backup em um armazenamento remoto, o tempo que o backup leva depende principalmente da largura de banda de upload, pelo menos quando a velocidade da CPU e IO são muito maiores do que a rede. Eu testei isso e o borg com compactação são de fato mais rápidos do que restic então, porque a compactação resulta em menos transferência de dados). Resumindo, sou a favor de que o restic ganhe suporte à compressão, de preferência usando a detecção automática para verificar se um trecho se beneficia da compressão.

@nioncode Se meus cálculos estiverem corretos, você faz backup de cerca de

Eu sei que arquivar VMs pode ser um caso de uso, mas estou tentando evitar a necessidade de fazê-lo.
Estou tentando automatizar toda a construção da VM a partir de arquivos iso e de instalação.
Em caso de recuperação de desastres, quero poder restaurar toda a VM usando o backup de arquivos de configuração, documentos e backup de bancos de dados. E estou tentando fazer isso sem interação do usuário.
Dessa forma, posso evitar a necessidade de compactar e fazer backup de muitos arquivos de lixo contidos em uma VM, como arquivos temporários, arquivos descompactados como exe e dll, e assim por diante.
Eu sei, não é simples, mas posso evitar compactar e desduplicar os mesmos e inúteis GB de arquivos, economizando espaço em disco e largura de banda.

Não vamos bagunçar este tópico sobre quem faz as coisas como. Já foi o suficiente.

A compactação é um recurso que muitas pessoas desejam (inclusive eu) e pode economizar tanto armazenamento de backup quanto tempo de upload em caso de conectividade de internet lenta ou média, para algumas pessoas até 30% ou mais.

No entanto, nem todo mundo precisa dele e algumas pessoas adaptaram seu fluxo de trabalho de forma inteligente para lidar com isso - ou simplesmente têm dinheiro ou largura de banda ou ambos para simplesmente não se importar.

Em qualquer caso, ambos os lados falaram.

@ bjoe2k4 ou estão preocupados com as implicações negativas de segurança de compactar dados antes de criptografá-los, o que fornece informações sobre os dados de texto simples, como também foi levantado como um argumento várias vezes neste tópico nos últimos anos. :)

A menos que a compactação se torne obrigatória, as questões de segurança da compactação são simplesmente uma troca que um usuário pode fazer. Vou fazer backups mais rápidos e reduzir os custos mensais e únicos sobre este risco teórico (um risco que provavelmente não poderia ser explorado de qualquer maneira, pois meus conjuntos de dados são grandes e as alterações imprevisíveis, então o ruído abafaria qualquer tentativa de gerar um sinal de compressão).

No entanto, não acredito que alguém esteja falando em tornar a compressão obrigatória.

Meu caso de uso especial é fazer backup de GRANDES conjuntos de dumps CSV e SQL. Esses arquivos seriam MUITO compactáveis ​​... e não quero / não posso pré-compactá-los.

Eu realmente gostaria de ter o recurso de compressão, já que pago por cada GB de armazenamento online

Como essa discussão está se tornando um pouco mais ativa agora, gostaria de compartilhar algumas descobertas que fiz com uma versão remendada do restic de alguns amigos meus. Eles adicionaram compressão ao restic (mais ou menos rápido e sujo até onde eu sei) e eu os notificarei sobre este post para que eles possam comentar sobre os detalhes da implementação se alguém estiver interessado.
Meu caso de uso é um software bancário muito feio que tem seu próprio formato de banco de dados. Temos que usar este software por motivos regulamentares e os dados que temos são vários TB de arquivos bastante grandes que podem ser compactados até 90% de seu tamanho original. Então, obviamente, a compressão nos pouparia muito em armazenamento de backup, tempos de backup e tempos de restauração.
Minhas descobertas ao comparar o restic upstream, o restic corrigido com compactação e nossa solução de backup atual com tar podem ser encontradas aqui: https://gist.github.com/joerg/b88bf1de0ce824894ffc38f597cfef5f

| Ferramenta | Tempo de backup (m: s) | Tempo de restauração (m: s) | Espaço de backup (G) | Espaço de backup (%) | Backup (MB / s) | Restaurar (MB / s) |
| --------------------------- | ----------------- | ------------------ | ---------------- | ---------------- | ------------- | -------------- |
| Tar | 4:42 | 5:19 | 11 9,6% | 404 357
| Restic S3 local Upstream | 10:04 30:56 | 102 89,5% | 189 61
| Restic S3 local Compress | 5:43 | 19:28 | 8,6 | 7,5% | 332 98
| Restic Local Upstream | 8:33 | 26:06 | 102 89,5% | 222 73
| Restic Local Compress | 5:21 | 16:57 | 8,6 | 7,5% | 355 112
| Restic S3 Remote Upstream | 17:12 | 46:06 | 102 89,5% | 110 41
| Restic S3 Remote Compress | 5:27 | 21:42 | 8,6 | 7,5% | 349 88

Acho que o Restic ganharia muito com a compressão opcional de qualquer tipo, porque reduz quase tudo.

Nem todo arquivo terá uma taxa de compressão interessante. Compactar um arquivo de vídeo provavelmente não vale a pena, mas compactar um dump SQL com certeza é. É por isso que sistemas de arquivos como o Btrfs primeiro tentam compactar os primeiros 128 KB de um arquivo e, se houver uma taxa de compactação significativa, eles compactarão todo o arquivo. Definitivamente, não é perfeito, mas é rápido e deve funcionar para a maioria dos casos de uso se for decidido compactar arquivos individualmente.

Para aqueles que estão argumentando contra o fornecimento de compactação como uma opção, meu caso de uso é fazer backup de uma mistura de tipos de arquivos compactáveis ​​dos quais não tenho controle do conteúdo e não é razoável esperar que eu tenha que compactar os dados em várias máquinas (que ocupam mais espaço em disco local no caso de compactação em um novo arquivo ou torna os arquivos inutilizáveis ​​por seus aplicativos associados, se compactados no local) antes de executar uma operação de backup.

Eu preferiria poder usar o restic como minha ferramenta de backup de DR, mas atualmente estou usando o borg (requisitos de memória ram massivos e lentos, etc) porque a compactação + desduplicação resultante economiza muitos gigabytes de transferência de rede por operação de backup e facilmente em um terrabyte de espaço de armazenamento (que pago por mês) na nuvem durante todo o meu conjunto de backup. Eu seria capaz de reter backups por mais tempo ou reduzir meus custos de armazenamento se restic suportasse compactação.

Olá @joerg , obrigado por compartilhar seus testes.
Você tentou fazer backup com restic a saída da tarefa de compactação Tar?
Estou curioso para comparar "Restic S3 Remote Compress" e "Tar" + "Restic S3 Remote Upstream".
Além disso, o que você diz parece não ser realmente verdade:

Acho que o Restic ganharia muito com compressão opcional de qualquer tipo, porque reduz quase tudo

Vendo os resultados do teste, parece que o tempo de CPU necessário para o restic é 2x maior para backup local e 6x maior para restauração. Não é muito bom em comparação com Tar.

tar não é um algoritmo de compressão. claro que é rápido.
EDIT: oh e btw. se você tar um diretório, ele não usará vários threads por arquivo e também não funcionará com dois ou mais arquivos por vez; em vez disso, ele varrerá o diretório e adicionará um arquivo e então irá para o próximo. Bastante lento. mas o problema é o arquivo compactado que não foi projetado para adicionar vários threads.

Vendo os resultados do teste, parece que o tempo de CPU usado pelo restic é 2x mais lento no backup local e 6x mais lento na restauração. Não é muito bom em comparação com Tar.

Não estou completamente certo do seu ponto aqui. restic é mais lento que Tar, claro, mas restic com compressão é sempre mais rápido do que restic sem, então restic claramente se beneficiaria.

Tar é uma comparação útil com o “melhor caso neste hardware”, mas está ausente na maioria dos outros recursos do restic (instantâneos e desduplicação de dados vêm à mente). Adicionar compactação parece apenas melhorar os tempos de backup, tempos de restauração e custos de armazenamento, coisas que são importantes para um produto de backup.

@joerg Os seus amigos podem abrir um Pull Request e disponibilizar ao público os seus patches para restic com compressão? Qual algoritmo de compressão eles usam?

@joerg @thedaveCA
Peço desculpas, eu entendi mal o significado da afirmação de

Lembre-se de que não estamos usando arquivos compactados de tar, mas compactados com uma implementação zip paralela especial, caso contrário, o arquivamento de terabytes de dados levaria dias em vez das "apenas" horas que leva agora: https: //gist.github. com / joerg / b88bf1de0ce824894ffc38f597cfef5f # tarpigz
@shibumi Eu os informei sobre este assunto e minha postagem, então agora é com eles se e até onde querem se envolver nisso. Pessoalmente, espero que eles abram essa solicitação pull ...

A compactação é proibida para a criptografia. Ele permite que um invasor adivinhe se um repositório criptografado contém um determinado arquivo, pois uma seção (pedaço) de um arquivo é compactado para o mesmo tamanho, independentemente da chave de criptografia usada. Esta é uma vulnerabilidade muito conhecida dos protocolos de criptografia e é por isso que a compactação foi removida do TLS 1.3.

Não vamos criar um problema conhecido onde não há nenhum, certo?

(Acho que esse problema já foi mencionado, e provavelmente nem uma vez. Ainda assim, esse problema está em aberto, onde eu sinto que, por esse único motivo, deve ser encerrado de uma vez por todas.)

Por que você está enviando spam para o problema? :( Já foi discutido tantas vezes que é quase offtopic. Você NÃO SERÁ FORÇADO a habilitar a compressão !!

Além disso, acho que sua ideia de ataque requer que o invasor seja capaz de controlar os dados a serem compactados e criptografados (não tenho certeza, porém!). https://en.m.wikipedia.org/wiki/CRIME

Mas em qualquer caso, mesmo que seja uma preocupação de segurança, alguém pode querer usar a compressão apenas para um armazenamento que está sob seu próprio controle para simplesmente economizar espaço de armazenamento.

Ter até mesmo um recurso opcional que enfraquece a criptografia convida a uma falsa sensação de segurança. Restic afirma ser um programa de backup _seguro_. Adicionar uma compactação opcional anulará essa promessa, pois você não pode estar seguro às vezes, apenas em tempo integral, o tempo todo. E haverá relatórios CVE, com certeza. Quem deseja para seu software esse tipo de "popularidade"?

Mas eu acho que adicionar uma compressão de uma forma que nunca será usada com criptografia é uma opção viável.

FWIW em 2017, fiz uma demonstração em que removi a criptografia do Restic e mostrei que a compactação pode ser muito eficaz . Cem vezes eficaz. A compactação IIRC pode ser adicionada como um tipo de invólucro, assim como a criptografia, mas não olhei para o código por muito tempo, então as coisas podem ser mais difíceis ou mais fáceis hoje em dia.

na verdade, o CRIME precisa saber o comprimento do texto cifrado, o que é basicamente impossível no restic.
também não existe um programa de backup "seguro". se os arquivos de backup são acessíveis por terceiros, sempre há uma chance de que alguém possa adulterar ou pior, ler os dados.
então, dizer que a compressão torna tudo pior, é simplesmente estúpido.

na verdade, CRIME precisa saber o comprimento do texto cifrado

O CRIME precisa, mas você não. Imagine que você é um jornalista investigativo que recebeu um conjunto de arquivos ultrassecretos de sua fonte. Você faz o backup deles com criptografia e ninguém saberá que você possui esses arquivos.

Agora imagine que você não foi inteligente o suficiente para habilitar a compactação, e agora todos os outros, que por acaso também têm esses arquivos, a julgar pelos tamanhos dos blocos compactados e depois criptografados, saberão que você tem esses arquivos ultrassecretos neste arquivo sem mesmo precisando saber a chave de criptografia. Isso está muito longe de ser seguro. As pessoas podem ir para a cadeia por causa desse "recurso", serem torturadas ou pior.

não existe um programa de backup "seguro"

Isso então precisa de uma atualização.

Fast, secure, efficient backup program

Observe também seguro por padrão.

restic armazena apenas pedaços compactados, então o tamanho dos pedaços não é evidente para
alguém que não tem as chaves.

Na sexta-feira, 09 de agosto de 2019 às 02:09:23 AM -0700, Alexey Kopytko escreveu:

A compactação é proibida para a criptografia. Ele permite que um invasor adivinhe se um repositório criptografado contém um determinado arquivo, pois uma seção (pedaço) de um arquivo é compactado para o mesmo tamanho, independentemente da chave de criptografia usada. Esta é uma vulnerabilidade muito conhecida dos protocolos de criptografia, por isso a compressão foi removida do TLS 1.3.

Não vamos criar um problema conhecido onde não há nenhum, certo?

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente ou visualize-o no GitHub:
https://github.com/restic/restic/issues/21#issuecomment -519844526

-
(Escriu-me xifrat si saps PGP / Write cifrado se você conhece PGP)
Chave PGP 7CBD1DA5 - https://emailselfdefense.fsf.org/

Para quem deseja saber mais sobre essas questões de segurança, há um bom artigo que o descreve http://www.iacr.org/cryptodb/archive/2002/FSE/3091/3091.pdf
No meu entender, pode haver uma falha se o arquivo for fragmentado e, em seguida, compactado e criptografado. Mas se o arquivo for compactado antes da fragmentação, será um arquivo binário como qualquer outro e os ataques de texto simples se tornarão inúteis.

Mas se o arquivo for compactado antes da fragmentação, será um arquivo binário como qualquer outro e os ataques de texto simples se tornarão inúteis.

Está correto. Mas isso não ajudará exatamente com a desduplicação eficiente se bem entendi, pois um algoritmo de compressão pode usar um vocabulário diferente para cada versão de um arquivo, resultando em um resultado binário muito diferente. O que obviamente não desduplicará. Colocado de outra forma, só faz sentido compactar os pedaços resultantes.

O restic armazena apenas pedaços compactados, então o tamanho dos pedaços não é evidente para quem não tem as chaves

Isso é um alívio.

Meu ponto ainda é válido: que há muitas maneiras de adicionar uma fraqueza oculta em um programa quando ele implementa compactação junto com criptografia, portanto, é melhor não adicionar nenhuma. Mesmo os especialistas em criptografia que decidem sobre o TLS optaram por remover a compactação. Acho que eles tinham um raciocínio semelhante.

por falar nisso.:

However, it is important to note that these attacks have little security impact on, say, a bulkencryption application which compresses data before encrypting

...
também CRIME funciona se você tiver várias versões diferentes dos arquivos criptografados.
ou seja, várias execuções de backup (para diferentes repositórios, onde o invasor obteve todos eles)
e também só funciona com uma pequena quantidade de dados.

O CRIME precisa, mas você não. Imagine que você é um jornalista investigativo que recebeu um conjunto de arquivos ultrassecretos de sua fonte. Você faz o backup deles com criptografia e ninguém saberá que você possui esses arquivos.

Agora imagine que você não foi inteligente o suficiente para habilitar a compactação, e agora todos os outros, que por acaso também têm esses arquivos, a julgar pelos tamanhos dos blocos compactados e depois criptografados, saberão que você tem esses arquivos ultrassecretos neste arquivo sem mesmo precisando saber a chave de criptografia. Isso está muito longe de ser seguro. As pessoas podem ir para a cadeia por causa desse "recurso", serem torturadas ou pior.

Isso é besteira. porque só funciona com um tamanho de amostra pequeno. também pode ser possível ir para a prisão sem compressão. especialmente em algum momento, quando um invasor obtiver seus arquivos de backup, ele pode ser capaz de forçá-los com violência no futuro.
pode haver outros problemas de segurança que apareçam no futuro, etc ...
a discussão acabou se transformando em uma agitação sem sentido.

@sanmai , não entendi este exemplo com

Imagine que você é um jornalista investigativo ... Agora imagine que você não foi inteligente o suficiente para habilitar a compactação, e agora todos os outros, que por acaso também têm esses arquivos, a julgar pelos tamanhos dos blocos compactados e depois criptografados, saberão que você tem esses arquivos ultrassecretos neste arquivo sem precisar saber a chave de criptografia.

O que isso significa? Que alguém pode adivinhar que um instantâneo criptografado contém esses arquivos apenas olhando o tamanho? Isso pressupõe que os arquivos são compactados sozinhos ou junto com outros arquivos conhecidos. Mas então a mesma suposição pode ser feita com um shapshot não criptografado.

Na verdade, que tal fazer o gzip dos arquivos antes de fazer o backup? Isso abre uma vulnerabilidade de segurança também?

Acho que este exemplo é totalmente sem sentido: se você afirma que pode determinar se um instantâneo contém versões compactadas de alguns arquivos (arbitrários) conhecidos por você, também pode determinar se ele contém esses arquivos descompactados.

Não acredito que a compressão possa tornar a criptografia significativamente menos segura.

A maioria dos ataques de canal lateral de compressão envolvem vários fatores:
1) O invasor pode controlar a entrada
2) O invasor pode observar o tamanho da saída
3) Pequenas mudanças nos dados de entrada resultam em mudanças mensuráveis ​​no tamanho de saída
4) O invasor pode alterar a entrada e tentar novamente centenas de milhares de vezes

Ao contrário dos sistemas baseados na web, na grande maioria envolvendo backups restic, (1) e (2) raramente funcionarão ao mesmo tempo. Além disso, para a compactação baseada em bloco (3) não é realmente garantido, e para a maioria dos regimes de backup (4) certamente não é válido. Como a frequência de backup é geralmente uma vez por dia ou mais, levaria milhares de anos para ser capaz de manipular os dados e monitorar o tamanho da saída compactada para notar quaisquer diferenças significativas, e isso assumindo que nenhum outro dado está mudando, o que na maioria dos casos seria.

Se você estava fazendo backups em que o tamanho da saída era visível, talvez você queira desabilitar a compactação. Caso contrário, não há realmente nenhum ataque prático contra ele e não seria menos seguro tê-lo ativado.

O restic já faz deduplicação, o que o expõe aos mesmos ataques teóricos dos canais laterais de compressão, e ninguém reclamou disso que eu saiba.

O fato é que existem centenas ou milhares de usuários que se beneficiariam de um recurso de compressão sem quaisquer desvantagens. Podemos apenas deixar este problema de 5 anos para os desenvolvedores que estão trabalhando nele?

para ser honesto ... eu prefiro o conceito de restic ... mas fiz testes no meu caso de uso (muitos arquivos CSV e dumps SQL) e tive que mudar para borg.

Testei com quatro gerações de backup incremental e meus arquivos obtiveram uma compactação de 7: 1 e junto com a desduplicação alcancei> 20: 1. Não posso ignorar que desde já falei que pago o meu armazenamento de backup online por GB.

root<strong i="7">@xxxx</strong>:~# borg list
2019-08-08_14:37                     Thu, 2019-08-08 14:37:10 [5e113a8102f2bd7e40d100343f849dc73843d145011c7214d5fa0895927eb6d1]
2019-08-08_22:28                     Thu, 2019-08-08 22:28:21 [17d815d000212a576610b2fd5688ab87cce00039bb89f63722c6a7819dec1821]
2019-08-09_02:00                     Fri, 2019-08-09 02:00:23 [217c53b07f30dfbca584c49468cfa624a2445a005890220509c97715f7007e81]
2019-08-10_02:00                     Sat, 2019-08-10 02:00:10 [5dd45b8ccf0aa382bf00d5b08e1d5d88daae014f0a1a42b3e2b0fc368623bba0]
root<strong i="8">@xxxx</strong>:~# borg info
Repository ID: xxxx
Location: ssh://xxxx
Encrypted: Yes (repokey)
Cache: /var/lib/borg/cache/xxxx
Security dir: /var/lib/borg/security/xxxx
------------------------------------------------------------------------------
                       Original size      Compressed size    Deduplicated size
All archives:               69.02 GB             11.24 GB              2.80 GB

                       Unique chunks         Total chunks
Chunk index:                    9227                41812

O que isso significa? Que alguém pode _adivinhar_ que um instantâneo criptografado contém esses arquivos apenas olhando o tamanho? Isso pressupõe que os arquivos são compactados sozinhos ou junto com outros arquivos conhecidos. Mas então a mesma suposição pode ser feita com um shapshot não criptografado.

Exatamente. Divida um arquivo de texto simples em partes iguais, compacte-o e criptografe-o. Corte novamente, comprima e criptografe. Como os tamanhos dos arquivos criptografados não mudam no que diz respeito ao AES, você veria que, em ambos os casos, há uma gama de tamanhos que correspondem entre si, como uma impressão digital. Eles (e com eles quero dizer principalmente administrações de regimes opressores como o Irã ou a Rússia) podem fazer uma suposição razoável de que esses arquivos estão presentes aqui, o que, portanto, dá a razão, digamos, para continuar a torturar o suspeito. Não entendo porque vocês ficam tão ofendidos com essas ideias, não são fáceis de entender? Isso não é CRIME em si, é?

Mas, conforme observado antes por @viric , tecnicamente o Restic não é afetado por essas vulnerabilidades, pois os tamanhos dos pedaços não são vistos sem uma chave de criptografia. No entanto, se a compressão for adicionada em algum ponto, o Restic pode ainda não ser afetado agora, mas pode ser afetado mais tarde.

Adicionar compactação expõe o Restic a alguma vulnerabilidade adicional, visto que ele já realiza a desduplicação?

Se sua preocupação é um invasor adivinhar os tamanhos dos blocos compactados para inferir o tamanho descompactado, tudo bem, mas a compactação torna isso pior? Um invasor não teria as mesmas informações básicas?

Se um invasor pudesse ver os tamanhos não compactados e compactados de cada arquivo, a identificação poderia se tornar mais realista, mas isso não seria possível no restic.

No final das contas, a eliminação da duplicação já expõe você a todos os ataques teóricos nos quais eu vejo a compressão tendo um impacto, além disso, é claro, a compressão pode ser desativada para manter o estado atual das coisas, se isso se adequar melhor à sua situação.

Simplesmente não entendo por que você discute sobre hipotéticas preocupações de segurança sobre adivinhar a presença de um arquivo ao ver o tamanho de um fragmento criptografado .. ,,

Vocês usam ZIP ou GZ? Então você deve ficar bem.

Você acha que as autoridades iranianas podem adivinhar meu conteúdo por tamanhos? Então não use compressão (!). Isso simplesmente não significa que a compactação não deva estar disponível.

Acho que cobrimos todos os ângulos relevantes para adicionar compressão ao restic, muito obrigado por todas as suas contribuições.

Acho que devemos adicionar compactação e habilitá-la por padrão, mas permitir que os usuários desabilitem a compactação. Por favor, tenha paciência até que eu tenha mais algum tempo para trabalhar nisso.

Parece-me que essa discussão está fora de controle, então, estou bloqueando esse problema por enquanto. Se você quiser continuar esta discussão, vá para o fórum . Obrigado!

Esta página foi útil?
0 / 5 - 0 avaliações