Restic: Formato do repositório v2

Criado em 19 set. 2016  ·  51Comentários  ·  Fonte: restic/restic

Eu gostaria de começar a discussão sobre como mudar o formato do repositório para a versão 2. Isso é necessário para dar suporte à compressão (veja #21).

A lista a seguir será atualizada quando novas propostas chegarem.

Aceitaram:

  • Pacote de arquivos: Mova o cabeçalho para o início do arquivo. No momento, o cabeçalho está no final. Eu pensei que seria bom apenas escrever o arquivo e quando isso for feito, escrever o cabeçalho. No entanto, descobriu-se que, para poder repetir solicitações de back-end com falha, precisamos armazenar o arquivo localmente em buffer de qualquer maneira. Assim, podemos gravar o conteúdo (blobs) em um arquivo temporário e, em seguida, gravar o cabeçalho ao fazer o upload do arquivo do pacote para o back-end. Isso permite ler o cabeçalho com mais facilidade, pois não precisamos começar do final do arquivo.
  • Arquivos do pacote: No momento, o cabeçalho do arquivo do pacote é uma estrutura binária personalizada (consulte o documento de design ). Isso é inflexível, requer um analisador personalizado e não permite extensão sem alterar o formato do repositório. Gostaria de reconstruir o cabeçalho do pacote como uma estrutura de dados JSON, semelhante à maneira como os objetos de árvore são armazenados no repositório. Isso permite a extensão sem ter que alterar o formato de dados subjacente.
  • Arquivos/índice do pacote: Quando o cabeçalho do pacote for alterado, adicione suporte para compactação (algoritmo, comprimento compactado/descompactado). Adicione também o tamanho compactado/descompactado aos arquivos de índice.
  • Arquivos de instantâneos: permite instantâneos compactados para que muitos instantâneos se tornem utilizáveis ​​(cf #523)
  • Adicione um arquivo README em novos repositórios que descreva o que este diretório contém.
  • Remova o nome de usuário e o nome do host dos arquivos de chave (#2128)

Para ser discutido:

  • Existe uma maneira de adicionar códigos de correção de erros aos arquivos? Outras ideias para se recuperar de erros de dados?
  • Altere o formato do índice para melhorar o uso da memória
  • Adicione uma indireta de criptografia: anote no cabeçalho qual chave é usada para autenticação/criptografia de cada blob (para que possamos implementar o nº 187 mais facilmente mais tarde)

Adiado/rejeitado:

  • Mude para uma função de hash mais rápida (SHA3/Keccak/Blake2 em vez de SHA256)
  • Suporta criptografia assimétrica

Algo mais?

project repo v2 discussion

Comentários muito úteis

É importante ter tamanho descompactado no arquivo de índice ou no rodapé do pacote?

Sim: O cabeçalho do pacote descreve o que está no pacote e informa ao processo de extração o que esperar (em termos de algoritmo de compactação, tamanho não compactado e, posteriormente, também outros atributos, como a chave que foi usada para a criptografia). O mesmo precisa ser representado no índice, que foi introduzido para que o restic não precise procurar cada blob em um cabeçalho de pacote. Portanto, a mesma informação precisa estar presente lá.

Na minha opinião, o formato do repositório 2 == primeiro byte de dados do blob indica o formato de compactação, é tudo o que é necessário. Talvez um dos 255 formatos possíveis seja {comprimento descompactado de 64 bits}{dados compactados}.

Não gosto dessa ideia, ela torna o formato do arquivo mais complicado: Teremos informações de controle em dois lugares diferentes: no início de um blob e no cabeçalho. O cabeçalho é precisamente o local que contém as informações de controle.

Acho que a correção de erros é uma boa ideia para backup. Mas acho que é uma responsabilidade do sistema de arquivos.

Em princípio eu concordo, mas os sistemas de arquivos são coisas muito complicadas, e a propagação de erros (por exemplo, de erros de leitura/gravação da mídia) geralmente é sub-ótima. Para dados de backup altamente reduzidos (em termos de redundância, por exemplo, desduplicados), ainda acho uma boa ideia adicionar (ou oferecer para adicionar) outra camada de correção de erros.

Todos 51 comentários

Não tenho certeza sobre mover o cabeçalho para a frente. Eu sei que isso não está implementado atualmente, mas para um repositório local, ter o cabeçalho no final significa que podemos salvar uma cópia do arquivo.

Ponto interessante, obrigado. Ainda não tenho certeza de como julgar o que é melhor. Para backends remotos, também poderíamos (após algumas alterações na interface de backend) passar um io.Reader e talvez o stdlib possa usar sendfile para transmitir o arquivo diretamente do disco. hum.

Apenas para sua informação, tenho me perguntado por que você não usa o GCM, então executei os benchmarks. AES-CTR + Poly1305 é bastante rápido se a CPU não tiver AES-NI (50% mais rápido que o GCM integrado ao Go). Com o AES-NI, o código de montagem otimizado do Go para GCM é provavelmente imbatível.

Intel Xeon E312xx

restic:
BenchmarkEncrypt-4        50      32470322 ns/op     258.35 MB/s

stupidgcm:
Benchmark4kEncStupidGCM-4     200000         10620 ns/op     385.67 MB/s
Benchmark4kEncGoGCM-4         300000          5540 ns/op     739.22 MB/s

Intel Pentium G630 (sem AES-NI)

restic:
BenchmarkEncrypt-2            10     108468078 ns/op      77.34 MB/s

stupidgcm:
Benchmark4kEncStupidGCM-2          50000         24182 ns/op     169.38 MB/s
Benchmark4kEncGoGCM-2              20000         96391 ns/op      42.49 MB/s

Isso não pertence a este problema, mas vou responder de qualquer maneira:

Acho que na época em que comecei o restic, o Go não tinha uma versão otimizada do GCM. Além disso, não me senti à vontade para usar o GCM porque não o entendia, enquanto o papel Poly1305 era muito mais fácil de ler e entender.

Acho que seu benchmark processa blobs de dados muito menores, talvez se aproxime quando os blobs forem maiores.

Entendo. Sim, o GCM otimizado é bem recente, acho que a Cloudflare doou para o Go 1.5.

Em relação ao tamanho do bloco, o benchmark restic usa 8 MiB enquanto o estúpidogcm usa 4kiB . Tentei novamente com o tamanho de bloco de 8 MiB para o estúpidogcm, mas os resultados são praticamente idênticos.

Então não vamos perder tempo com isso, acho que CTR+Poly1305 é rápido o suficiente.

É importante ter tamanho descompactado no arquivo de índice ou no rodapé do pacote? Eu acho que seria bom saber isso apenas dentro do blob, então, menos alterações são necessárias no restic. Ele permite que novos recursos sejam conhecidos neste local adicional?

Na minha opinião, o formato do repositório 2 == primeiro byte de dados do blob indica o formato de compactação, é tudo o que é necessário. Talvez um dos 255 formatos possíveis seja {comprimento descompactado de 64 bits}{dados compactados}.

Acho que a correção de erros é uma boa ideia para backup. Mas acho que é uma responsabilidade do sistema de arquivos. Você também deseja implementar o RAID dentro do restic?

É importante ter tamanho descompactado no arquivo de índice ou no rodapé do pacote?

Sim: O cabeçalho do pacote descreve o que está no pacote e informa ao processo de extração o que esperar (em termos de algoritmo de compactação, tamanho não compactado e, posteriormente, também outros atributos, como a chave que foi usada para a criptografia). O mesmo precisa ser representado no índice, que foi introduzido para que o restic não precise procurar cada blob em um cabeçalho de pacote. Portanto, a mesma informação precisa estar presente lá.

Na minha opinião, o formato do repositório 2 == primeiro byte de dados do blob indica o formato de compactação, é tudo o que é necessário. Talvez um dos 255 formatos possíveis seja {comprimento descompactado de 64 bits}{dados compactados}.

Não gosto dessa ideia, ela torna o formato do arquivo mais complicado: Teremos informações de controle em dois lugares diferentes: no início de um blob e no cabeçalho. O cabeçalho é precisamente o local que contém as informações de controle.

Acho que a correção de erros é uma boa ideia para backup. Mas acho que é uma responsabilidade do sistema de arquivos.

Em princípio eu concordo, mas os sistemas de arquivos são coisas muito complicadas, e a propagação de erros (por exemplo, de erros de leitura/gravação da mídia) geralmente é sub-ótima. Para dados de backup altamente reduzidos (em termos de redundância, por exemplo, desduplicados), ainda acho uma boa ideia adicionar (ou oferecer para adicionar) outra camada de correção de erros.

Para códigos Reed-Solomon, há uma implementação Go pura em https://github.com/klauspost/reedsolomon com alguns dados de desempenho.

De acordo com https://www.usenix.org/legacy/event/fast09/tech/full_papers/plank/plank_html/ ZFEC deve ser mais rápido. Uma implementação está em https://gitlab.com/zfec/go-zfec que parece ser baseada em https://pypi.python.org/pypi/zfec.

Os ECCs são aplicados após a compactação e normalmente são intercalados no arquivo de dados, pois distribuí-los os torna mais robustos se os dados forem transferidos por canais de comunicação não confiáveis ​​ou ruidosos.

Nos grupos binários Usenet, eles usam arquivos separados (consulte https://en.wikipedia.org/wiki/Parchive) que contém as informações de ECC. Isso adicionaria apenas outro subdiretório ao layout do repositório e aplicar ECC às informações de gerenciamento do repositório (config, index, ...) também seria fácil. Mas não tenho certeza se fazer isso dessa maneira enfraqueceria o esquema ECC (talvez a robustez contra erros de cluster nas informações ECC diminua).

Obrigado pelas dicas. Encontrei a versão em PDF do artigo aqui: https://www.usenix.org/legacy/event/fast09/tech/full_papers/plank/plank.pdf

A implementação do ZFEC Go é apenas um wrapper em torno da biblioteca C.

Para ZFEC existe uma porta Go com adições (uso de goroutines) chamada jfec em [https://github.com/korvus81/jfec].

Eu adicionei um "projeto" (uma adição recente ao GitHub) para acompanhar a implementação do novo formato de repositório: https://github.com/restic/restic/projects/3

Algumas ideias que podem ser analisadas ao quebrar a compatibilidade com versões anteriores:

  • Mudar de sha256 para sha512

O uso de sha512 (ou sha512/256) em vez de sha256 resultará em maior velocidade de backup? Tanto quanto posso ver, isso é verdade para a maioria das plataformas, exceto para ARM.

Discussão sobre sincronização (https://github.com/syncthing/syncthing/issues/582)

Discussão Borg (https://github.com/jborg/attic/issues/209)

Documento sobre sha512/256 (https://eprint.iacr.org/2010/548.pdf)

  • Usando criptografia de chave pública em vez de uma senha simples

Atualmente todo mundo que tem acesso para escrever no repositório tem acesso para ler a partir dele. A criptografia de chave pública eliminaria isso e ainda permitiria a desduplicação com base nos hashes.

A aplicação de criptografia de chave pública aos blobs de dados funcionaria, mas não estou familiarizado o suficiente com como o restic processa a estrutura da árvore para saber se ela também pode ser implementada com sucesso para isso. Poderia possivelmente introduzir muita complexidade. Se apenas os blobs de dados estiverem ocultos, ainda haverá muitas informações nas árvores.

NaCl - https://godoc.org/golang.org/x/crypto/nacl/box

  • Identificação do repositório

Atualmente, não há como saber que você está olhando para um repositório restic quando se depara com o repositório. No momento, estamos vazando "created":"TIMESTAMP","username":"XXXXX","hostname":"XXXXX" nos arquivos principais. Sugiro ocultar essas informações e, em vez disso, incluir algumas informações sobre restic, como restic repository version X . Pode ser tão simples quanto um README.

Em relação às discussões anteriores; Sou altamente a favor da implementação de alguma forma de correção de erros.

@oysols Obrigado por adicionar suas ideias!

Vou adicionar meus pensamentos abaixo:

Mude de sha256 para sha512 (para velocidade)

No momento, não estou preocupado com a velocidade (restic já é muito rápido), então pelo menos para mim esse item é de baixa prioridade. Existe até uma versão otimizada do SHA256 para processadores compatíveis com SIMD para os quais podemos simplesmente alternar. Por outro lado, quando decidimos acelerar restic e o hash deve ser discutido, provavelmente prefiro Keccak (SHA3) ou Blake2, esses são (até onde eu sei, não fiz nenhum benchmark ainda) muito mais rapido.

Então, do meu ponto de vista, este item está adiado por enquanto.

Usando criptografia de chave pública em vez de uma senha simples

Esse recurso está planejado (consulte #187), mas é complicado e requer muita reflexão e várias mudanças importantes na infraestrutura. Eu também gostaria de adiar isso e fazer atualizações incrementais menores em vez de uma em que mudamos tudo -> adiado.

Identificação do repositório (adicione um arquivo README no repositório)

Ponto muito bom, podemos até adicionar isso agora sem quebrar nada.

Repositório "vazamento de informações" (removendo nome de usuário, nome de host e carimbo de data/hora criado de arquivos-chave)

Isso também é um bom ponto. Atualmente, usamos essas informações apenas para exibi-las junto com o ID da chave no comando key list . Podemos facilmente descartar username e host , o timestamp não dá muita informação, na maioria dos casos será o mesmo que a data de criação do arquivo.

Eu gostaria de deixar username e host e deixar o timestamp criado. Pensamentos?

Eu brinquei com https://github.com/klauspost/reedsolomon hoje e acho que podemos adicionar códigos de correção de erros com bastante facilidade ao final do arquivo do pacote (uma vez que movemos o cabeçalho do pacote para o início do arquivo ). Existem duas desvantagens, no entanto:

  • O tamanho do arquivo aumentará em ~ 14-30%, dependendo dos parâmetros que escolhermos para o reed-solomon
  • Precisaremos armazenar checksums (não necessariamente hashes criptográficos) de seções do arquivo de pacote no próprio arquivo de pacote, estes são necessários para reconstrução porque o algoritmo para reconstrução precisa saber quais partes do arquivo foram danificadas. Portanto, isso demora um pouco mais para calcular, embora possamos optar por usar uma soma de verificação rápida (como CRC ou algo assim).

Pensamentos?

A proteção da haste de dados poderia ser opcional então? Considero o aumento de tamanho mais do que marginal (é um ótimo recurso para outras pessoas, embora eu acredite!)

Deixe-me brincar um pouco com isso, para que eu possa ter uma ideia de quanto maior (ou menor?) o repositório será quando o ECC for combinado com a compactação. Talvez adicionemos dois tipos de códigos: Um para o cabeçalho do pacote e um (talvez opcional) para os dados.

solte nome de usuário e host

Parece uma boa ideia. Se quisermos manter as informações, elas podem ser adicionadas a um campo criptografado separado, da mesma forma que a chave mestra.

ECC: O tamanho do arquivo aumentará em ~ 14-30%,

Eu não acho que seja uma boa ideia incluir o ECC nos próprios arquivos do pacote. Eles não são úteis em um cenário típico de restauração e são usados ​​apenas no caso de os arquivos do pacote estarem danificados.

Sugiro que os dados de paridade sejam colocados em um diretório separado:

repo/data/1e/1ef7267...
repo/parity/1e/1ef7267...
  • A paridade será totalmente opcional e poderá ser criada após o backup.
  • Nenhuma lentidão das operações de restauração. Nenhuma largura de banda extra necessária para restauração.
  • Nomes de arquivos idênticos facilitam a identificação de dados de paridade corretos. Isso significa que os dados de paridade não são nomeados após seu próprio hash sha256, mas nenhum índice adicional será necessário. (A verificação dos dados de paridade deve ser feita verificando os arquivos do pacote, de qualquer maneira.)
  • O usuário tem uma ideia da quantidade de dados de paridade.

Não importa como é implementado; Com muitas camadas de compactação e criptografia, acho que algum tipo de ECC é necessário. Um bit errado pode causar muitos problemas.

Obrigado por seus comentários, vamos mover a discussão para uma questão separada que acabei de criar: #804.

Não posso deixar de ter a impressão de que existem dois grupos conversando entre si sobre códigos de correção de erros avançados em restic. Um grupo quer (apenas) proteger o repositório do bitrot, porque mesmo um único bitflip pode criar um grande problema em um repositório desduplicado. O outro grupo deseja usar códigos de eliminação para distribuir o repositório por vários domínios de falha (por exemplo, discos não RAID). Ambos os objetivos podem ser atendidos pelos códigos Reed-Solomon, mas exigem parâmetros e layouts de armazenamento diferentes.

Fiz uma verificação rápida no meu repositório com meu script python (https://github.com/oysols/restic-python).

header_length:        8688549
tree_length:         53898054
data_length:     146443506727
treeblobs:               8466
datablobs:             200975
packfiles:              29351
---- repo size by dir ----
            155   config
146 510 470 574   data
     27 538 629   index
          4 545   keys
          4 243   locks
         14 041   snapshots
          4 096   tmp
-----
Currently 116071 original files contained in the backup.

De um backup de 146 GB, os blobs de árvore têm apenas 54 MB e compactarão bem para cerca de um terço do espaço original, quando implementarmos a compactação.

Haveria uma melhoria de desempenho separando os blobs de árvore dos blobs de dados?

Parece que a maioria das operações executadas durante uma restauração são feitas com base nos blobs de árvore, antes de realmente restaurar os dados. Separá-los em arquivos de pacote separados minimizaria a quantidade de dados que precisam ser baixados para analisar a árvore de um backup. Dado o pequeno tamanho dos blobs de árvore, pode ser ainda mais rápido baixar todos os blobs de árvore antes de iniciar o processo de restauração.

Claro; Essa distribuição pode não ser a mesma para todos os repositórios.

Você acha que vale a pena pesquisar mais sobre isso?

Haveria uma melhoria de desempenho separando os blobs de árvore dos blobs de dados?

Talvez, esta seja uma das otimizações que tenho em mente para o futuro.

Além disso, também gostaria de adicionar um cache local para os metadados, para que não precise ser buscado no repositório. Isso deve melhorar muito a velocidade de muitas operações.

Haveria uma melhoria de desempenho separando os blobs de árvore dos blobs de dados?

Isso poderia, teoricamente, melhorar a operação prune , pois seria necessário menos reempacotamento se blobs de árvore e blobs de dados estivessem em arquivos de pacote separados (pode ser possível excluir um arquivo de pacote antigo em vez de reembalá-lo).

Eu já estou olhando para isso durante #842

gcm vs ctr: http://www.daemonology.net/blog/2009-06-11-cryptographic-right-answers.html

sym vs asym: a ideia é criptografar uma chave de "sessão", certo?

Não vamos discutir criptomoedas nesta edição, pois está adiada por enquanto. A questão relevante para discussões criptográficas assimétricas é #187. Além disso, gostaria de manter a discussão em alto nível até definirmos o caso de uso. Então podemos falar sobre criptografia de baixo nível.

Remova o nome de usuário e o nome do host dos arquivos de chave.

Grande vazamento de metadados!
Por exemplo, "username":"WorldBank\\JimYongKim" indica claramente um proprietário de alto nível .

Esperando que isso seja _removido_ (ou _encriptado_) desde que o primeiro binário do Windows foi compilado em janeiro de 2017.
Felizmente, examinei o backup antes de fazer o upload ou recomendar o Restic para colegas conscientes da privacidade.

Edit: O fuso horário do usuário também é mencionado em texto simples, o que também vai contra o princípio de confidencialidade .

Re: SHA3 - aqui está uma opinião sobre por que não vale a pena adotar (ainda?): https://www.imperialviolet.org/2017/05/31/skipsha3.html

Assim, acredito que o SHA-3 provavelmente não deve ser usado. Ele não oferece nenhuma vantagem convincente sobre o SHA-2 e traz muitos custos. O único argumento que posso creditar é que é bom ter uma função de hash de backup, mas SHA-256 e SHA-512 são comumente suportados e têm núcleos diferentes. Portanto, já temos duas funções de hash seguras implantadas e acho que não precisamos de outra.

Li o post e entendi os argumentos da agl. Para restic, isso não é tão relevante: estamos usando a função hash para (exclusivamente) identificar blobs, não como um bloco de construção de um protocolo criptográfico. Minha ideia de olhar para outras funções de hash foi principalmente que o SHA-256 é lento para computar, especialmente em sistemas de baixo custo. Outras funções de hash são muito mais rápidas (por exemplo, blake2).

Não tenho certeza se isso é uma coisa de formato repo: Que tal tornar a criptografia opcional? Estou pensando em backups que serão armazenados em um servidor de backup confiável que já tenha discos criptografados.

@mschiff Veja #1018 para essa discussão. ;)

Que tal fazer do tamanho da peça uma opção?
Atualmente eu tenho 4-6 MB por arquivo. Com menos arquivos, mas maiores, o backup remoto será muito mais rápido.

@fd0 escreveu:

No momento, não estou preocupado com a velocidade (restic já é muito rápido), então pelo menos para mim esse item é de baixa prioridade. Existe até uma versão otimizada do SHA256 para processadores compatíveis com SIMD para os quais podemos simplesmente alternar. Por outro lado, quando decidimos acelerar restic e o hash deve ser discutido, provavelmente prefiro Keccak (SHA3) ou Blake2, esses são (até onde eu sei, não fiz nenhum benchmark ainda) muito mais rapido.

Outra consideração para um algoritmo de hash mais rápido e com menos uso de CPU (como Blake2) seria o uso reduzido da bateria em laptops ao fazer backups sem estar conectado a uma fonte de alimentação.

Respondendo ao primeiro post:

Remova o nome de usuário e o nome do host dos arquivos de chave.

Isso seria substituído pelo nome da chave ou descrição de algum tipo? Acredito que alguma maneira de distinguir chaves diferentes (sem ter acesso à própria chave, por exemplo, ao revogar o acesso de alguma máquina) é útil para tornar o gerenciamento de chaves útil?

Uma nova sugestão: que tal usar uma chave diferente para blobs, árvores e instantâneos? Isso, AFAICS, permitiria um cenário em que o esquecimento e a remoção ocorressem no servidor de armazenamento de backup, e não nos clientes. Ao conceder ao servidor de armazenamento acesso à árvore e aos objetos de captura instantânea, ele deve ter informações suficientes para determinar quais objetos são necessários para quais capturas instantâneas e quais objetos não são mais usados. Se o servidor de armazenamento estiver comprometido, o acesso será obtido aos metadados da árvore, mas não ao conteúdo real do arquivo.

Isso pode ser um pouco mais forte permitindo apenas o acesso à lista de ids de objetos referenciados por uma árvore, sem permitir o acesso ao restante dos metadados (mas isso exigiria uma estrutura de dados adicional para cada árvore).

Se o acima for possível, isso abre o caminho para usar o tipo de armazenamento somente gravação/somente anexo (onde o cliente com backup não pode excluir backups, consulte #784), sem ter que sacrificar a remoção automática ou segurança de dados.

Em relação ao meu comentário anterior (poda sem precisar de acesso total aos dados): Isso também se aplica (possivelmente ainda mais forte) à verificação do backup. Faz sentido verificar um repositório no servidor de armazenamento por motivos de eficiência (AFAICS para verificar um repositório remotamente requer a transferência de todo o conteúdo) ou ao implementar suporte somente gravação verdadeiro (consulte https://github.com/ncw/rclone/issues /2499).

Além disso, para uma abordagem somente gravação verdadeira, são necessárias alterações para limitar quais arquivos ele precisa ler (de acordo com https://github.com/ncw/rclone/issues/2499#issuecomment-418609301). Não tenho certeza se isso também precisa de alterações no formato do repositório, se assim for, pode ser útil incluí-las aqui?

Verificar e remover um repositório no servidor remoto seria muito bom. Estou configurando o restic para fazer backup de vários hosts e gostaria de fazer todas as tarefas de manutenção no controle remoto para que a configuração do cliente seja o mais fácil possível e exija apenas que o backup seja executado regularmente.

Eu gostaria de discutir algumas adições (talvez opcionais) ao formato de arquivo de instantâneo:

  • Adicionar lista de arquivos de índice usados ​​(veja #1988)
  • Adicione a possibilidade de dados definidos pelo usuário (como descrições de adições, etc., não encontrou o problema no momento)
  • Adicione dados estatísticos como número de arquivos/blobs, espaço usado etc. Isso pode tornar a exibição de estatísticas muito mais rápida e também permite verificações extras

Sobre o formato do arquivo do pacote, gostaria de questionar por que não remover completamente o cabeçalho.
As informações são incluídas de forma redundante nos arquivos de índice. Houve alguma discussão sobre a adição de redundância para correção de erros, mas IMO isso deve (e pode) ser separado do formato de repositório geral e pode ser adicionado ou não adicionado a isso.

Para resumir: Se você não precisar ou quiser informações extras para correção de erros, não há necessidade de duplicar informações no cabeçalho do pacote e nos arquivos de índice. Os arquivos de índice são necessários para uma operação de alto desempenho e usados ​​em todos os lugares. Os cabeçalhos do pacote raramente são usados ​​- e se for apenas para verificação dupla ou correção de erros.

Outra proposta: Adicionar nome de usuário, nome de host e conteúdo do arquivo de configuração à seção data do arquivo de chave. Assim, remova completamente o arquivo de configuração.

Conforme já proposto, nome de usuário e host devem estar presentes apenas de forma criptografada. Para verificar se a chave derivada de KDF é válida, já é suficiente verificar o MAC da seção data criptografada.
IMO faz sentido colocar todas as informações necessárias para identificar a chave lá. Adicionar as informações armazenadas no arquivo config ATM apenas remove um arquivo extra do repositório e facilita a inicialização do repositório.

Desculpe pela pergunta "burra", mas há algum esforço sério em andamento para introduzir um formato aprimorado em breve? Acompanho essa questão há anos. restic atualmente não funciona bem para grandes conjuntos de dados ou quando há muitos instantâneos e requer muita memória. Parece que a falta de compactação e a grande sobrecarga dos metadados codificados em JSON são os grandes problemas do restic. Talvez o esforço tenha parado porque há uma necessidade percebida de alcançar a "perfeição"?

Também estou interessado no que o futuro traz para descansar. Especialmente em criptografia e compressão assimétrica.
A propósito, para uma nova função de hash, também existe o blake3 que é muito novo e também extremamente rápido: https://github.com/BLAKE3-team/BLAKE3
Se nenhuma decisão já foi tomada em relação a uma mudança na função hash, isso pode ser interessante.

Mais algumas ideias para repo.v2:

  • salve a árvore e os blobs de dados em diretórios diferentes (no passado, a árvore e os dados eram misturados, mas isso foi preterido com a introdução do cache).
  • adicione informações de 'hora de criação' aos blobs de dados.

Isso deve simplificar o suporte para armazenamento 'frio' com download muito lento ou caro, como o Amazon Glacier.

* save tree and data blobs to different directories (in the past tree and data was mixed, but this was deprecated with introduction of cache).

Eu não gosto dessa idéia. Isso torna muito mais fácil adivinhar os tamanhos dos arquivos de backup, enquanto eu não vejo um benefício nisso.

* add 'created time' info to data blobs.

Não vejo utilidade em adicionar um "tempo criado". Você pode dar um caso de uso?

Isso deve simplificar o suporte para armazenamento 'frio' com download muito lento ou caro, como o Amazon Glacier.

Eu diria que o suporte a "armazenamento frio" já pode ser alcançado com o formato de repositório atual, adicionando algumas possibilidades de ajuste fino para restic e armazenamento duplo dos arquivos nunca menos usados, por exemplo, em um cache local. Veja também #2504

* save tree and data blobs to different directories (in the past tree and data was mixed, but this was deprecated with introduction of cache).

Eu não gosto dessa idéia. Isso torna muito mais fácil adivinhar os tamanhos dos arquivos de backup, enquanto eu não vejo um benefício nisso.

O benefício é bem apresentado em comentários anteriores sobre esta questão:
https://github.com/restic/restic/issues/628#issuecomment -280436633
https://github.com/restic/restic/issues/628#issuecomment -280833405
Os resultados no primeiro comentário também mostram que misturar esses dois tipos de blobs não obscurece os tamanhos dos arquivos de maneira significativa.

postagem relacionada no fórum:
https://forum.restic.net/t/feature-using-an-index-for-restic-find/1773

@cfbao Os comentários aos quais você está se referindo são sobre a mistura de árvore e blob de dados em um arquivo de dados (pacote). Separar isso foi útil para habilitar o manuseio de cache. Isso também já está alterado no restic.

No entanto, ainda não vejo nenhum benefício em salvar blobs de árvore e dados em diretórios diferentes . Você pode dar um caso de uso? (IMO o tópico do fórum de localização não está relacionado - eu vou te responder lá)

Separar entradas de árvore e blob de dados em arquivos de índice separados (por exemplo, diretórios "index-data" e "index-tree") permitiria algumas melhorias, no entanto.

Os blobs de árvore já estão armazenados em arquivos de pacote separados (isso foi introduzido junto com o cache).
Apenas gravá-los em um diretório diferente abrirá uma maneira de melhorar o suporte de armazenamentos muito lentos para download (3-5 horas para o padrão Amazon Glacier). Como armazenar todos os metadados (índice + instantâneos + árvore no S3 regular e dados no Glacier).

2504 melhora um pouco, mas não gosto da ideia de depender de 'cache local' ou esperar muito para preencher o cache.

Eu gosto muito mais da ideia de ter algum proxy reverso que armazene tree+index+snapshots no S3 normal ou em qualquer outro lugar, mas coloque dados em arquivos profundos.
De qualquer forma, certamente é possível usar restic como está com algumas limitações. Mas algumas mudanças de formato podem melhorar/simplificar as coisas.

@cfbao , tanto quanto vejo no código restic find , não se beneficiará disso. Ele já caminha sobre instantâneos. Basicamente, é basicamente o mesmo que restic ls <all-snapshots> | grep something .

@dionorgua
Eu gosto da ideia de adicionar um repositório arbitrário como cache "adicional", onde todos, exceto os pacotes de dados, são armazenados em cache. Isso não precisa de uma mudança no layout do repositório e o IMO é muito mais flexível.
Já estou trabalhando nisso, veja também #2516, último comentário.

Talvez seja uma ideia estúpida, mas que tal um formato compatível com borg ou kopia ?

@aawsome

Os comentários aos quais você está se referindo são sobre a mistura de árvore e blob de dados em um arquivo de dados (pacote).

Verdadeiro. Foi mal. Sim, esta é a única coisa que me interessa.

Isso também já está alterado no restic.

Você sabe em qual PR/versão isso foi alterado? Na última vez que verifiquei meu repositório, notei uma mistura de dados e blobs de árvore nos mesmos arquivos de pacote. De alguma forma eu posso (provavelmente lentamente) converter meu repositório para ter uma melhor separação?

Ainda não vejo nenhum benefício em salvar blobs de árvore e dados em diretórios diferentes. Você pode dar um caso de uso?

Eu não faço ideia. Como mencionado anteriormente, eu realmente não me importo com isso.


@dionorgua

tanto quanto vejo no código restic find não se beneficiará disso. Ele já caminha sobre instantâneos. Basicamente, é basicamente o mesmo que restic ls| grep alguma coisa.

Separar blobs de árvore de blobs de dados não reduziria o número de chamadas de API necessárias para localizar? Se concentrado, o número de arquivos de pacote que contêm blobs de árvore seria reduzido e o restic pode baixar um número menor de arquivos inteiros em vez de buscar muitos segmentos de muitos arquivos de pacote. Isso é importante para back-ends relativamente lentos e com limitação de taxa mais rígida (por exemplo, Google Drive).

De qualquer maneira que eu possa (provavelmente lentamente) converter meu repositório para ter melhor
separação?

Com uma versão recente do restic, uma execução de 'prune' deve reconstruir esses pacotes mistos.
Observe que a implementação real de 'prune' gera muito tráfego para repositórios remotos. Com a reimplementação experimental em #2718, você só poderia reembalar pacotes mistos com tráfego mínimo.

Separar blobs de árvore de blobs de dados não reduziria o número de API
chamadas necessárias para encontrar?

Em uma versão recente e com um repositório que não possui pacotes mistos, todas as informações necessárias são armazenadas em cache localmente.

Outra ideia para um formato de repositório aprimorado:

Como vimos, é benéfico separar os arquivos de pacote por tipo de blob (blobs de árvore e de dados entram em arquivos de pacote diferentes). Não seria uma boa ideia separar também os arquivos de índice por tipo de blob? Os PRs de índice recentes já vão na direção de separar entradas de índice para árvore e blobs de dados na representação na memória.
Também existem otimizações possíveis para carregar apenas parte do índice

Fazer isso também no repositório permitiria uma representação mais compacta, por exemplo

{
  "supersedes": [
    "ed54ae36197f4745ebc4b54d10e0f623eaaaedd03013eb7ae90df881b7781452"
  ],
  "type": "data",
  "packs": [
    {
      "id": "73d04e6125cf3c28a299cc2f3cca3b78ceac396e4fcf9575e34536b26782413c",
      "blobs": [
        {
          "id": "3ec79977ef0cf5de7b08cd12b874cd0f62bbaf7f07f3497a5b1bbcc8cb39b1ce",
          "offset": 0,
          "length": 25
        },{
          "id": "9ccb846e60d90d4eb915848add7aa7ea1e4bbabfc60e573db9f7bfb2789afbae",
          "offset": 38,
          "length": 100
        },
        {
          "id": "d3dc577b4ffd38cc4b32122cabf8655a0223ed22edfd93b353dc0c3f2b0fdf66",
          "offset": 150,
          "length": 123
        }
      ]
    }, [...]
  ]
}
Esta página foi útil?
0 / 5 - 0 avaliações