Restic: Formato de repositorio v2

Creado en 19 sept. 2016  ·  51Comentarios  ·  Fuente: restic/restic

Me gustaría comenzar la discusión sobre cómo cambiar el formato del repositorio a la versión 2. Esto es necesario para admitir la compresión (ver #21).

La siguiente lista se actualizará cuando lleguen nuevas propuestas.

Aceptado:

  • Empaquetar archivos: Mueva el encabezado al inicio del archivo. Por el momento, el encabezado está al final. Pensé que sería bueno simplemente escribir el archivo y, cuando termine, escribir el encabezado. Sin embargo, resultó que para poder reintentar las solicitudes de back-end fallidas, necesitamos almacenar el archivo en el búfer localmente de todos modos. Entonces, podemos escribir el contenido (blobs) en un archivo temporal y luego escribir el encabezado al cargar el archivo del paquete en el backend. Esto permite leer el encabezado más fácilmente, ya que no necesitamos comenzar desde el final del archivo.
  • Paquete de archivos: Por el momento, el encabezado del archivo del paquete es una estructura binaria personalizada (consulte el documento de diseño ). Esto es inflexible, requiere un analizador personalizado y no permite la extensión sin cambiar el formato del repositorio. Me gustaría reconstruir el encabezado del paquete como una estructura de datos JSON, similar a la forma en que los objetos del árbol se almacenan en el repositorio. Esto permite la extensión sin tener que cambiar el formato de datos subyacente.
  • Paquete de archivos/Índice: cuando se cambia el encabezado del paquete, agregue soporte para compresión (algoritmo, longitud comprimida/sin comprimir). Agregue también el tamaño comprimido/sin comprimir a los archivos de índice.
  • Archivos de instantáneas: permita instantáneas empaquetadas para que se puedan utilizar muchas instantáneas (cf. n.º 523)
  • Agregue un archivo README en nuevos repositorios que describa lo que contiene este directorio.
  • Eliminar el nombre de usuario y el nombre de host de los archivos clave (#2128)

Para ser discutido:

  • ¿Hay alguna manera de agregar códigos de corrección de errores a los archivos? ¿Otras ideas para recuperarse de errores de datos?
  • Cambie el formato del índice para mejorar el uso de la memoria
  • Agregue una dirección indirecta de cifrado: escriba en el encabezado qué clave se usa para la autenticación/cifrado de cada blob (para que podamos implementar el #187 más fácilmente más adelante)

Aplazado/rechazado:

  • Cambie a una función hash más rápida (SHA3/Keccak/Blake2 en lugar de SHA256)
  • Admite criptografía asimétrica

¿Algo más?

project repo v2 discussion

Comentario más útil

¿Es importante tener un tamaño sin comprimir en el archivo de índice o en el pie de página del paquete?

Sí: el encabezado del paquete describe lo que hay en el paquete y esto le dice al proceso de extracción qué esperar (en términos de algoritmo de compresión, tamaño sin comprimir y luego también otros atributos como la clave que se usó para el cifrado). Lo mismo debe representarse en el índice, que se ha introducido para que restic no necesite buscar cada blob en el encabezado de un paquete. Entonces, la misma información debe estar presente allí.

En mi opinión, el formato de repositorio 2 == el primer byte de los datos del blob indica el formato de compresión, es todo lo que se necesita. Quizás uno de los 255 formatos posibles podría ser {longitud sin comprimir de 64 bits}{datos comprimidos}.

No me gusta esta idea, hace que el formato del archivo sea más complicado: Tendremos información de control en dos lugares diferentes: al comienzo de un blob y en el encabezado. El encabezado es precisamente la ubicación que contiene la información de control.

Creo que la corrección de errores es una buena idea para la copia de seguridad. Pero creo que es una responsabilidad del sistema de archivos.

En principio, estoy de acuerdo, pero los sistemas de archivos son cosas muy complicadas y la propagación de errores (por ejemplo, errores de lectura/escritura del medio) suele ser subóptima. Para datos de copia de seguridad muy reducidos (en términos de redundancia, por ejemplo, deduplicados), sigo pensando que es una buena idea agregar (u ofrecer agregar) otra capa de corrección de errores.

Todos 51 comentarios

No estoy seguro de mover el encabezado al frente. Sé que esto no está implementado actualmente, pero para un repositorio local, tener el encabezado al final significa que podemos guardar una copia del archivo.

Punto interesante, gracias. Todavía no estoy seguro de cómo juzgar qué es mejor. Para backends remotos también podríamos (después de algunos cambios en la interfaz de backend) simplemente pasar un io.Reader y luego tal vez stdlib pueda usar sendfile para transmitir el archivo directamente desde el disco. mmm

Solo para su información, me preguntaba por qué no usa GCM, así que ejecuté los puntos de referencia. AES-CTR + Poly1305 es bastante rápido si la CPU no tiene AES-NI (50 % más rápido que el GCM integrado de Go). Con AES-NI, el código ensamblador optimizado de Go para GCM probablemente sea imbatible.

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 (sin 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

Esto no pertenece a este problema, pero responderé de todos modos:

Creo que cuando comencé con restic, Go no tenía una versión optimizada de GCM. Además, no me sentía cómodo usando GCM porque no lo entendía, mientras que el documento Poly1305 era mucho más fácil de leer y entender.

Creo que su punto de referencia procesa blobs de datos mucho más pequeños, tal vez se acerque más cuando los blobs sean más grandes.

Veo. Sí, el GCM optimizado es bastante reciente, creo que Cloudflare lo donó para Go 1.5.

Con respecto al tamaño del bloque, el punto de referencia restic usa 8 MiB mientras que estupidgcm usa 4kiB . Volví a intentarlo con un tamaño de bloque de 8 MiB para estupidgcm, pero los resultados son prácticamente idénticos.

Así que no perdamos el tiempo con esto, creo que CTR+Poly1305 es lo suficientemente rápido.

¿Es importante tener un tamaño sin comprimir en el archivo de índice o en el pie de página del paquete? Creo que estaría bien saberlo solo dentro del blob, entonces, se necesitan menos cambios en restic. ¿Habilita alguna novedad para que se conozca en este lugar adicional?

En mi opinión, el formato de repositorio 2 == el primer byte de los datos del blob indica el formato de compresión, es todo lo que se necesita. Quizás uno de los 255 formatos posibles podría ser {longitud sin comprimir de 64 bits}{datos comprimidos}.

Creo que la corrección de errores es una buena idea para la copia de seguridad. Pero creo que es una responsabilidad del sistema de archivos. ¿También desea implementar RAID dentro de restic?

¿Es importante tener un tamaño sin comprimir en el archivo de índice o en el pie de página del paquete?

Sí: el encabezado del paquete describe lo que hay en el paquete y esto le dice al proceso de extracción qué esperar (en términos de algoritmo de compresión, tamaño sin comprimir y luego también otros atributos como la clave que se usó para el cifrado). Lo mismo debe representarse en el índice, que se ha introducido para que restic no necesite buscar cada blob en el encabezado de un paquete. Entonces, la misma información debe estar presente allí.

En mi opinión, el formato de repositorio 2 == el primer byte de los datos del blob indica el formato de compresión, es todo lo que se necesita. Quizás uno de los 255 formatos posibles podría ser {longitud sin comprimir de 64 bits}{datos comprimidos}.

No me gusta esta idea, hace que el formato del archivo sea más complicado: Tendremos información de control en dos lugares diferentes: al comienzo de un blob y en el encabezado. El encabezado es precisamente la ubicación que contiene la información de control.

Creo que la corrección de errores es una buena idea para la copia de seguridad. Pero creo que es una responsabilidad del sistema de archivos.

En principio, estoy de acuerdo, pero los sistemas de archivos son cosas muy complicadas y la propagación de errores (por ejemplo, errores de lectura/escritura del medio) suele ser subóptima. Para datos de copia de seguridad muy reducidos (en términos de redundancia, por ejemplo, deduplicados), sigo pensando que es una buena idea agregar (u ofrecer agregar) otra capa de corrección de errores.

Para los códigos Reed-Solomon, hay una implementación Go pura en https://github.com/klauspost/reedsolomon con algunos datos de rendimiento.

Según https://www.usenix.org/legacy/event/fast09/tech/full_papers/plank/plank_html/ ZFEC debería ser más rápido. Hay una implementación en https://gitlab.com/zfec/go-zfec que parece estar basada en https://pypi.python.org/pypi/zfec.

Los ECC se aplican después de la compresión y normalmente se intercalan en el archivo de datos, ya que su distribución los hace más sólidos si los datos se transfieren a través de canales de comunicación poco fiables o ruidosos.

En los grupos binarios de Usenet, usan archivos separados (consulte https://en.wikipedia.org/wiki/Parchive) que contienen la información de ECC. Eso agregaría solo otro subdirectorio al diseño del repositorio y aplicar ECC a la información de administración del repositorio (configuración, índice, ...) también sería fácil. Pero no estoy seguro de si hacerlo de esa manera debilitaría el esquema ECC (tal vez disminuya la solidez contra los errores de clúster dentro de la información ECC).

Gracias por los consejos. Encontré la versión en PDF del documento aquí: https://www.usenix.org/legacy/event/fast09/tech/full_papers/plank/plank.pdf

La implementación de ZFEC Go es solo un contenedor alrededor de la biblioteca C.

Para ZFEC hay un puerto Go con adiciones (uso de goroutines) llamado jfec en [https://github.com/korvus81/jfec].

Agregué un "proyecto" (una adición reciente a GitHub) para rastrear la implementación del nuevo formato de repositorio: https://github.com/restic/restic/projects/3

Algunas ideas que podrían analizarse al romper la compatibilidad con versiones anteriores:

  • Cambiar de sha256 a sha512

¿El uso de sha512 (o sha512/256) en lugar de sha256 dará como resultado una mayor velocidad de copia de seguridad? Por lo que puedo ver, esto es cierto para la mayoría de las plataformas, excepto para ARM.

Debate sobre sincronización (https://github.com/syncthing/syncthing/issues/582)

Discusión de Borg (https://github.com/jborg/attic/issues/209)

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

  • Uso de cifrado de clave pública en lugar de una contraseña simple

Actualmente, todos los que tienen acceso para escribir en el repositorio tienen acceso para leerlo. El cifrado de clave pública eliminaría esto y aún permitiría la deduplicación basada en los hash.

La aplicación de cifrado de clave pública a los blobs de datos funcionaría, pero no estoy lo suficientemente familiarizado con la forma en que restic procesa la estructura de árbol para saber si también podría implementarse con éxito para eso. Posiblemente podría introducir mucha complejidad. Si solo se ocultan los blobs de datos, todavía hay mucha información en los árboles.

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

  • Identificación del repositorio

Actualmente, no hay forma de saber que está mirando un repositorio restic cuando se topa con el repositorio. Actualmente estamos filtrando "created":"TIMESTAMP","username":"XXXXX","hostname":"XXXXX" en los archivos clave. Sugeriría ocultar esta información y, en su lugar, incluir información sobre restic, como restic repository version X . Puede ser tan simple como un README.

En cuanto a discusiones anteriores; Estoy muy a favor de implementar alguna forma de corrección de errores.

@oysols ¡ Gracias por agregarte ideas!

Agregaré mis pensamientos a continuación:

Cambiar de sha256 a sha512 (para velocidad)

Por el momento, no me preocupa la velocidad (restic ya es muy rápido), por lo que al menos para mí este elemento tiene poca prioridad. Incluso existe una versión optimizada de SHA256 para procesadores compatibles con SIMD a la que simplemente podemos cambiar. Por otro lado, cuando decidamos acelerar el restic y se discuta el hash, probablemente preferiría Keccak (SHA3) o Blake2, esos son (hasta donde yo sé, no hice ningún punto de referencia todavía) mucho mas rápido.

Entonces, desde mi punto de vista, este artículo se pospone por ahora.

Uso de cifrado de clave pública en lugar de una contraseña simple

Esta función está planificada (consulte el n.° 187), pero es complicada y requiere mucha reflexión y varios cambios importantes en la infraestructura. También me gustaría posponer esto y preferir hacer actualizaciones incrementales más pequeñas en lugar de una en la que cambiamos todo -> pospuesto.

Identificación del repositorio (añadir un archivo README en el repositorio)

Muy buen punto, incluso podemos agregar eso ahora sin romper nada.

Repositorio "fuga de información" (eliminación de nombre de usuario, nombre de host y marca de tiempo creada de archivos clave)

Ese también es un buen punto. Actualmente, solo usamos esta información para mostrarla junto con la ID de clave en el comando key list . Podemos soltar fácilmente username y host , la marca de tiempo no da mucha información, en la mayoría de los casos será la misma que la fecha de creación del archivo.

Me gustaría soltar username y host y dejar la marca de tiempo creada. ¿Pensamientos?

He jugado con https://github.com/klauspost/reedsolomon hoy y creo que podemos agregar códigos de corrección de errores con bastante facilidad al final del archivo del paquete (una vez que movemos el encabezado del paquete al inicio del archivo ). Sin embargo, hay dos inconvenientes:

  • El tamaño del archivo aumentará en ~14-30%, dependiendo de los parámetros que elijamos para reed-solomon
  • Necesitaremos almacenar sumas de verificación (no necesariamente hashes criptográficos) de secciones del archivo del paquete en el propio archivo del paquete, estas son necesarias para la reconstrucción porque el algoritmo de reconstrucción necesita saber qué partes del archivo se han dañado. Eso toma un poco más de tiempo para calcular, aunque podemos optar por usar una suma de verificación rápida (como CRC o algo así).

¿Pensamientos?

Entonces, ¿la protección de la barra de datos podría ser opcional? Considero que el aumento de tamaño es más que marginal (¡aunque creo que es una gran característica para otras personas!)

Permítanme jugar un poco con esto, para que pueda tener una idea de cuánto más grande (¿o más pequeño?) será el repositorio cuando ECC se combine con la compresión. Tal vez agreguemos dos tipos de códigos: uno para el encabezado del paquete y otro (quizás opcional) para los datos.

soltar nombre de usuario y host

Suena como una buena idea. Si queremos conservar la información, se podría agregar a un campo encriptado separado, de la misma manera que la clave maestra.

ECC: el tamaño del archivo aumentará ~14-30%,

No creo que sea una buena idea incluir el ECC en los archivos del paquete. No son útiles en un escenario de restauración típico y solo se usan en caso de que los archivos del paquete estén dañados.

Sugiero que los datos de paridad se coloquen en un directorio separado:

repo/data/1e/1ef7267...
repo/parity/1e/1ef7267...
  • La paridad será completamente opcional y se puede crear después de la copia de seguridad.
  • Sin ralentización de las operaciones de restauración. No se necesita ancho de banda adicional para la restauración.
  • Los nombres de archivo idénticos facilitan la identificación de datos de paridad correctos. Esto significará que los datos de paridad no tienen el nombre de su propio hash sha256, pero no se necesitará ningún índice adicional. (La verificación de los datos de paridad debe realizarse verificando los archivos del paquete, de todos modos).
  • El usuario se hace una idea de la cantidad de datos de paridad.

No importa cómo se implemente; Con muchas capas de compresión y cifrado, creo que es necesario algún tipo de ECC. Un bit equivocado puede causar muchos problemas.

Gracias por sus comentarios, pasemos la discusión a un tema separado que acabo de crear: #804.

No puedo evitar tener la impresión de que hay dos grupos hablando entre sí sobre los códigos de corrección de errores de reenvío en restic. Un grupo quiere (solo) proteger el repositorio de bitrot, porque incluso un solo bitflip puede crear un gran problema en un repositorio deduplicado. El otro grupo quiere usar códigos de borrado para distribuir el repositorio en múltiples dominios de fallas (por ejemplo, discos que no son RAID). Ambos objetivos pueden cumplirse con los códigos Reed-Solomon, pero requieren diferentes parámetros y diferentes diseños de almacenamiento.

Realicé una revisión rápida de mi repositorio con mi script de 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 una copia de seguridad de 146 GB, los blobs de árbol son solo 54 MB y se comprimirán bien hasta aproximadamente un tercio del espacio original, cuando implementemos la compresión.

¿Habría una mejora en el rendimiento al separar los blobs de árbol de los blobs de datos?

Parece que la mayoría de las operaciones realizadas durante una restauración se realizan en función de los blobs del árbol, antes de restaurar los datos. Separarlos en archivos de paquetes separados minimizaría la cantidad de datos que deben descargarse para analizar el árbol de una copia de seguridad. Dado el pequeño tamaño de los blobs de árbol, incluso podría ser más rápido descargar todos los blobs de árbol antes de iniciar el proceso de restauración.

Por supuesto; Esta distribución podría no ser la misma para todos los repositorios.

¿Crees que vale la pena investigar más sobre esto?

¿Habría una mejora en el rendimiento al separar los blobs de árbol de los blobs de datos?

Tal vez, esta es una de las optimizaciones que tengo en mente para el futuro.

Aparte de esto, también me gustaría agregar un caché local para los metadatos, de modo que no sea necesario obtenerlos del repositorio en absoluto. Esto debería mejorar en gran medida la velocidad de muchas operaciones.

¿Habría una mejora en el rendimiento al separar los blobs de árbol de los blobs de datos?

En teoría, esto podría mejorar el funcionamiento prune , ya que se necesitaría menos reempaquetado si los blobs de árbol y los blobs de datos estuvieran en archivos de paquete separados (podría ser posible eliminar al por mayor un archivo de paquete antiguo en lugar de volver a empaquetarlo).

Ya estoy viendo eso durante el #842

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

sym vs asym: la idea es cifrar con clave pública una clave de "sesión", ¿verdad?

No hablemos de criptografía en este número, ya que se pospone por ahora. El tema relevante para las discusiones criptográficas asimétricas es el #187. Además, me gustaría mantener la discusión en un nivel alto hasta que hayamos concretado el caso de uso. Entonces podemos hablar de criptografía de bajo nivel.

Eliminar el nombre de usuario y el nombre de host de los archivos clave.

¡Gran fuga de metadatos!
Por ejemplo, "username":"WorldBank\\JimYongKim" indica claramente que es un propietario de alto rango.

Esperando a que esto se _elimine_ (o _cifre_) desde que se compiló el primer binario de Windows en enero de 2017.
Afortunadamente, examiné la copia de seguridad antes de cargar o recomendar Restic a personas conscientes de la privacidad.

Editar: la zona horaria del usuario también se menciona en texto sin formato, lo que también va en contra del principio de confidencialidad .

Re: SHA3: aquí hay una opinión sobre por qué no vale la pena adoptarlo (¿todavía?): https://www.imperialviolet.org/2017/05/31/skipsha3.html

Por lo tanto, creo que SHA-3 probablemente no debería usarse. No ofrece ninguna ventaja convincente sobre SHA-2 y conlleva muchos costos. El único argumento que puedo acreditar es que es bueno tener una función hash de respaldo, pero tanto SHA-256 como SHA-512 son comúnmente compatibles y tienen diferentes núcleos. Así que ya tenemos implementadas dos funciones hash seguras y no creo que necesitemos otra.

He leído la publicación y entiendo los argumentos de agl. Para restic, eso no es tan relevante: estamos usando la función hash para (únicamente) identificar blobs, no como un componente básico de un protocolo criptográfico. Mi idea de observar otras funciones hash fue principalmente que SHA-256 es lento de calcular, especialmente en sistemas de gama baja. Otras funciones hash son mucho más rápidas (por ejemplo, blake2).

No estoy seguro de si se trata de una cosa de formato repo: ¿Qué tal si hacemos que el cifrado sea opcional? Estoy pensando en copias de seguridad que se almacenarán en un servidor de copia de seguridad de confianza que ya tenga discos cifrados.

@mschiff Ver #1018 para esa discusión. ;)

¿Qué tal hacer que el tamaño de la pieza sea una opción?
Actualmente tengo 4-6 MB por archivo. Con menos archivos pero más grandes, la copia de seguridad remota será mucho más rápida.

@fd0 escribió:

Por el momento, no me preocupa la velocidad (restic ya es muy rápido), por lo que al menos para mí este elemento tiene poca prioridad. Incluso existe una versión optimizada de SHA256 para procesadores compatibles con SIMD a la que simplemente podemos cambiar. Por otro lado, cuando decidamos acelerar el restic y se discuta el hash, probablemente preferiría Keccak (SHA3) o Blake2, esos son (hasta donde yo sé, no hice ningún punto de referencia todavía) mucho mas rápido.

Otra consideración para un algoritmo hash más rápido y menos intensivo en la CPU (como Blake2) sería reducir el uso de la batería en las computadoras portátiles al realizar copias de seguridad mientras no están conectadas a una fuente de alimentación.

Respondiendo al primer mensaje:

Eliminar el nombre de usuario y el nombre de host de los archivos clave.

¿Se reemplazaría esto por un nombre clave o una descripción de algún tipo? Creo que alguna forma de distinguir diferentes claves (sin tener acceso a la clave en sí, por ejemplo, al revocar el acceso para alguna máquina) es útil para que la administración de claves sea útil.

Una nueva sugerencia: ¿Qué tal usar una clave diferente para blobs, árboles e instantáneas? Esto, AFAICS, habilitaría un escenario donde el olvido y la poda ocurren en el servidor de almacenamiento de respaldo, en lugar de en los clientes. Al dar acceso al servidor de almacenamiento a los objetos de árbol e instantánea, debería tener suficiente información para determinar qué objetos son necesarios para qué instantáneas y qué objetos ya no se usan. Si el servidor de almacenamiento se ve comprometido, se obtiene acceso a los metadatos del árbol, pero no al contenido real del archivo.

Esto se puede hacer un poco más fuerte al permitir solo el acceso a la lista de ID de objetos a los que hace referencia un árbol, sin permitir el acceso al resto de los metadatos (pero esto requeriría una estructura de datos adicional para cada árbol).

Si lo anterior fuera posible, esto abre el camino para usar el tipo de almacenamiento de solo escritura / solo agregar (donde el cliente respaldado no puede eliminar las copias de seguridad, consulte # 784), sin tener que sacrificar la poda automática o seguridad de datos.

Con respecto a mi comentario anterior (poda sin necesidad de acceso completo a los datos): Esto también se aplica (posiblemente aún más fuerte) para verificar la copia de seguridad. Tiene sentido verificar un repositorio en el servidor de almacenamiento por razones de eficiencia (AFAICS para verificar un repositorio de forma remota requiere transferir todo el contenido), o cuando se implementa un verdadero soporte de solo escritura (consulte https://github.com/ncw/rclone/issues /2499).

Además, para un verdadero enfoque de solo escritura, se necesitan cambios para limitar qué archivos necesita leer (según https://github.com/ncw/rclone/issues/2499#issuecomment-418609301). No estoy seguro de si eso también necesita cambios en el formato del repositorio, si es así, ¿podría ser útil incluirlos aquí?

Verificar y podar un repositorio en el servidor remoto sería realmente genial. Estoy en el proceso de configurar restic para realizar copias de seguridad de varios hosts y me gustaría realizar todas las tareas de mantenimiento en el control remoto para que la configuración del cliente sea lo más fácil posible y solo requiera que la copia de seguridad se ejecute con regularidad.

Me gustaría discutir algunas adiciones (quizás opcionales) al formato de archivo de instantánea:

  • Agregar lista de archivos de índice usados ​​(ver #1988)
  • Agregue la posibilidad de datos definidos por el usuario (como descripciones de adiciones, etc., no encontró el problema en este momento)
  • Agregue datos estadísticos como la cantidad de archivos/blobs, espacio utilizado, etc. Esto podría hacer que la visualización de estadísticas sea mucho más rápida y también permite verificaciones adicionales

Sobre el formato de archivo del paquete, me gustaría preguntar por qué no eliminar completamente el encabezado.
La información se incluye de forma redundante en los archivos de índice. Ha habido cierta discusión sobre agregar redundancia para la corrección de errores, pero en mi opinión, esto debería (y puede) separarse del formato de repositorio general y puede agregarse o no agregarse además de eso.

En pocas palabras: si no necesita o desea información adicional para la corrección de errores, no es necesario duplicar la información en el encabezado del paquete y los archivos de índice. Los archivos de índice son necesarios para una operación eficaz y se usan en todas partes. Los encabezados de paquete rara vez se usan, y solo para verificar dos veces o corregir errores.

Otra propuesta: agregue el nombre de usuario, el nombre de host y el contenido del archivo de configuración a la sección data del archivo de claves. Por lo tanto, elimine completamente el archivo de configuración.

Como ya se propuso, el nombre de usuario y el host deben estar presentes solo en forma cifrada. Para verificar si la clave derivada de KDF es válida, ya es suficiente verificar el MAC de la sección cifrada data .
En mi opinión, tiene sentido poner toda la información necesaria para identificar la clave allí. Agregar la información que se almacena en el archivo config ATM simplemente elimina un archivo adicional del repositorio y facilita la inicialización del repositorio.

Perdón por la pregunta "tonta", pero ¿hay algún esfuerzo serio para introducir un formato mejorado en el corto plazo? Llevo años siguiendo este tema. restic actualmente no funciona bien para grandes conjuntos de datos, o cuando hay muchas instantáneas, y requiere mucha memoria. Parece que la falta de compresión y la gran sobrecarga de los metadatos codificados en JSON son los grandes problemas de restic. ¿Quizás el esfuerzo se ha estancado porque se percibe la necesidad de lograr la "perfección"?

También estoy interesado en lo que el futuro trae para descansar. Especialmente en criptografía asimétrica y compresión.
Por cierto, para una nueva función hash, también está blake3, que es muy nuevo y extremadamente rápido: https://github.com/BLAKE3-team/BLAKE3
Si aún no se tomó una decisión con respecto a un cambio en la función hash, esto podría ser interesante.

Algunas ideas más para repo.v2:

  • guarde el árbol y los blobs de datos en diferentes directorios (en el pasado, el árbol y los datos se mezclaban, pero esto quedó en desuso con la introducción de la memoria caché).
  • agregue información de 'tiempo de creación' a los blobs de datos.

Esto debería simplificar el soporte para almacenamiento 'frío' con descargas muy lentas o costosas como 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).

No me gusta esta idea. Hace que adivinar el tamaño de los archivos de las copias de seguridad sea mucho más fácil, aunque no veo ningún beneficio en ello.

* add 'created time' info to data blobs.

No veo ningún uso en agregar un "tiempo creado". ¿Puedes dar un caso de uso?

Esto debería simplificar el soporte para almacenamiento 'frío' con descargas muy lentas o costosas como Amazon Glacier.

Diría que el soporte de "almacenamiento en frío" ya se puede lograr con el formato de repositorio actual agregando algunas posibilidades de ajuste fino para restringir y almacenar dos veces los archivos que se usan con menos frecuencia, por ejemplo, en un caché local. Ver también #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).

No me gusta esta idea. Hace que adivinar el tamaño de los archivos de las copias de seguridad sea mucho más fácil, aunque no veo ningún beneficio en ello.

El beneficio está bien expuesto en comentarios anteriores sobre este mismo tema:
https://github.com/restic/restic/issues/628#issuecomment-280436633
https://github.com/restic/restic/issues/628#issuecomment-280833405
Los resultados del primer comentario también muestran que la combinación de estos dos tipos de blobs no oscurece el tamaño de los archivos de forma significativa.

mensaje relacionado en el foro:
https://forum.restic.net/t/feature-using-an-index-for-restic-find/1773

@cfbao Los comentarios a los que se refiere son sobre la combinación de árbol y blob de datos dentro de un archivo de datos (paquete). Separar esto fue útil para habilitar el manejo de caché. Esto también ya está cambiado dentro de restic.

Sin embargo, todavía no veo ningún beneficio en guardar blobs de datos y árboles en diferentes directorios . ¿Puedes dar un caso de uso? (En mi opinión, el tema del foro de búsqueda no está relacionado; te responderé allí)

Sin embargo, separar las entradas del árbol y del blob de datos en archivos de índice separados (por ejemplo, los directorios "index-data" y "index-tree") permitiría algunas mejoras.

Los blobs de árbol ya están almacenados en archivos de paquete separados (esto se introdujo junto con el caché).
Simplemente escribirlos en un directorio diferente abrirá una manera de mejorar el soporte de almacenamientos de descarga muy lenta (3-5 horas para el estándar de Amazon Glacier). Como almacenar todos los metadatos (índice+instantáneas+árbol en S3 normal y datos en Glacier).

2504 lo mejora un poco, pero no me gusta la idea de depender del 'caché local' o esperar mucho para llenar el caché.

Me gusta mucho más la idea de tener un proxy inverso que almacene tree+index+snapshots en S3 normal o en cualquier otro lugar, pero coloque los datos en un archivo profundo.
En cualquier caso, seguramente es posible usar restic tal como está con algunas limitaciones. Pero algunos cambios de formato pueden mejorar/simplificar las cosas.

@cfbao por lo que veo del código restic find no se beneficiará de esto. Ya camina sobre instantáneas. Básicamente es casi lo mismo que restic ls <all-snapshots> | grep something .

@dionorgua
Me gusta la idea de agregar un repositorio arbitrario como caché "adicional" donde se almacena en caché todo excepto los paquetes de datos. Esto no necesita un cambio en el diseño del repositorio y IMO es mucho más flexible.
Ya estoy trabajando en esto, vea también #2516, último comentario.

Tal vez sea una idea estúpida, pero ¿qué pasa con un formato compatible con borg o kopia?

@awsome

Los comentarios a los que se refiere son sobre la combinación de árbol y blob de datos dentro de un archivo de datos (paquete).

Cierto. Mi error. Sí, esto es lo único que me importa.

Esto también ya está cambiado dentro de restic.

¿Sabes en qué PR/versión se cambió esto? La última vez que revisé mi repositorio, noté una combinación de blobs de datos y árboles en los mismos archivos del paquete. ¿Alguna forma en que pueda (probablemente lentamente) convertir mi repositorio para tener una mejor separación?

Todavía no veo ningún beneficio de guardar blobs de árboles y datos en diferentes directorios. ¿Puedes dar un caso de uso?

No tengo ni idea. Como mencioné antes, realmente no me importa esto.


@dionorgua

por lo que veo del código restic find no se beneficiará de esto. Ya camina sobre instantáneas. Básicamente es casi lo mismo que restic ls| grep algo.

¿Separar los blobs de árbol de los blobs de datos no reduciría la cantidad de llamadas API necesarias para encontrar? Si se concentra, se reduciría la cantidad de archivos de paquete que contienen blobs de árbol, y restic puede descargar una cantidad menor de archivos completos en lugar de obtener muchos segmentos de muchos archivos de paquete. Esto es importante para los backends que son relativamente lentos y tienen una limitación de velocidad más estricta (por ejemplo, Google Drive).

Cualquier forma en que pueda (probablemente lentamente) convertir mi repositorio para tener una mejor
¿separación?

Con una versión reciente de restic, una ejecución de 'prune' debería reconstruir estos paquetes mixtos.
Tenga en cuenta que la implementación real de 'prune' genera mucho tráfico para repositorios remotos. Con la reimplementación experimental en el n.º 2718, solo podrá volver a empaquetar paquetes mixtos con un tráfico mínimo.

Separar los blobs de árbol de los blobs de datos no reduciría la cantidad de API
llamadas necesarias para encontrar?

En una versión reciente y con un repositorio que no tiene paquetes mixtos, toda la información necesaria se almacena en caché localmente.

Otra idea para un formato de repositorio mejorado:

Como hemos visto, es beneficioso separar los archivos de paquete por tipo de blob (los blobs de árbol y de datos van en diferentes archivos de paquete). ¿No sería una buena idea separar también los archivos de índice por tipo de blob? Las relaciones públicas de índice recientes ya van en la dirección de separar las entradas de índice para blobs de datos y árboles en la representación en memoria.
También hay posibles optimizaciones para cargar solo una parte del índice.

Hacer esto también en el repositorio permitiría una representación más compacta, por ejemplo

{
  "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
        }
      ]
    }, [...]
  ]
}
¿Fue útil esta página
0 / 5 - 0 calificaciones