Restic: Mettre en œuvre la compression

Créé le 15 nov. 2014  ·  167Commentaires  ·  Source: restic/restic

Ce problème est un problème de suivi aux fins de suivi des discussions et d'autres problèmes/RP liés à la demande de mise en œuvre de la compression.

Les problèmes/RP suivants sont liés à ce sujet (et peuvent donc être clos en faveur de celui-ci) :

  • RP #2441
backend backup feature suggestion tracking

Commentaire le plus utile

Je pense qu'il y a eu suffisamment de discussions sur la question de l'ajout de compression. Je peux voir que c'est une fonctionnalité très attendue. Je m'attaquerai à cela après avoir terminé le nouveau code de l'archiveur (voir #1494).

S'il vous plaît ne pas ajouter d'autres commentaires, merci!

Tous les 167 commentaires

Lors de l'implémentation, ajoutez des benchmarks et surtout regardez l'utilisation de la mémoire avec -benchmem et benchcmp !

lz4, lzo, lzma, nul. bz2 est plutôt lent.

Snappy est rapide avec une compression modérée

Si la compression est effectuée par bloc, il convient de veiller à ce qu'elle ne laisse pas les sauvegardes restic ouvertes aux attaques par filigrane/empreintes digitales.

Il s'agit essentiellement du même problème dont nous avons discuté concernant la prise d'empreinte du processus de déduplication CDC :
Avec CDC "naïf", un fichier "texte en clair connu" peut être vérifié pour exister dans la sauvegarde si la taille des blocs individuels peut être observée par un attaquant, en utilisant CDC sur le fichier en parallèle et en comparant la quantité résultante de morceaux et d'individus. longueurs de morceaux.
Comme indiqué précédemment, cela peut être quelque peu atténué en salant l'algorithme CDC avec une valeur secrète, comme cela se fait dans le grenier.

Avec le CDC salé, je suppose que la compression se produirait sur chaque morceau individuel, après avoir divisé le fichier problématique en morceaux. Les morceaux restants sont compris entre 512 Ko et 8 Mo (mais pas uniformément répartis - n'est-ce pas ?).

  • L'attaquant sait que l'algorithme CDC utilise un sel secret, de sorte qu'il génère une plage de fragments composée des premiers 512 Ko à 8 Mo du fichier, un pour chaque longueur de fragment valide. L'attaquant est également capable de déterminer la longueur des morceaux compressés.
  • L'attaquant compresse ensuite ce morceau à l'aide de l'algorithme de compression.
  • L'attaquant compare les longueurs des morceaux résultants au premier morceau dans les jeux de sauvegarde restic.
  • SI une longueur de bloc correspondante est trouvée, l'attaquant répète l'exercice avec le prochain morceau, et le prochain morceau, et le prochain morceau, ... et le prochain morceau.
  • Je pense qu'avec des fichiers suffisamment volumineux, et compte tenu du fait que l'algorithme CDC est "biaisé" (en l'absence de mots meilleurs) vers la génération de blocs d'environ 1 Mo, cela suffirait pour déterminer si oui ou non un certain le fichier existe dans la sauvegarde.

COMME toujours, un courant de conscience paranoïaque et hautement non scientifique.

Les pensées?

Intéressant. Je ne comprends pas comment l'attaque que vous décrivez dépend de l'utilisation ou non de la compression, est-ce vraiment nécessaire ? Cette attaque ne fonctionne-t-elle pas avec et sans compression ?

En ce moment, je réfléchis à la façon d'implémenter #56. Que pensez-vous du regroupement de plusieurs blobs dans un seul fichier ?

Le fonctionnement exact de la mise en œuvre du CDC n'est pas clair pour moi :

  • Vous divisez-vous sur des limites d'octets exactes ou les blocs de 512 Ko - 8 Mo sont-ils "arrondis" à un multiple de quelque chose ?
  • (La vraie question est : y a-t-il (15 * 512 * 1024) / (16 à cause d'AES-CTR) taille de morceau possible, ou moins ?)
  • Je suis également curieux de savoir dans quelle mesure il serait possible de reconstruire la graine avec suffisamment de morceaux d'un fichier connu - pas très faisable, je suppose?

Pour répondre à ta première question :
Avec le CDC ensemencé, "l'empreinte digitale" dépend du (contenu + la graine secrète), mais la différence est que lorsque la compression est effectuée _après_ le découpage, et en supposant que vous puissiez distinguer les blocs individuels les uns des autres, vous avez une empreinte/ filigrane (le taux de compression d'un certain bloc) qui dépend uniquement du contenu, dans ce scénario un texte en clair connu.

Exemple:
Si le fichier filigrané contient 64 Mo (8-128 morceaux) de "AAAA", puis 64 Mo de "ABCABCABCABC", puis 64 Mo de données aléatoires, les 16-256 premiers morceaux seraient très petits (car ces séquences se compressent très bien , où les 8-128 morceaux se compresseraient plutôt mal).
L'attaquant pourrait également travailler en arrière, en commençant par le tout dernier morceau (24e - 384e) et compresser 512 Ko à 8 Mo jusqu'à ce que l'attaquant trouve une taille qui se compresse exactement à la même taille de morceau. Une fois que cela est trouvé, les 512 Ko à 8 Mo « prochains » du texte en clair d'origine sont compressés pour déterminer quelle longueur se compresse à la longueur de l'avant-dernier bloc (23e - 383e), et ainsi de suite, jusqu'à ce que l'attaquant rencontre le petits morceaux qui sont le résultat des chaînes "AAAA".
Cela ne permet pas à un adversaire de confirmer positivement qu'un fichier filigrané est stocké dans la sauvegarde, mais je pense que statistiquement, cela peut créer des résultats assez clairs, avec suffisamment de données.

Je vois des solutions potentielles, peut-être avez-vous d'autres idées :

  • Autoriser la désactivation de la compression et/ou de la déduplication pour certains répertoires (probablement le plus simple à mettre en œuvre)
  • Randomiser les dictionnaires de compression (je n'ai pas vraiment réfléchi à celui-ci, mais cela semble être une idée intéressante)
  • Empêchez les attaquants d'apprendre les longueurs des morceaux compressés individuels, par exemple en remplissant (potentiellement assez cher) ou en regroupant plusieurs petits morceaux et en remplissant le reste (plus de complexité, mais plus efficace)

Merci pour votre explication, je comprends votre scénario maintenant.

Il n'y aura probablement aucune option pour désactiver la déduplication dans restic, car c'est vraiment difficile à faire étant donné la structure actuelle du programme, restic est construit autour de CDC. L'ajout de la prise en charge de la compression n'est pas une priorité pour le moment et n'est pas un objectif pour la version alpha.

Votre troisième idée sera mise en œuvre dans #56 (regrouper plusieurs morceaux), j'y travaille en ce moment. Et j'ajouterai probablement plus de documentation à doc/Design.md concernant le fonctionnement du chunker.

Merci encore d'avoir évoqué ce scénario !

Je ne sais pas si je suis @cfcs - la taille compressée n'est-elle pas juste comme un hachage incroyablement mauvais ? Étant donné une taille de fichier compressée, le nombre d'entrées possibles qui génèrent cette taille de fichier est infini. Mais je ne comprends probablement pas.

De toute façon. Je voulais juste vous indiquer sans vergogne une bibliothèque deflate/gzip modifiée que j'ai créée. Cela pourrait vous intéresser que je mette en place un mode de compression à temps constant , qui permet un débit d'environ 150 Mo/s/cœur sur TOUTES les données, ce qui les rend presque invisibles dans les scénarios de sauvegarde. Il existe également un package gzip parallèle qui compresse les fichiers plus volumineux sur plusieurs cœurs.

@klauspost : Gardez à l'esprit que nous discutons de la taille compressée des morceaux individuels plutôt que des fichiers. Un fichier de 100 Go avec une taille de morceau moyenne de 1 Mo aura environ 100 x 1024 morceaux, chacun laissant filtrer le taux de compression pour un certain morceau du fichier. Cela donne beaucoup plus de données statistiques que la taille d'un seul fichier compressé, ce qui permet de comparer un texte en clair connu à un fichier compressé et fragmenté même si le sel CDC (et donc les limites d'alignement exactes des fragments) est inconnu.

151 a été fusionné, cependant, ce n'est probablement pas un problème maintenant.

À mon avis, cette fuite d'informations n'a qu'une importance mineure, étant donné que nous avons un chunker prédéfini (via le polynôme personnalisé par dépôt) et un emballage de blob (où un attaquant ne peut pas voir les morceaux individuels, mais uniquement des groupes de morceaux et le nombre de morceaux dans un groupe, via la longueur d'en-tête en clair). Je pense que c'est une bonne idée d'offrir la désactivation complète de la compression pour des raisons de vitesse ou de confidentialité, mais la valeur par défaut (lorsqu'elle est implémentée) sera probablement "activer".

@klauspost Je vais certainement regarder votre bibliothèque, merci de l'avoir signalé !

Je suis d'accord avec vos observations ci-dessus, @fd0 , mais j'aimerais ajouter que je pense qu'il peut y avoir un autre cas d'utilisation important pour désactiver sélectivement la compression pour des fichiers/répertoires/périphériques cibles spécifiques, par exemple lors de la sauvegarde de formats multimédias déjà compressés, des fichiers binaires avec une entropie élevée qui ne se compressent pas bien, ou lors de sauvegardes incrémentielles de volumes chiffrés.

@cfcs - ok - à partir de votre texte, je pensais que vous

En ce qui concerne les fichiers non compressibles, c'est la raison pour laquelle j'ai mentionné le mode Huffman à temps constant que j'ai mis en dégonfle, comme son nom l'indique, il compresse toutes les données à la même vitesse et dispose d'un repli automatique pour stocker les données non compressées. Ainsi, la surcharge maximale est d'environ 0,04 % si le contenu est compressé.

Voici quelques repères . Le plus applicable pour les sauvegardes est probablement sur la "Compression moyenne", qui est un contenu mixte de 10 Go - compressible et incompressible.

Utiliser par défaut uniquement gzip Huffman et avoir la possibilité de spécifier un niveau de compression plus gourmand en CPU pourrait avoir du sens.

À mon avis, il pourrait être utile d'activer/désactiver sélectivement la compression séparément pour les données et les objets d'arborescence. Les objets d'arbre particulièrement volumineux devraient être très bien compressés.

J'ai examiné certains "points" où il pourrait être judicieux d'insérer une compression. L'endroit le plus transparent et le plus polyvalent serait quelque part entre le référentiel et le backend.

J'ai brièvement examiné la modification de Repository.Encrypt et Repository.DecryptTo , mais nous n'avons pas de types, et les différentes tailles feraient un gâchis.

Ma proposition est d'implémenter la compression et le _encryption_ en tant que "backend", que les deux écrivent sur un backend sous-jacent. Cela rendra la compression et le cryptage transparents pour le référentiel.

La raison pour laquelle nous devons séparer le cryptage est que les données cryptées ne se compressent pas (comme vous le savez probablement).

référentiel.Référentiel

L'algorithme de compression ne peut être défini qu'à l'initialisation, et tout sauf la configuration est supposé être compressé avec cet algorithme.

référentiel.Config

La configuration ne peut pas être compressée. Nous ajoutons une chaîne qui indique le type de décompression à utiliser pour tout. Vide ("") n'est pas compressé. Sinon, il s'agit de la dernière partie du nom de package de la bibliothèque de compression utilisée.

Notez que les niveaux de compression peuvent être modifiés entre chaque exécution/type. Il n'y a aucun problème à avoir un dépôt où certains instantanés/types sont dégonflés au niveau 0 (stockage) et d'autres au niveau 9 (meilleure compression) - tant que le décompresseur est le même.

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

La compression est ajoutée en tant que paramètre de création :

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

Le backend est remplacé après LoadConfig/CreateConfig. Voici un exemple de ce à quoi cela pourrait ressembler :

// 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
}

Implémentation de la compression

Le compresseur peut mettre en œuvre une compression sélective/réglable pour certains types. Puisqu'il est considéré comme un "backend", la taille compressée ne sera jamais visible pour le référentiel. Le compresseur doit être sommé avec tous les réglages.

Problèmes

HELPME/FIXME : les fichiers « emballés » semblent poser problème, car le chiffrement redémarre à chaque fichier. Si le chiffrement est déplacé vers le backend, le chiffrement sera pour l'intégralité du blob, pas pour chaque fichier. Je suppose que c'est un problème, et je n'ai pas de bonne solution.

A FAIRE : Trouver un bon moyen pour que les paramètres/configurations soient envoyés au compresseur. Pas nécessaire pour une première implémentation.

À FAIRE : nous soucions-nous de la taille des disques ? Si ce qui précède est mis en œuvre, le référentiel ne le saura pas.

Merci d'avoir partagé vos idées, voici les miennes :

Je pense que la compression et le cryptage doivent être intégrés l'un à l'autre, je vais y réfléchir. Pour le moment, je n'aime pas l'idée d'abstraire complètement la couche de compression/chiffrement les unes des autres. Comme vous l'avez déjà décrit, nous devons faire attention à ne pas faire de bêtises, par exemple compresser des données cryptées. De plus, nous devrions offrir une option pour désactiver la compression en faveur de problèmes de vitesse et/ou de sécurité. Concernant le cryptage : Il peut y avoir un mode non-crypto pour restic plus tard, mais pour l'instant le cryptage n'est pas facultatif.

De plus, les fichiers compressés sont un niveau d'abstraction en soi (par exemple, les éléments peuvent être reconditionnés), ce qui ne fonctionne pas avec l'abstraction de la crypto.

Je pense que l'objet Repository est beaucoup trop complexe et a besoin d'une refonte générale avant de s'attaquer à cela. Je n'ai pas vraiment de bon plan pour le moment.

Concernant les différents algorithmes et options de compression : Je pense que nous devrions sélectionner un algorithme (incluant un ensemble de paramètres) pour les données, et peut-être un deuxième pour compresser les arborescences JSON, mais c'est tout. Pour toutes les choses facultatives (par exemple, différents algorithmes et/ou paramètres de compression configurables), j'aimerais avoir une considération solide en pondérant les avantages par rapport à la complexité et à la quantité de code supplémentaire.

Ne vous méprenez pas, j'aimerais ajouter des fonctionnalités à restic, mais surtout pour les changements qui modifient le format sur disque, j'ai besoin de très bons arguments. Dans le cas général de l'ajout de compression, je peux voir l'avantage, mais la complexité et les modifications du format sur disque doivent être gérables.

vous aurez besoin de différents algorithmes et paramètres (et pas seulement par dépôt, mais même par exécution de sauvegarde), il n'y a pas de compression "la meilleure pour chaque cas d'utilisation".

juste à titre d'exemple pratique :

Je fais des sauvegardes de mon serveur d'entreprise vers mon serveur de sauvegarde à la maison. liaison montante dsl avec ~700kbit/s.
pour cela, je veux la meilleure compression (comme lzma + haut niveau). le processeur a beaucoup de temps libre la nuit en attendant que la connexion de merde accepte le prochain paquet.

dans le même référentiel, je sauvegarde également mon ordinateur portable lorsque je suis à la maison, j'y ai une connexion sans fil "N". bien sûr, je ne veux pas ralentir la connexion en utilisant lzma + haut niveau, mais je veux plutôt quelque chose de très rapide qui ne ralentit pas du tout - comme lz4. Je veux toujours la compression, ne pas utiliser lz4 prendrait environ 2 fois plus d'espace.

Je veux lzma ici mais lz4 là (reformulé :-))

C'est tout bikeshedding à mon humble avis... Choisissons une valeur par défaut raisonnable et n'exposons pas trop de configuration, cela introduira juste beaucoup de complexité pour peu de gain, à mon humble avis.

Je pense que l'objet Repository est beaucoup trop complexe et a besoin d'une refonte générale avant de s'attaquer à cela. Je n'ai pas vraiment de bon plan pour le moment.

Assez juste. J'ai commencé à parcourir repository.go et j'ai trouvé tous les endroits où vous inséreriez une étape de compression/décompression, et la complexité supplémentaire n'était pas une bonne chose. En l'implémentant en tant qu'interface backend , vous pourriez soudainement supprimer tout le cryptage et l'intégrer à une chaîne principale. Vous pouvez faire un test générique qui garantit la symétrie des parties principales, y compris la compression et le cryptage.

Concernant le cryptage : Il peut y avoir un mode non-crypto pour restic plus tard, mais pour l'instant le cryptage n'est pas facultatif.

C'est pourquoi le chaînage backend le rend si agréable. Vous oubliez simplement le cryptage (ou créez un backend passthrough) et cela fonctionne de manière transparente.

Dans le cas général de l'ajout de compression, je peux voir l'avantage, mais la complexité et les modifications du format sur disque doivent être gérables.

C'était la façon la moins intrusive que je puisse voir. S'il existe un moyen de résoudre le problème du « fichier compressé », les dépôts non compressés restent entièrement rétrocompatibles ; l'ancien client pourra les opérer comme avant aux côtés des nouveaux.

Les dépôts compressés ne le seront évidemment pas, mais nous pouvons changer version en 2 uniquement si le dépôt est compressé, cela fera échouer les clients plus anciens. La vérification devrait alors évidemment être changée en if cfg.Version > RepoVersion { , mais cela ne pose aucun problème de compatibilité.

C'est tout bikeshedding à mon humble avis... Choisissons une valeur par défaut raisonnable et n'exposons pas trop de configuration, cela introduira juste beaucoup de complexité pour peu de gain, à mon humble avis.

Se mettre d'accord. La plupart des algorithmes (lzma/deflate) ont beaucoup de flexibilité dans le même format de décompression.

Pour tester la compressibilité il y a DataSmoke : https://github.com/Bulat-Ziganshin/DataSmoke

De plus, pcompress choisit un bel assortiment d'algorithmes de compression : https://github.com/moinakg/pcompress

La bibliothèque d'abstraction de compression squash a une bonne liste d'algorithmes et un benchmark : https://quixdb.github.io/squash/

Il existe un benchmark de compression de texte ici : http://mattmahoney.net/dc/text.html

Une approche simple consiste à toujours filtrer à l'intérieur des fonctions crypto/crypto.go Encrypt/Decrypt.

gzip-compression-v1.patch.txt c'est un

Merci d'avoir essayé @mappu , mais avant de mettre cela en œuvre, nous devons nous mettre d'accord sur une stratégie. Les questions ouvertes (du haut de ma tête) sont au moins :

  • Quand la compression est-elle appliquée ? (Données ? Métadonnées/JSON ?)
  • Quel algorithme doit-on implémenter ? Je pense que @klauspost a quelques suggestions pour nous :)
  • Comment stocker cela dans un référentiel sans casser les clients ?

Quand la compression est-elle appliquée ? (Données ? Métadonnées/JSON ?)

Les données évidemment oui.
Metadata/json, c'est peut-être inutile, mais je pense que cela pourrait aider pour les gros fichiers de métadonnées, car les données JSON sont principalement ASCII et bénéficieraient du codage arithmétique / de la phase huffman (gzip a).

Étant donné que les données/métadonnées sont toujours chiffrées, je pense que l'ajout à la routine de chiffrement/déchiffrement est un moyen simple d'attraper toutes les utilisations, sans cela "J'ai commencé à parcourir repository.go et j'ai trouvé tous les endroits où vous inséreriez une étape de compression/décompression, et la complexité supplémentaire n'était pas une bonne chose." de @klauspost .
De plus, étant donné que les blobs sont stockés sous le nom de hachage (texte en clair) et non de hachage (texte chiffré) {{évidemment nécessaire pour la déduplication, sinon une IV aléatoire détruirait la déduplication}}, il est sûr de le faire sans nuire à la déduplication.

Quel algorithme doit-on implémenter ? Je pense que @klauspost a quelques suggestions pour nous :)

ça m'est égal Bien que je @ThomasWaldmann qu'il devrait être configurable. Au moins pour un cas d'utilisation --best et --fast .

Je suggérerais gzip uniquement parce que c'est purement go, c'est dans la bibliothèque standard golang et reçoit l'attention de Google sur les performances. xz est une compression lente beaucoup plus forte. lz4 est une compression rapide beaucoup plus faible. gzip est équilibré et facile à régler, même s'il n'atteint aucun des extrêmes.

Comment stocker cela dans un référentiel sans casser les clients ?

Le référentiel doit être compatible dans un seul sens. Je pense que ce n'est pas grave si l'ancien restic ne peut pas lire le nouveau repo, tant que le nouveau restic peut lire l'ancien repo.

Vous pourriez peut-être ajouter un octet de balise après le MAC. Non présent - pas de compression (ancien restic). Ensuite, l'octet peut également indiquer quel algorithme de compression a été utilisé. 0x01 gzip 0x02 lz4 ou plus.

Il semble que le même (ou pire) problème que dans le grenier soit présent (pas de type de compression/octet(s) de paramètre utilisé(s) dans le format actuel).

Dans le grenier (borg), j'ai eu de la chance car l'ancien format était uniquement gzip et le format gzip peut être détecté à partir des 2 premiers octets. J'ai donc conservé gzip sans octets supplémentaires (identiques aux anciens repos) et ajouté des octets de type (pour aucune ou autre compression) qui ne sont jamais ambigus avec les 2 premiers octets gzip.

Évidemment, vous ne pouvez pas le faire comme ça si l'ancien format n'est que des données brutes et arbitraires.

Non. Mais il existe d'autres moyens de signaler cette information. par exemple, si IV au début du morceau crypté est exactement "NEWFORMAT" (1 :: 2^xyz chance de collision) alors analyser comme nouveau format. Ce n'est pas si "propre" mais je pense bien dans la pratique.

comme c'est fait avec EXTENDEDPROTOCOL dans la poignée de main de verrouillage nmdc.

Oh non, nous ne ferons pas quelque chose de moche comme ça, et nous n'en avons pas besoin. Si nous décidons d'implémenter cela, les fichiers du pack ont ​​un champ type pour chaque blob. Il s'agit d'un uint8 , et pour le moment défini uniquement pour data et tree , nous pouvons facilement ajouter compressed data et compressed tree . https://github.com/restic/restic/blob/master/doc/Design.md#pack -format

Pour le moment, je ne considère pas cette fonctionnalité comme une priorité élevée.

L'ajout de nouveaux types de blob au format de pack est acceptable pour la compression de données, mais ne fournit pas de compression d'index. Étant donné que les index peuvent devenir volumineux et que JSON a un bon taux de compression, et peut-être que l'index n'a pas de cache local, je pense donc qu'il est important de compresser également les index.

Il est important que new-restic fonctionne avec old-repo, pour permettre une mise à niveau facile. Il doit être transparent (de préférence) ou avoir un outil restic upgrade-repo (pas de préférence).

Alors, qu'en est-il de cela ?

Toutes les commandes restic font déjà d'abord charger+décrypter le config .

  • si le premier octet config est { (c'est le premier octet de l'objet json), alors tout le référentiel est dans l'ancien format (non compressé)
  • sinon, le premier config octet est {tag byte} et le dépôt entier est au nouveau format. {tag byte} au début des données déchiffrées indique le format de compression. exemple 0x00 non compressé 0x01 gzip

Merci pour la proposition. Je pense qu'il est inutile de compresser la configuration, car ce n'est qu'un très petit fichier et peut toujours rester au format JSON, et nous pouvons ajouter des champs si nécessaire, par exemple si les fichiers d'index sont compressés ou non.

Je viens de trouver restic hier en cherchant une bonne solution de sauvegarde. L'une de mes principales préoccupations est de limiter l'espace occupé par mes données. Surtout si j'envoie des données à des endroits pour lesquels je paie, comme S3. La déduplication aidera certainement, mais je m'attendais à ce que la compression fasse partie intégrante d'une solution de sauvegarde ... Dans https://github.com/restic/restic/issues/21#issuecomment -185920429 vous ( @fd0 ) dites ceci est une faible priorité, pouvez-vous expliquer pourquoi ? Existe-t-il une feuille de route que je pourrais consulter n'importe où ?

Aussi, +1. ;)

En ce moment, je travaille sur la suppression des anciennes données de sauvegarde (#518). Il n'est pas facile d'obtenir une compression correcte et sécurisée en même temps, et je dois réfléchir un peu plus à la manière de l'intégrer dans le format du référentiel.

Nous allons implémenter la compression (après tout ce dont il s'agit dans ce problème), cela n'a tout simplement pas encore été fait. restic est un projet plutôt nouveau, s'il vous plaît soyez indulgents avec nous :)

Ce problème est lié au #116. En raison du cryptage, nous ne pouvons pas compresser la sauvegarde après avec d'autres outils, n'est-ce pas ? Quelle priorité avez-vous entre la compression et rendre le chiffrement facultatif ? (Je parie d'abord pour la compression !)
_Désolé de faire pression à ce sujet, vous avez raison, le format du référentiel doit être pris avec précaution !_

C'est facile de répondre : la compression sera implémentée en premier.

C'est parce que je n'ai pas l'intention pour le moment de rendre le cryptage facultatif. Je pense aussi qu'il est très difficile d'avoir raison. Nous aurions besoin de penser à l'intégrité, car c'est une chose qui ne devrait pas être facultative, mais (au moins pour le moment) elle est étroitement liée au cryptage.

@fd0 Merci d'avoir répondu à ma question. Cela me fait souhaiter que mes compétences en développement soient à la hauteur de l'aide. Mais j'ai à peine touché au go, et la plupart de mes autres xp sont dans des scripts webdev ou sysadmin.

Je suis tout à fait d'accord pour dire que vous devez vous assurer que la compression est effectuée "correctement et en toute sécurité". Si cela retarde les choses, qu'il en soit ainsi. :le sourire:

J'ai implémenté une compression rapide dans restic ici : https://github.com/viric/restic/tree/snappy

C'est juste une proposition. Fondamentalement, j'ai ajouté une compression/décompression rapide pour les blobs dans les packs, et j'utilise un peu de l'octet de type blob comme marque. J'ai également ajouté un champ dans les indices de pack : PLength (longueur du texte en clair), qui n'était jusqu'alors pas stocké mais calculé comme "bloblength - crypto.Extension".

J'ai remarqué que pour certaines de mes sauvegardes, non seulement cela prend moins d'espace, mais cela fonctionne même plus rapidement (moins de données à gérer).

Tous les tests restic passent bien. Il peut fonctionner sur les référentiels restic précédents, mais le restic normal (celui de master) ne peut pas gérer les nouveaux blobs.

J'ai utilisé snappy (https://github.com/golang/snappy) parce que je pensais que cela affecterait moins l'objectif de vitesse de @fd0.

Ajout d'une prime de 50 $ pour l'atterrissage par compression sur le maître

Bountysource

Comme mentionné ci-dessus, il devrait exister un moyen automatisé et non configurable d'éviter d'essayer de compresser des fichiers incompressibles tels que des fichiers multimédias, cryptés ou déjà compressés. Le problème est exacerbé par certains formats de conteneurs comme le PDF dont le contenu est parfois compressible, parfois non.

Il serait plus simple d'utiliser un algorithme qui gère cela de manière transparente, comme le mode de compression à temps constant mentionné dans le premier commentaire de @klauspost.

Sinon, il faudrait des listes de types de fichiers : une liste noire à ne jamais compresser, une liste blanche à compresser toujours, une heuristique pour le reste qui essaie de compresser une petite fraction du fichier, et abandonne si la réduction de taille n'est pas au-dessus d'un seuil donné.

Je ne sais pas dans quelle mesure cela serait mappé au niveau du bloc plutôt qu'au niveau du fichier.

Je m'opposerais à son ajout à la passe de cryptage/décryptage.
Nous ne voulons pas mélanger différentes sortes de données, car certaines d'entre elles peuvent être prévisibles, et les longueurs de pack/blob résultantes peuvent divulguer des informations sur le texte en clair des données imprévisibles/secrètes.
Je pense que cela devrait être par fichier, même si cela le rend "moins sympa". Cela, cependant, présente l'avantage de ne pas avoir à décompresser des tonnes de fichiers de pack (où un seul blob dans chaque compte) pour lire un fichier.

@teknico

Comme mentionné ci-dessus, il devrait exister un moyen automatisé et non configurable d'éviter d'essayer de compresser des fichiers incompressibles tels que des fichiers multimédias, cryptés ou déjà compressés.

Mon package deflate modifié implémente le saut de données déjà compressées et le fait à un taux d'environ 250 Mo/s par cœur. Le dégonflage Go 1.7 ne prend en charge que les niveaux de compression les plus rapides.

Snappy et LZ4 prennent en charge une fonctionnalité de saut similaire.

Il serait plus simple d'utiliser un algorithme qui gère cela de manière transparente, comme le mode de compression à temps constant.

Cela devrait certainement être une option. Dans Go 1.7 (maintenant appelé HuffmanOnly et mon équivalent), ce mode prend en charge ~ 200 Mo/s par cœur, quelle que soit l'entrée. Cependant, la compression est gravement entravée par rapport à la "meilleure vitesse", qui fonctionne généralement à 80 Mo/s/cœur.

@cfcs

Je pense que cela devrait être par fichier, même si cela le rend "moins sympa".

En général je suis d'accord. Je vais devoir lire sur restic. La taille binaire de chaque taille de pack est-elle disponible non cryptée ?

@klauspost Il semble que certaines de vos améliorations aient été fusionnées dans le mode "BestSpeed" de Go 1.7 DEFLATE, est-ce correct ? Ce serait peut-être une valeur par défaut raisonnable.

L'avantage d'utiliser le format DEFLATE est qu'il existe de nombreux compresseurs différents disponibles qui produisent des flux binaires compatibles, il est donc complètement transparent pour le décompresseur.

En raison de la nature du fonctionnement de restic (diviser les fichiers en blobs, ne gère que les blobs par la suite), le moyen le plus simple d'ajouter de la compression est au niveau des blobs. Peut-être pourrions-nous ajouter des heuristiques pour décider si un blob doit être compressé ou non, mais cela peut être la deuxième étape.

Les blobs sont combinés dans des fichiers pack, qui sont ensuite stockés dans le référentiel. Un fichier pack contient un certain nombre de blobs (chiffrés séparément), suivis d'un en-tête (chiffré), suivi de la longueur de l'en-tête (non chiffré). Les attaquants sans clé de déchiffrement ne voient que le texte chiffré, la longueur de l'en-tête et la longueur du fichier. Donc, en fonction de la taille du fichier pack et de la longueur de l'en-tête, les attaquants pourraient calculer la taille moyenne d'un blob dans un fichier pack particulier, mais c'est tout. Les fichiers d'index contiennent également toutes les données (taille, taille cryptée et plus tard peut-être la taille compressée), mais celles-ci sont également cryptées. Je ne vois aucun risque ici.

Une heuristique de test "compressible" est à la fois sujette aux erreurs et assez coûteuse. J'estimerais qu'il serait difficile d'aller bien au-dessus de 200 Mo/s/cœur - c'est la vitesse de la recherche d'ordre 1 dans le package de déduplication sur AMD64.

De plus, cela dépend beaucoup du compresseur utilisé. Snappy ne serait pas en mesure de compresser des données aléatoires en base 64, mais dégonfler le ferait par exemple, donc je laisserais cette partie au compresseur - nous l'avons intégré pour Snappy, LZ4 et dégonfler.

@fd0 désolé, je voulais dire par blob, pas par fichier.
À moins que nous ne choisissions un algorithme léger, la compression, étant quelque peu lourde en CPU, est susceptible de devenir un goulot d'étranglement (à côté d'AES, qui, espérons-le, sera pris en charge à l'avenir par AES-NI).

@fd0 - J'ai fait un "estimateur de compressibilité" rapide : https://play.golang.org/p/Ve5z3txkyz - il estime la prévisibilité et l'entropie de données arbitraires. Cependant, comme je l'ai mentionné, il devrait plutôt appartenir au compresseur de décider.

borg 1.1 aura 2 "décideurs de compression":

  1. décider par fichier en fonction de la correspondance du modèle de chemin ( *.zip , *.mp3 , /htdocs/photos/* , ...)
  2. en cas d'indécis, décidez par morceau, utilisez lz4 comme test de compressibilité - si cela compresse, compressez à nouveau avec la compression souhaitée (lz4, zlib, lzma), sinon, ne compressez pas.

@klauspost hm, ce test n'est pas si mal sur ma machine :

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

Le code de référence est ici : https://gist.github.com/908c23123dda275a479cf931f2784f5d

Lz4 n'a pas de codeur entropique, il sera donc faux négatif de nombreuses fois
Probablement?

Je pense que nous avons besoin de trois modes (globalement):

  • Compresser tous les blobs de données avec un compresseur temporel linéaire (par défaut)
  • Pas de compression
  • Compression maximale (pour les personnes ayant beaucoup de puissance CPU, mais seulement une faible bande passante)

J'aimerais toujours compresser les objets arborescents (JSON), nous devons donc sélectionner un algorithme approprié pour le texte ASCII.

Sinon, je travaillerai avec @viric pour construire un prototype, puis nous pourrons raisonner sur une implémentation concrète.

Les pensées?

@klauspost hm, ce test n'est pas si mal sur ma machine

J'oublie toujours à quel point le nouveau compilateur Go peut incroyablement bien faire. Au moins le double de ce à quoi je m'attendais.

Je pense que nous avons besoin de trois modes (globalement):

Deflate fait assez bien les 3, bien qu'il existe des compresseurs plus efficaces (LZMA principalement). Dégonfler sans compression est bien sûr inutile, mais est bien sûr rapide et avec une surcharge minimale, donc une approche générale de dégonflement pourrait être utilisée, avec la possibilité d'en spécifier d'autres plus tard.

J'ai commencé à regarder une autre accélération , qui serait entre le niveau 1 et Huffman à la fois en termes de vitesse et de compression. Cependant, le temps est un peu précieux pour le moment, et j'ai encore besoin de tester un backport de certains des derniers changements de Go 1.7 avant de pouvoir passer à de nouvelles choses.

Si vous voulez juste un seul algorithme de compression, vous devriez jeter un œil au nouveau concurrent zstd : https://github.com/facebook/zstd

Il a été développé par le même développeur que lz4 et a un meilleur taux de compression que gzip tout en étant plus de 3 fois plus rapide : https://code.facebook.com/posts/1658392934479273/smaller-and-faster-data-compression-with -zstandard/

zstd semble très prometteur, même si je n'ai pas pu trouver d'implémentation dans Go.

Le site officiel http://facebook.github.io/zstd/#other -languages ​​renvoie à cette implémentation Go : https://github.com/DataDog/zstd

Ou voulez-vous dire une implémentation Go pure ?

Oui, cela signifiait une pure implémentation Go. Pour le moment, restic ne dépend d'aucun code C, et idéalement, j'aimerais que cela reste ainsi.

Y a-t-il des prévisions pour mettre en œuvre la compression ?

La mise en œuvre de la compression dépend du changement de format du référentiel (le planning/les idées sont au n°628), ce qui nécessite une grande prudence. Donc, non, il n'y a pas de date définitive à laquelle la compression est ajoutée ;)

Y a-t-il quelque chose que nous puissions faire ou contribuer pour aider à ce que cela se produise ?

Je ne pense pas, désolé :wink:, il faut juste du temps.

J'ai donc pensé que je pourrais utiliser mon banc d'essai du #790 une fois de plus. Dans ma version de restic, j'ai supprimé tout le cryptage, puis j'ai à nouveau effectué une sauvegarde complète. Il est venu dans la même taille que crypté - pas de surprises ici. Mais ensuite j'ai compressé le référentiel, et ce que j'ai trouvé est :

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

Quelle différence! À titre de comparaison, voici la taille d'un seul dump de base de données compressé :

1.7G    single-backup.sql.gz

J'en ai 29 ci-dessus. Environ 100 fois plus d'économies par rapport aux sauvegardes régulières !

Depuis que j'ai trouvé tous les endroits où le cryptage a été ajouté, je pense que je peux ajouter une compression configurable très simple avec une implémentation stock gzip , avec la possibilité d'utiliser un moteur de compression différent à l'avenir. Des objections?

(Je vais probablement me donner deux semaines de soirées pour réussir ou échouer.)

Merci pour vos recherches et la publication des résultats ici ! Je m'attendais à des résultats similaires. Pour être honnête avec vous : je ne fusionnerai rien qui supprime la crypto, ni même la rend facultative. C'est quelque chose que nous pouvons faire plus tard, mais cela doit être soigneusement planifié.

L'ajout de la compression peut sembler facile au début, mais ce n'est pas le cas. Nous devons faire très attention à ne pas rendre accidentellement restic vulnérable à des attaques inattendues (cela est arrivé plusieurs fois de suite au protocole TLS (oui, je suis conscient que c'est une situation différente)).

La chose la plus importante dans tout le projet n'est pas le code : c'est le format du référentiel. Les utilisateurs nous font confiance avec leurs données, et ils dépendent de la possibilité de restaurer les données après une longue utilisation de restic, la stabilité du format du référentiel est donc de la plus haute importance. Ainsi, afin de prendre en charge la compression, nous devons d'abord décider (et implémenter) la prochaine version du format de référentiel. La discussion est ici : https://github.com/restic/restic/issues/628

Je peux voir que vous êtes très désireux d'implémenter cela (et même de contribuer au code), mais s'il vous plaît ne perdez pas de temps là-dessus jusqu'à ce que nous soyons d'accord sur le format du référentiel et que nous ayons discuté de tous les angles de ce problème. Merci!

Quant à la crypto supprimée, je ne vais pas proposer de la fusionner. Je l'ai fait uniquement pour voir si une compression fonctionnera. Et oui, cela devait être soigneusement planifié (personne ne veut perdre soudainement la possibilité de vérifier un référentiel avec le cryptage désactivé).

Puisque nous utilisons json.Unmarshal nous pouvons ajouter autant de nouvelles clés à la configuration que nous le souhaitons. S'ils ne sont pas trouvés dans le JSON, ils conserveront simplement leurs valeurs par défaut.

Le choix de l'algorithme n'est pas le point principal, bien compris : mais juste pour référence future, Brotli semble un concurrent sérieux.

Pour autant que je sache, la compression Brotli est très lente (iirc 60 fois gzip), elle est donc recommandée pour les données lues très fréquemment par rapport à celles écrites et compressées, ce qui n'est probablement pas courant pour les sauvegardes. Mais oui, n'entrons pas encore dans les détails :)

Cela donne un bon aperçu des différents algorithmes de compression.

Brotli est toujours plus rapide ou a une meilleure compression. Dépend du niveau de compression.

@ibib Comment brotli apparaît plus lentement que la plupart des autres (sur les ensembles de données mixtes) sans atteindre des taux de compression particulièrement étonnants. C'est peut-être mieux pour des types spécifiques de données structurées ?

Comme indiqué dans les comparaisons du benchmark Squash , trois paramètres doivent être pris en compte :

  • Taux de compression atteint : la qualité de la compression est importante pour économiser de l'espace disque (et des E/S vers le backend).

  • Vitesse de compression : est importante car nous allons effectuer cette opération à chaque fois que nous ajoutons un bloc, nous voulons donc vraiment quelque chose qui puisse suivre l'AES-NI et les E/S générales afin de ne pas devenir un goulot d'étranglement. Nous ne voulons probablement pas choisir un algorithme qui compresse plus lentement qu'il ne décompresse puisque nous avons le cas d'utilisation inverse des navigateurs Web que ces nouveaux algorithmes (comme zstd , lz4 , brotli ) sont optimisés pour (nous avons "compresser souvent, décompresser rarement" par opposition à "compresser une fois, décompresser souvent").

  • Vitesse de décompression : La vitesse de décompression n'est pertinente que lorsque nous restaurons. Si nous sommes d'accord avec une restauration lente, nous pouvons accepter une vitesse de décompression lente. D'un autre côté, nous avons également des métadonnées que nous ne voulons pas décompresser lentement, ce qui pourrait même justifier deux algorithmes différents.

Il semble que density soit parmi les plus rapides, bien que pas particulièrement efficace en termes de taux de compression. En termes de ne pas être un goulot d'étranglement, il semble que cela nous procurera (en moyenne) un taux de compression de 2: 1 presque gratuitement. Si nous voulons 4:1, nous devrons choisir un algorithme différent, mais nous finirons par nous asseoir et l'attendre.

Nous avons également deux (au moins ?) types de données différents : les index ; et les morceaux de données. Les deux sont utilisés différemment, et je suppose que l'on pourrait discuter de la pertinence de choisir des algorithmes différents pour eux. Personnellement, je pense que nous devrions nous en tenir à un algorithme (quel que soit notre choix) afin que la réimplémentation de Restic (dans une nouvelle langue ou autre) ne soit pas rendue déraisonnablement difficile. Et pour que nous ne nous exposions pas aux bogues de deux algorithmes de compression passionnants car ceux-ci sont difficiles à tester pour les cas extrêmes.

Je ne suis pas d'accord avec vos compromis recommandés. Les sauvegardes peuvent s'exécuter en arrière-plan à un moment opportun (peut-être avec nice 10). Leur restauration se fait sous la pression du temps. Le compromis pertinent que je vois se situe entre la taille du bloc et le taux de compression. Des blocs trop petits ne seront pas bien compressés et augmenteront la surcharge des métadonnées. Des blocs trop gros réduisent le taux de déduplication. Pour la plupart des algorithmes de compression, les paramètres de niveau supérieur n'amélioreront pas les taux de compression pour les petites entrées.

De plus, des taux de compression plus élevés permettent aux utilisateurs de conserver plus de versions de leurs données dans le même espace.

N'oubliez pas que mes tests avec snappy ont eu pour résultat : 1) une taille de sauvegarde plus petite (elle compresse, normalement) et 2) une sauvegarde et une restauration plus rapides (moins de chiffrement de données, de HMAC et de transfert). Utiliser un ordinateur portable très bon marché.

@cfcs j'ai fait
image
Ici, brotli a toujours la compression la plus rapide et la meilleure.

@Crest C'est assez juste, nous avons probablement des cas d'utilisation différents - je n'utilise tout simplement pas restic la même manière que vous. Je fais des sauvegardes de mon ordinateur portable et je veux qu'il se termine rapidement afin que je puisse partir avec mon ordinateur portable. Je suppose que vous parlez de sauvegardes de serveurs ou d'autres machines connectées en permanence où le taux de sauvegarde n'est pas si important. De même, je n'ai jamais besoin de restaurer toutes mes données sous la pression du temps ; s'il y a une pression de temps (parce que vous l'utilisez dans des contextes professionnels ?), je peux restaurer de manière sélective les données dont j'ai besoin, et procéder au reste plus tard.

Vous faites un très bon point sur les « petites entrées plusieurs fois » ;

@viric L'effet Transfer + Processing :-)

@ibib ah,

@ibib pouvez-vous établir un lien d'où vous avez obtenu ce graphique ?

J'ai fait quelques tests avec brotli et zstd, et j'ai remarqué que mes résultats ne correspondent pas du tout à ceux du benchmark squash. Ensuite, j'ai compris que cette référence avait 1,5 ans.

zstd fonctionne très bien pour moi. Ratio rapide + élevé, et son "niveau" permet une très grande plage entre ratio rapide et élevé. Bonne chose.

Brotli fonctionne très lentement pour moi, sans meilleur taux de compression qu'un zstd beaucoup plus rapide. Et brotli semble concentré sur de petits fichiers de textes anglais (il comprend un dictionnaire anglais). Pour la compression html ou similaire.

Références plus récentes que j'ai trouvées : https://github.com/inikep/lzbench

J'ai donc jeté mon banc d'essai une fois de plus contre zbackup avec compression LZMA.

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

Impressionnant, n'est-ce pas ?

Autant dire que zbackup a son propre ensemble de limitations et d'inconvénients.

Donc, selon @viric lzbench link, le compresseur le plus approprié est celui qui ne ralentit pas les sauvegardes (vitesse de compression élevée ?, > 200 Mo/sec), qui a en fait un bon taux de compression (>=50), n'est-ce pas ?

J'ai donc filtré les résultats du tableau ordonné par rapport.

J'ai également effectué une recherche _rapide_ pour les implémentations Go (c'est pourquoi je les ai conservées dans le tableau). Le barré signifie que je n'ai trouvé aucune implémentation, ce qui a presque tout éliminé. Comme c'était juste une recherche rapide, j'ai gardé les résultats. Exception pour zstd qui n'est qu'un wrapper.

| Nom du compresseur | Compression| Décompresser.| Comp. taille | Rapport |
| --------------- | -----------| -----------| ----------- | ----- |
| zstd 1.1.4 -1 | 242 Mo/s | 636 Mo/s | 73654014 | 34,75 |
| lézard 1.0 -30 | 258 Mo/s | 867 Mo/s | 85727429 | 40.45 |
| densité 0,12,5 bêta -3 | 253 Mo/s | 235 Mo/s | 87622980 | 41.34 |
| gipfeli 2016-07-13 | 233 Mo/s | 451 Mo/s | 87931759 | 41,49 |
| lapidaire 2011-12-24 -9 | 257 Mo/s | 1263 Mo/s | 90360813 | 42,63 |
| lapidaire 24-12-2011 -6 | 295 Mo/s | 1268 Mo/s | 92090898 | 43.45 |
| quicklz 1.5.0 -1 | 346 Mo/s | 435 Mo/s | 94720562 | 44,69 |
| lézard 1.0 -20 | 284 Mo/s | 1734 Mo/s | 96924204 | 45,73 |
| lapidaire 24-12-2011 -3 | 352 Mo/s | 1222 Mo/s | 97255186 | 45,89 |
| lzrw 15-juil-1991 -4 | 243 Mo/s | 392 Mo/s | 100131356 | 47.24 |
| lzo1x 2.09 -1 | 394 Mo/s | 551 Mo/s | 100572537 | 47.45 |
| lz4 1.7.5 | 452 Mo/s | 2244 Mo/s | 100880800 | 47,60 |
| fastlz 0.1 -2 | 243 Mo/s | 469 Mo/s | 100906072 | 47,61 |
| lzo1y 2.09 -1 | 397 Mo/s | 556 Mo/s | 101258318 | 47,78 |
| lzo1x 2.09 -15 | 406 Mo/s | 549 Mo/s | 101462094 | 47,87 |
| densité 0,12,5 bêta -2 | 480 Mo/s | 655 Mo/s | 101706226 | 47,99 |
| lzf 3,6 -1 | 251 Mo/s | 565 Mo/s | 102041092 | 48.14 |
| accrocheur 1.1.4 | 327 Mo/s | 1075 Mo/s | 102146767 | 48.19 |
| blosclz 2015-11-10 -9 | 220 Mo/s | 696 Mo/s | 102817442 | 48,51 |
| lapidaire 2011-12-24 -0 | 384 Mo/s | 1221 Mo/s | 103072463 | 48,63 |
| lzo1x 2.09 -12 | 418 Mo/s | 550 Mo/s | 103238859 | 48,71 |
| lézard 1.0 -10 | 360 Mo/s | 2625 Mo/s | 103402971 | 48,79 |
| fastlz 0.1 -1 | 235 Mo/s | 461 Mo/s | 104628084 | 49,37 |
| lzrw 15-juil-1991 -3 | 226 Mo/s | 449 Mo/s | 105424168 | 49,74 |
| lzf 3,6 -0 | 244 Mo/s | 550 Mo/s | 105682088 | 49,86 |
| lzo1x 2.09 -11 | 424 Mo/s | 560 Mo/s | 106604629 | 50.30 |
| lz4fast 1.7.5 -3 | 522 Mo/s | 2244 Mo/s | 107066190 | 50.52 |
| tornade 0.6a -1 | 233 Mo/s | 334 Mo/s | 107381846 | 50,66 |
| memcpy | 8657 Mo/s | 8891 Mo/s | 211947520 | 100,00 |

Le LZ4 ressemble-t-il au compresseur le plus approprié ?

supposez que vous voulez lz4 (>=1.7.0 r129) et zstd (>=1.3.0), le cas échéant. nous les utilisons également pour borgbackup.

MAIS zstd est très ajustable avec un seul entier, de la vitesse lz4 à mieux
que la compression xz. Cela rendrait les utilisateurs heureux de dense plus lent
compression et celles de compression rapide. Sans oublier que zstd
décompresse très rapidement, quel que soit l'effort de compression.

lz4 est assez étroit.

Le samedi 16 décembre 2017 à 09:50:49 -0800, TW a écrit :

supposez que vous voulez lz4 et zstd, le cas échéant. nous les utilisons également pour borgbackup.

--
Vous recevez ceci parce que vous avez été mentionné.
Répondez directement à cet e-mail ou consultez-le sur GitHub :
https://github.com/restic/restic/issues/21#issuecomment-352199097

--
(Escriu-me xifrat si saps PGP / Ecrire chiffré si vous connaissez PGP)
Clé PGP 7CBD1DA5 - https://emailselfdefense.fsf.org/

Eh bien.. selon https://github.com/restic/restic/issues/21#issuecomment -250983311 de garder la dépendance restic libre, zstd n'est pas une option, pour l'instant. En outre, il existe quelques fils de discussion sur les problèmes de brevets/licences.

En ce qui concerne les taux de compression xz et élevés, même pour les paramètres de compression les plus bas, selon le tableau, la compression la plus rapide est d'environ 15 Mo/s.

Si l'exigence de sauvegarde rapide est abaissée, disons, >=30 Mo/sec, nous pourrions ajouter :

| Nom du compresseur | Compression| Décompresser.| Comp. taille | Rapport |
| --------------- | -----------| -----------| ----------- | ----- |
| xz 5.2.3 -9 | 1,70 Mo/s | 56 Mo/s | 48745306 | 23h00 |
| xz 5.2.3 -6 | 1,89 Mo/s | 58 Mo/s | 49195929 | 23.21 |
| xz 5.2.3 -3 | 4,18 Mo/s | 55 Mo/s | 55745125 | 26.30 |
| zstd 1.1.4 -8 | 30 Mo/s | 609 Mo/s | 61021141 | 28.79 |
| zling 2016-01-10 -2 | 32 Mo/s | 136 Mo/s | 61917662 | 29.21 |
| xz 5.2.3 -0 | 15 Mo/s | 44 Mo/s | 62579435 | 29.53 |
| zling 2016-01-10 -0 | 38 Mo/s | 134 Mo/s | 63407921 | 29,92 |
| zstd 1.1.4 -5 | 88 Mo/s | 553 Mo/s | 64998793 | 30,67 |
| lzfse 2017-03-08 | 48 Mo/s | 592 Mo/s | 67624281 | 31,91 |
| libdeflate 0.7 -6 | 64 Mo/s | 609 Mo/s | 67928189 | 32.05 |
| brotli 2017-03-10 -2 | 98 Mo/s | 289 Mo/s | 68085200 | 32.12 |
| zstd 1.1.4 -2 | 185 Mo/s | 587 Mo/s | 70164775 | 33.10 |
| tornade 0.6a -4 | 91 Mo/s | 197 Mo/s | 70513617 | 33.27 |
| libdeflate 0.7 -3 | 96 Mo/s | 602 Mo/s | 70668968 | 33.34 |
| xpack 2016-06-02 -1 | 98 Mo/s | 506 Mo/s | 71090065 | 33,54 |
| tornade 0.6a -3 | 119 Mo/s | 188 Mo/s | 72662044 | 34.28 |
| libdeflate 0.7 -1 | 117 Mo/s | 570 Mo/s | 73318371 | 34,59 |
| lézard 1.0 -42 | 90 Mo/s | 938 Mo/s | 73350988 | 34,61 |
| zstd 1.1.4 -1 | 242 Mo/s | 636 Mo/s | 73654014 | 34,75 |

Il existe plusieurs implémentations de deflate, mais on ne sait pas si elles sont comparables.
xz gauche pour référence
zstd a l'air si prometteur. Dommage qu'il n'y ait pas d'implémentation Go

@viric zstd n'est pas tout à fait la vitesse lz4.

mais si l'on veut avoir un seul compresseur plutôt que plusieurs, zstd est plus flexible.

Pardonnez mon retard. Certains commentaires:

Vitesse de compression : est importante car nous allons effectuer cette opération à chaque fois que nous ajoutons un bloc, nous voulons donc vraiment quelque chose qui puisse suivre l'AES-NI et les E/S générales afin de ne pas devenir un goulot d'étranglement. Nous ne voulons probablement pas choisir un algorithme qui compresse plus lentement qu'il ne décompresse car nous avons le cas d'utilisation inverse des navigateurs Web pour lesquels ces nouveaux algorithmes (comme zstd, lz4, brotli) sont optimisés (nous avons "compresser souvent, décompresser rarement" par opposition à "compresser une fois, décompresser souvent").

Non, il n'est pas nécessaire de compresser à des vitesses AES accélérées par le matériel. La compression consiste à échanger le temps contre la taille. Il est tout à fait prévu que les sauvegardes compressées prendront plus de temps.

Par exemple, plutôt que d'utiliser restic sur mes sauvegardes personnelles, j'utilise toujours Obnam, car sur l'un des petits serveurs sur lesquels je les stocke, si elles n'étaient pas compressées, elles ne rentreraient pas. Les sauvegardes prennent déjà des heures et elles s'exécutent en arrière-plan, donc je ne m'en rends même pas compte.

Peu m'importe si les sauvegardes compressées de restic prennent plus de temps. En effet, je m'y attends, et c'est le compromis que je dois faire. Sans ce genre de compression, restic ne me serait pas utile.

Vitesse de décompression : La vitesse de décompression n'est pertinente que lorsque nous restaurons. Si nous sommes d'accord avec une restauration lente, nous pouvons accepter une vitesse de décompression lente. D'un autre côté, nous avons également des métadonnées que nous ne voulons pas décompresser lentement, ce qui pourrait même justifier deux algorithmes différents.

Les restaurations sont effectuées beaucoup moins fréquemment que les sauvegardes, la vitesse de décompression n'est donc pas aussi importante. Quelqu'un a mentionné qu'elles sont souvent effectuées sous la pression du temps : c'est vrai, mais cela ne signifie pas que les restaurations doivent être aussi rapides que les sauvegardes, ou n'importe où à proximité.

Nous avons également deux (au moins ?) types de données différents : les index ; et les morceaux de données. Les deux sont utilisés différemment, et je suppose que l'on pourrait discuter de la pertinence de choisir des algorithmes différents pour eux.

Il n'est peut-être pas nécessaire (ou nécessairement une bonne idée) de compresser les index du tout. Étant des index, il semble peu probable qu'ils se compressent bien en premier lieu, car leur objectif est de stocker des données uniques.

Personnellement, je pense que nous devrions nous en tenir à un algorithme (quel que soit notre choix) afin que la réimplémentation de Restic (dans une nouvelle langue ou autre) ne soit pas rendue déraisonnablement difficile. Et pour que nous ne nous exposions pas aux bogues de deux algorithmes de compression passionnants car ceux-ci sont difficiles à tester pour les cas extrêmes.

Je comprends ces préoccupations, mais je pense que ce serait une erreur. Au minimum, le format de dépôt doit permettre plusieurs algorithmes de compression afin que de nouveaux puissent être ajoutés à l'avenir. Il devrait probablement y avoir des modules enfichables pour la compression afin que les utilisateurs puissent sélectionner ceux qu'ils souhaitent utiliser, par exemple, je pourrais imaginer des packages Debian comme restic-xz , restic-zstd , etc. que les utilisateurs pourraient installer s'ils le souhaitaient utiliser ces algorithmes. La compression des données de sauvegarde doit être abstraite afin que restic remette à une fonction de compression certaines données et les récupère compressées, et restic ne devrait pas se soucier de ce qui se passe entre les deux ; idem pour la décompression.

Si l'exigence de sauvegarde rapide est abaissée, disons, >=30 Mo/sec, nous pourrions ajouter

Cela me semble raisonnable. N'oubliez pas que les sauvegardes locales sont d'un seul type ; les sauvegardes réseau sont moins susceptibles d'être entravées par la vitesse de compression.

Mais, encore une fois, cela devrait être paramétrable par les utilisateurs afin qu'ils puissent sélectionner la solution appropriée à leurs besoins.

Ajout d'une prime de 10$ pour une :bière: :)
image

++

Voici un lien vers la BountySource si quelqu'un d'autre souhaite contribuer
badge
https://api.bountysource.com/badge/issue?issue_id=6096108

Je me demande si cela peut être implémenté de manière configurable par l'utilisateur, de sorte que le choix de la vitesse par rapport à la taille soit laissé à l'utilisateur pour décider. Je préférerais une compression plus élevée par défaut.

Décidons quand nous y arriverons. Pour mémoire : je suis d'accord pour donner à l'utilisateur un peu de contrôle en termes de vitesse par rapport à la taille.

+1 pour restic nécessitant une implémentation de compression. J'utilise restic pour sauvegarder les images de la VM et j'aimerais pouvoir les compresser avant de les télécharger. Dans mon cas d'utilisation, j'échangerais une quantité presque infinie de temps/CPU pour réduire la taille des données transférées/stockées. Je me rends compte que la vitesse est plus une préoccupation pour certains. Il est essentiel d'avoir une architecture enfichable où plusieurs algorithmes peuvent être sélectionnés.

Je suis heureux d'aider à tester car cela est examiné plus loin.

@fd0 Cela fait un moment que je n'ai pas travaillé sur la base de code restic. Est-il possible pour vous de donner une direction rapide sur une bonne approche et où je dois regarder ?

@klauspost Il ne s'agit pas tant d'ajouter de la compression à un niveau technique, c'est plutôt facile à faire, mais de savoir comment nous gérons la mise à niveau du format de référentiel de manière rétrocompatible. Je suis actuellement occupé à réécrire la partie archiveur (afin que les choses laides comme #549 disparaissent), après cela, j'aimerais ajouter de la compression, puis passer au repo v2.

Quelle est votre opinion sur l'algorithme de compression que nous devrions utiliser ? Je pense prendre en charge trois modes :
1) Pas de compression
2) Compression "temps linéaire" (n'ajoute pas beaucoup de charge CPU)
3) "Compression maximale"

Peut-être que le premier et le deuxième mode seront les mêmes, je ne suis pas encore sûr

Ce serait vraiment génial de pouvoir utiliser quelque chose comme zstd, mais en tant que code Go natif. Damian a laissé entendre que le portage de la version Java ou C n'est peut-être pas beaucoup de travail : https://twitter.com/dgryski/status/947259359628738560, y a-t-il quelque chose que je puisse faire pour vous intéresser à essayer cela ? :)

J'ai regardé les spécifications du format zstd, et pour moi, ce n'est pas trivial à mettre en œuvre (enfin). Les sources Java ne sont que de la décompression.

Pour une compression rapide, LZ4 devrait faire très bien. Le port Go est excellent. zstd serait mieux, mais j'irais avec un package éprouvé, à moins que vous ne vouliez utiliser l'implémentation cgo.

Pour le milieu de la route, la compression de dégonflage est toujours bonne en termes de vitesse/compression. Bien testé, etc.

Une compression élevée est un peu plus délicate. Il semble cependant qu'il existe une implémentation native de LZMA(2) Go dans le package github.com/ulikunitz/xz . Il y a quelques mises en garde concernant la stabilité et les performances sur le README. Le wrapper xz n'est pas nécessaire, car vous avez déjà un hachage et une taille non compressés. Je peux lui donner un tourbillon et voir comment il se compare.

J'ai jeté un œil à la source pour trouver l'endroit naturel pour insérer l'étape de compression. Ce qui avait du sens pour moi, c'était d'avoir une compression ici et une décompression ici . Mais je vois le défi dans l'identification et le suivi de la compression.

Vous pouvez également jeter un œil à un "estimateur de compressibilité" que j'ai créé. Il donnera une estimation rapide de la compressibilité d'un blob de données. Il fonctionne généralement à > 500 Mo/s, il peut donc être utilisé pour rejeter rapidement les données difficiles à compresser.

Vous pouvez également jeter un œil à un "estimateur de compressibilité" que j'ai créé. Il donnera une estimation rapide de la compressibilité d'un blob de données. Il fonctionne généralement à > 500 Mo/s, il peut donc être utilisé pour rejeter rapidement les données difficiles à compresser.

J'adore l'estimateur de compressibilité ! Éviter les tentatives de compression de données incompressibles gagnerait beaucoup en vitesse.

Zstd a quelque chose comme ça intégré: [1]

Zstd passe plus rapidement sur les données incompressibles. Attendez-vous à quelque chose > 1 Go/s

Bien que je n'aie trouvé aucune référence explicite à ce sujet.

Le package xz semble être une bonne affaire pour lzma. J'ai fait quelques tests rapides avec les paramètres par défaut :

| algorithme | niveau | taille | surdimensionné | millièmes | mb/s | rapport |
|-----------|------|-----------|-----------|---- ----|--------|--------|
| 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% |

Compromis vitesse/compression très raisonnable. Tous sont des performances à cœur unique sur enwik9 - corps de texte moyennement compressible. Évidemment, je n'ai pas eu le temps de tester une image de VM complète ou quelque chose comme le corpus de 10 Go avec un contenu plus mixte.

Il ne semble pas que lzma2 offre beaucoup dans son implémentation actuelle par rapport à lzma standard. Puisque vous avez affaire à de petits blocs, la différence devrait être assez petite.

Zstd a quelque chose comme ça intégré

Oui, tout comme lz4 et deflate, cependant, je ne l'ai pas vu aussi rapide qu'une fonction dédiée.

zstd est vraiment impressionnant, sans aucun doute. Benchmarks utilisant l'implémentation cgo :

| niveau | taille | surdimensionné | millièmes | mb/s | rapport |
|-------|------------|----------|--------|------- -|--------|
| 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 % |

Pardonnez-moi si j'ai raté quelque chose, mais je n'ai pas vu de réponses à ces questions plus tôt.

  1. Nous semblons parler de compression au niveau du morceau, pas au niveau du fichier, n'est-ce pas ?
  2. Si c'est le cas, cela limite évidemment l'efficacité puisque les données dupliquées dans plusieurs morceaux d'un seul fichier seront stockées et compressées pour chaque morceau.
  3. Cependant, cela dépend évidemment aussi de la taille du morceau.
  4. Alors, quelle est la taille moyenne des morceaux ? On dirait que c'est un facteur important dans l'utilité de la compression.
  5. Si la taille du morceau est assez petite, nous devrions peut-être envisager une compression de fichier complet, pré-couplage pour les fichiers hautement compressibles (par exemple, en utilisant l'estimateur de @klauspost ). Par exemple, un fichier texte de 50 Mo (par exemple, des fichiers journaux, de gros fichiers en mode organisation, etc.) est susceptible d'être hautement compressible en un seul fichier. Mais s'il est d'abord fragmenté, puis que chaque fragment est compressé individuellement, sans partager d'index, cela limitera considérablement l'efficacité de la compression (IIUC).

Merci.

Si nous compressions des fichiers entiers, cela pourrait altérer l'algorithme de déduplication, le rendant éventuellement moins efficace.

En dehors de cela, n'oublions pas que toute compression, tout en offrant d' énormes avantages en termes d'espace , nous ouvre à une attaque par canal latéral. À partir d'une taille de données compressées, on peut faire une estimation éclairée du contenu des données. Je pense que cela a déjà été mentionné, mais quand même.

@alphapapa

Nous semblons parler de compression au niveau du morceau, pas au niveau du fichier, n'est-ce pas ?

Oui, au niveau des morceaux.

Si c'est le cas, cela limite évidemment l'efficacité puisque les données dupliquées dans plusieurs morceaux d'un seul fichier seront stockées et compressées pour chaque morceau. Cependant, cela dépend évidemment aussi de la taille du morceau. Alors, quelle est la taille moyenne des morceaux ? On dirait que c'est un facteur important dans l'utilité de la compression.

Nous visons 1 Mio, mais il peut atteindre 8 Mio.

Si la taille du morceau est assez petite, nous devrions peut-être envisager une compression de fichier complet, pré-couplage pour les fichiers hautement compressibles (par exemple, en utilisant l'estimateur de @klauspost ). Par exemple, un fichier texte de 50 Mo (par exemple, des fichiers journaux, de gros fichiers en mode organisation, etc.) est susceptible d'être hautement compressible en un seul fichier. Mais s'il est d'abord fragmenté, puis que chaque fragment est compressé individuellement, sans partager d'index, cela limitera considérablement l'efficacité de la compression (IIUC).

Au début, j'aimerais intégrer la compression au niveau des morceaux et voir à quel point cela fonctionne dans des scénarios réels. Nous pourrons revoir cette idée plus tard.

@klauspost Merci beaucoup d'avoir pris le temps de comparer certains algorithmes/implémentations et vos recommandations, je l'apprécie ! Bien que ce serait bien d'avoir zstd, je pense que ne pas dépendre de cgo est beaucoup plus important pour le projet dans son ensemble. Et utiliser un estimateur de compressibilité est une excellente idée, j'adore ça.

Les endroits que vous avez mentionnés pour ajouter la compression/décompression sonnent bien, mais nous devons suivre les métadonnées pour cela ailleurs. Je pense que nous allons probablement ajouter un sens aux bits de l'octet dans l'en-tête du pack, voir http://restic.readthedocs.io/en/latest/100_references.html#pack -format. C'est la partie qui doit être faite très soigneusement.

Alors, laissez-moi finir avec #1494, puis nous verrons que cela se résout.

@sanmai re: side-channels: J'ai soulevé cela à l'origine.
Diverses solutions ont été suggérées, je me contenterais personnellement de :

  • avoir des options de configuration pour l'utilisation de la compression sur liste blanche/liste noire (similaire à ce que nous avons pour l'inclusion de fichiers)

Une autre idée était d'essayer de cacher les limites des morceaux dans les fichiers pack, ce qui rendrait théoriquement les choses plus difficiles, mais je pense que vous seriez toujours en mesure de chronométrer les écritures sur le réseau et les canaux secondaires comme dans quelle mesure du système de fichiers le morceau a été écrit. et ainsi de suite pourraient être utilisés pour déduire les limites, donc je pense que le plus sûr/le plus facile serait de simplement conseiller de ne pas compresser les données sensibles.

Ce serait génial ! :bière: +10$

Juste en le jetant là-bas, mais en mettant de côté lzma ou l'un des algos de compression plus généraux, qu'en est-il simplement de l'encodage de la longueur d'exécution ou de l'écrasement de zéro ? Ou cela ne serait-il pas suffisamment utile à suffisamment de personnes ?

(J'ai un chien dans cette chasse, je sauvegarde souvent d'énormes fichiers WAV avec beaucoup de silence.)

+$15

Juste en le jetant là-bas, mais en mettant de côté lzma ou l'un des algos de compression plus généraux, qu'en est-il simplement de l'encodage de la longueur d'exécution ou de l'écrasement de zéro ? Ou cela ne serait-il pas suffisamment utile à suffisamment de personnes ?

Également utile pour sauvegarder les lecteurs VM avec principalement de l'espace vide/des fichiers épars (je ne sais pas si restic prend déjà en charge la sauvegarde/restauration des fichiers épars)

@bherila restic ne prend pas encore en charge l'archivage/la restauration de fichiers épars, les fichiers seront stockés dans le référentiel comme s'ils ne contenaient que de nombreux zéros. Ces gros blocs de zéros sont dédupliqués, cela ne prendra donc pas beaucoup de place dans le référentiel. Pour la restauration, cependant, vous vous retrouverez avec un fichier régulier (non fragmenté) sans "trous".

Je voulais juste vérifier, y a-t-il déjà une sorte de compression? J'ai sauvegardé plusieurs ordinateurs, dont un avec 50 Go de données, et j'obtiens un nombre bien inférieur sur le serveur :

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

@Alwaysin C'est probablement la déduplication , à moins que certains fichiers aient été exclus bien sûr.

@rawtaz merci, je n'étais pas au courant de la déduplication, ça doit être ça !

L' écrasement

@klauspost as -tu vu ça ? https://github.com/mvdan/zstd

Oui, mais honnêtement, un décodeur de flux est la partie facile. J'ai terminé l'en/décodage FSE et j'ai un encodeur Huffman prêt. Une fois le décodage Huffman terminé, un décodeur de flux zstd est assez simple, l'encodeur complet étant la partie finale.

LZ4 est parfaitement suffisant et serait également un gain rapide.

Pourquoi ne pas ajouter lz4 et créer un autre PR pour prendre en charge zstd ?

Pourquoi ne pas ajouter lz4 et créer un autre PR pour prendre en charge zstd ?

@dave-fl car nous devons être très prudents lorsque nous modifions le format du référentiel. Cela doit être fait de manière rétrocompatible. La partie la plus importante de l'ensemble du projet est le format du dépôt, pas la mise en œuvre. Les gens comptent sur nous pour ne pas bousiller le format afin de pouvoir restaurer leurs données :)

Je pense qu'on ne peut pas trop attendre avec la compression. Je viens de faire quelques tests sur quelques dépôts de sauvegardes de serveurs, je ne gagne exactement rien quand je gzip le dépôt ! Comme @Alwaysin je gagne déjà 30% avec la déduplication.

À propos de la rétrocompatibilité, vous voulez dire que Restic devrait lire les deux formats ou un outil pour migrer de l'ancien vers le nouveau ? Lorsque Restic n'est pas à la version 1.0.0, je pense que vous pouvez simplement migrer.

Je viens de faire quelques tests sur quelques dépôts de sauvegardes de serveurs, je ne gagne exactement rien quand je gzip le dépôt !

Euh, c'est normal : toutes les données du référentiel sont cryptées, elles sont donc à peine compressibles. Si la compression est utilisée, elle doit être effectuée sur les données avant de les chiffrer.

Je ne vois pas en quoi l'utilisation de LZ4 rend les choses non rétrocompatibles. La compression est la compression. Pourquoi ne pas prendre en charge plusieurs formats ?

Tu as raison, je n'y ai pas pensé.
Cependant quand je gzip le source je ne gagne pas plus de 30%, la déduplication est déjà très efficace sur un gros répertoire avec beaucoup de doublons. Mais bien sûr, avec les deux, cela peut être impressionnant.
Avec zpaq qui fait de la compression et de la déduplication, je gagne juste un peu plus, pas tellement.
Je suis très ouvert à tester une branche avec compression, peu importe si ce n'est pas compatible !

Je ne vois pas en quoi l'utilisation de LZ4 rend les choses non rétrocompatibles. La compression est la compression. Pourquoi ne pas prendre en charge plusieurs formats ?

Que se passe-t-il si 2 clients utilisent le même référentiel mais que 1 d'entre eux utilise une ancienne version de restic qui ne prend pas en charge la compression ? Cette fonctionnalité doit être conçue avec soin en tenant compte de tous les cas d'angle possibles.

Je préférerais qu'il n'y ait pas de compression plutôt qu'une solution à moitié fonctionnelle qui interrompe les sauvegardes précédentes.

Je pense qu'il y a eu suffisamment de discussions sur la question de l'ajout de compression. Je peux voir que c'est une fonctionnalité très attendue. Je m'attaquerai à cela après avoir terminé le nouveau code de l'archiveur (voir #1494).

S'il vous plaît ne pas ajouter d'autres commentaires, merci!

@dimejo Ce que vous

J'ose dire que la version CGO de zstd a l'air quelque peu portable :)

J'ai regardé à quel point il serait possible d'écrire une implémentation golang de zstd, très brièvement, basée sur la spécification .

zstd principalement tous les algorithmes internes mais (éventuellement) s'appuie sur la somme de un port golang de ce . puisque les bits facultatifs sont, eh bien, facultatifs, vous n'auriez pas à implémenter ces parties pour obtenir la prise en charge de zstd pour un lecteur/enregistreur en restic. zstd prend en charge le concept de "dictionnaires" pour optimiser la compression - je ne sais pas comment cela interagirait avec restict, mais ce serait un domaine de recherche intéressant pour compresser des parties spécifiques de l'archive, par exemple JSON ou des flux de métadonnées. sinon, cette implémentation pourrait également être ignorée car elle est facultative.

Là où cela devient plus délicat, bien sûr, c'est là que le codage entropique entre en jeu. zstd utilise une nouvelle approche appelée entropie à états finis (FSE, une variante de [ANS](https://en.wikipedia.org/wiki/Asymmetric_numeral_systems#, dont seule une implémentation C existe également. D'autres bits de codage entropique sont implémentés avec le codage huffman , dont il existe plusieurs implémentations, dont deux dans la bibliothèque standard : une dans compress.flate et une autre dans net.http2.hpack , qui est plutôt étrange.

D'après ce que je peux dire, tout le reste est collé dessus... Des arbres de Huffman, des séquences, des cadres et des blocs. Il existe également des propriétés intéressantes dans la façon dont les blocs et les cadres sont construits qui pourraient bien correspondre aux blobs restic, ce qui pourrait permettre de compresser le référentiel dans son ensemble tout en gardant les blobs séparés à l'intérieur, bien que je n'aie pas examiné cela en détail . Cela peut également rendre inacceptable le couplage entre le format du référentiel et la compression.

zstd est largement plus compliqué que gzip ou xzip, avec environ 70 000 lignes de code (selon la horloge) contre 36 000 et 12 000, respectivement. cela inclut cependant des tests qui sont nombreux : lorsque ceux-ci sont ignorés, l'implémentation elle-même est à peu près comparable à gzip (~34k).

donc, en résumé, ce n'est qu'une question de temps avant que cela ne soit mis en œuvre dans go. Je pense qu'un tel moteur pourrait également tirer parti du parallélisme de golang car les "frames" zstd sont indépendants les uns des autres. Cependant, je ne sais pas comment les cadres sont utilisés : la plupart des flux que j'ai testés n'avaient qu'un seul ( zstd /etc/motd ) ou deux ( zstd isos/Fedora-Workstation-Live-x86_64-27-1.6.iso ) cadres (tels que trouvés par binwalk -R "\x28\xb5\x2f\xfd" ), donc peut-être pas un tel gain là-bas, car les blocs sont interdépendants et moins parallélisables...

de toute façon, tous discutables à moins que quelqu'un ici veuille réellement s'asseoir et porter cela, mais j'ai pensé que je partagerais ce que j'ai trouvé en lisant la chose ... étant donné que zstd est une extension de LZMA faisant partie de la famille de compresseurs LZ77, cela ne devrait pas il ne sera pas impossible de porter...

Une mise à jour sur la compression ? Je sais que beaucoup de gens veulent attendre zstd , mais qu'y aurait-il de mal à implémenter lz4 ou lzo ou lzma ?

S'il y avait une mise à jour, ce problème serait mis à jour.

Essayons de respecter la demande de l'auteur en attendant :

S'il vous plaît ne pas ajouter d'autres commentaires, merci!

@fd0 , je voulais juste souligner qu'il semble y avoir une pure implémentation Go de l'algorithme zstd https://github.com/klauspost/compress/tree/master/zstd . Je n'ai pas essayé moi-même. Mais cela m'a enthousiasmé par la possibilité d'un support de compression dans restic.

Je ne connais pas les trucs Go zstd (vitesse ? qualité du code ? maintenance ?), mais les trucs C zstd sont à peu près tout ce dont un outil de sauvegarde a besoin car il prend en charge une large gamme de compression rapide/peu à plus lente/élevée.

Si nous n'avions pas déjà tous les autres algorithmes de compression (lz4, zlib, lzma) dans borgbackup et que nous commencions à ajouter de la compression maintenant, supposons que nous pourrions vivre avec uniquement zstd et aucun.

Pour une question de goût/préférence, la valeur par défaut pourrait être aucune (comme c'était le cas auparavant) ou un niveau zstd très rapide (ce qui, dans l'ensemble, rend la plupart des sauvegardes plus rapides car il y a moins de données à transférer).

Bonjour,
à mon avis, la compression n'est pas une fonctionnalité indispensable pour restic. J'ai comparé la sauvegarde de mes données avec Duplicati (avec compression) et restic (sans compression) et l'espace global utilisé était vraiment similaire.
J'ai besoin de restic uniquement pour obtenir une sauvegarde incrémentielle rapide et fiable. Pas besoin de casser le mors...
La restauration est également importante et restic convient à la reprise après sinistre. Duplicati est un cauchemar car si vous perdez la base de données locale, la tâche de réparation prend des jours...

Merci @fd0 et merci à tous les contributeurs !

@filippobottega si vous n'avez pas vu de grande différence dans votre expérience, cela signifie :

  • que vos données n'étaient pas (beaucoup) compressibles (mais ce n'est pas le cas en général), ou
  • que duplicati avait une efficacité de stockage pire sans rapport avec la compression (par exemple en raison de différents formats de stockage, granularité, algorithmes, etc.), de sorte que les économies de compression ont été compensées par des pertes dans d'autres domaines.

les deux ne signifient pas que la compression est inutile.

@ThomasWaldmann Je ne vois pas de grande différence pour la première raison.
Les données d'aujourd'hui sont déjà compressées de plusieurs manières : docx, xlsx, pptx, zip, 7z, jpeg, tif et ainsi de suite sont tous des formats compressés. Et aussi les images ISO contiennent des fichiers compressés. Pour cette raison, la compression est inutile en restic je pense.

@filippobottega Votre point de vue est un peu étroit sur les données que les gens utilisent restic pour sauvegarder. Qu'en est-il des vidages SQL, du code source, des ensembles de données, des images brutes, etc. ? La déduplication fait un excellent travail pour réduire la taille delta entre les sauvegardes, mais elle ne fait rien pour réduire la taille d'origine de l'ensemble de données. Dans le cas de formats non compressés, cela peut signifier plusieurs gigaoctets. Sans compter que le stockage d'un format non compressé puis la compression + la déduplication pourraient donner de meilleurs résultats que la déduplication des fichiers déjà compressés.

Les vidages SQL ont été ma première pensée, mais restic sauvegarde également mon serveur de messagerie et il semble que la compression globale soit meilleure sur la base de certains instantanés RAR que j'ai pris lors du passage de Duplicati à restic.

Je peux voir le cas d'utilisation pour rendre la compression facultative et avoir une liste par défaut de types de fichiers, mais la compression me ferait économiser une somme d'argent raisonnable.

@mrschyte

Votre point de vue est un peu étroit sur les données que les gens utilisent restic pour sauvegarder.

Maintenant maintenant, pas besoin de devenir personnel. Son point de vue est tout aussi valable que le vôtre et mérite d'être considéré. J'ai constaté que la plupart des données que je sauvegarde sont déjà compressées en raison des formats de fichiers.

Qu'en est-il des vidages SQL

Stockez-vous vraiment vos dumps SQL non compressés ? Je gz tous les miens avant de les sauvegarder, car je n'ai pas besoin de les stocker bruts.

code source, ensembles de données, images brutes, etc.

Je pense que le seul cas d'utilisation valide pour la sauvegarde compressée concerne les fichiers volumineux non compressés avec beaucoup de répétition _qui sont activement utilisés et ne sont donc pas déjà stockés compressés_. D'après mon expérience (qui comprend des années de gestion des données d'autres personnes), très peu de données entrent dans cette catégorie. Du moins, pas assez pour faire une énorme différence dans ces cas.

cependant, cela ne réduit en rien la taille d'origine de l'ensemble de données.

Sans doute, ce n'est pas le travail d'un programme de sauvegarde. Il ne doit pas toucher les données d'origine.

Sans compter que le stockage d'un format non compressé puis la compression + la déduplication pourraient donner de meilleurs résultats que la déduplication des fichiers déjà compressés.

De nombreux algorithmes de compression reposent sur la duplication pour faire leur travail (voir les dictionnaires de flate), donc je ne suis pas convaincu par cela _en général_ bien que je convienne que c'est juste au moins quelques fois.

(Je ne dis pas que la compression dans restic est _mauvais_ lorsqu'elle est effectuée correctement, je dis simplement que cela n'a pas besoin d'être une priorité - en particulier par rapport aux problèmes de performances persistants - et nous devons respecter les contraintes de temps de @fd0 et souhaits en ce qui concerne la vision.)

@mholt Je serais d'accord en général, mais faire une sauvegarde racine (via un vidage ou même une itération sur le contenu de /), me donne un bon taux de compression. Pas indispensable , car le total utilisé est déjà faible, mais j'obtiens environ 50% d'économies, et c'est toujours agréable d'avoir "gratuitement" en ce qui concerne l'utilisateur final.

Essayez ce test.

  1. prenez un vidage SQL ou un autre fichier non compressé. Compressez-le puis
    utilisez restic pour le sauvegarder.
  2. supprimer une table de la base de données SQL, faire un deuxième dump, puis le compresser,
    puis utilisez restic pour le sauvegarder.

Je crois que vous le trouverez car la compression se fait AVANT
déduplication, vous vaincrez presque entièrement l'algorithme de déduplication de restics.
Cependant, si restic pouvait gérer la compression APRÈS vous avoir dédupliqué
devrait obtenir une sortie globale beaucoup plus petite.

Dans l'industrie du stockage d'entreprise avec des outils comme DataDomain, il est toujours
recommandé de transmettre les données au périphérique de stockage dans un format non compressé
formater et laisser l'appareil faire la déduplication, puis la compression. Les
l'ordre général d'application de ces outils est la déduplication,
compression, puis cryptage. Pensez-y une seconde....est-ce que vous
voulez vraiment passer tout le CPU supplémentaire à compresser les mêmes données multiples
fois seulement pour qu'il soit dédupliqué et essentiellement mis au rebut de toute façon? Son
généralement accepté qu'il est préférable de réduire l'ensemble de données via la déduplication d'abord
avant de passer à la tâche potentiellement lourde de faire de la compression.

Le ven. 2 août 2019 à 13:29 Brandon Schneider [email protected]
a écrit:

@mholt https://github.com/mholt Je serais d'accord en général, mais en faisant
une sauvegarde root (via un dump ou même en itérant sur le contenu de /),
donne un bon taux de compression pour moi. Pas indispensable , car le total
d'occasion est déjà petit, mais j'obtiens environ 50% d'économies, et c'est toujours agréable
avoir "gratuitement" pour l'utilisateur final.

-
Vous recevez ceci parce que vous êtes abonné à ce fil.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/restic/restic/issues/21?email_source=notifications&email_token=AC3I762ZVGTTJL4TF3ODZILQCRVIXA5CNFSM4AXPP352YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJZKTDN5WW352YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJZKTDN5WW2GA
ou couper le fil
https://github.com/notifications/unsubscribe-auth/AC3I767IQQD3CZBIWM37C6TQCRVIXANCNFSM4AXPP35Q
.

Stockez-vous vraiment vos dumps SQL non compressés ? Je gz tous les miens avant de les sauvegarder, car je n'ai pas besoin de les stocker bruts.
Sans doute, ce n'est pas le travail d'un programme de sauvegarde. Il ne doit pas toucher les données d'origine.

Vous avez l'impression que ce type de vue entrave le stockage efficace des données ? L'idée que chaque programme et opération d'exportation devrait implémenter son propre format de compression ad hoc est quelque chose dont j'essaie de m'éloigner, car cela empêche la déduplication/compression/etc de fonctionner sur autre chose qu'une portée prédéfinie par fichier (ou tarball de répertoire) . La compression de fichiers individuellement perd la possibilité de trouver des points communs entre différents fichiers/dumps/etc et par la suite, vous perdez tous les avantages de la déduplication. Garder les choses non compressées permet à un système de fichiers (zfs, btrfs, etc.) de faire tout cela pour vous, et mieux car il peut à la fois compresser et dédupliquer à travers des dossiers, des instantanés, etc. et abstrait tout cela tout en conservant la compatibilité avec les outils qui doivent fonctionner avec les données non compressées.

La compression peut être considérée comme une simple optimisation supplémentaire sur la déduplication de top restic, mais elles semblent incompatibles les unes avec les autres si elles sont effectuées séparément... Suggérer de compresser et de prétraiter les fichiers avant de les sauvegarder ramène tout à un flux de travail où vous pouvez également utilisez simplement rsync/rclone à la place, alors pourquoi utiliser restic en premier lieu ?

Vous avez l'impression que ce type de vue entrave le stockage efficace des données ? L'idée que chaque programme et opération d'exportation devrait implémenter son propre format de compression ad hoc est quelque chose dont j'essaie de m'éloigner, car cela empêche la déduplication/compression/etc de fonctionner sur autre chose qu'une portée prédéfinie par fichier (ou tarball de répertoire) . La compression de fichiers individuellement perd la possibilité de trouver des points communs entre différents fichiers/dumps/etc et par la suite, vous perdez tous les avantages de la déduplication. Garder les choses non compressées permet à un système de fichiers (zfs, btrfs, etc.) de faire tout cela pour vous, et mieux car il peut à la fois compresser et dédupliquer à travers des dossiers, des instantanés, etc. et abstrait tout cela tout en conservant la compatibilité avec les outils qui doivent fonctionner avec les données non compressées.

Il ne s'agit pas seulement d'un stockage efficace des données, il s'agit également des workflows existants. Je veux un produit de sauvegarde pour sauvegarder mes données de manière fiable et efficace, et non pour appliquer des flux de travail sur d'autres aspects du système. Il est bien plus important que les sauvegardes (qui sont conservées, potentiellement indéfiniment) soient stockées efficacement, tandis que les données de travail en direct doivent être stockées dans le meilleur format pour leur utilisation active.

Maintenant, il y a des cas où il est logique de compresser avant de stocker, en particulier avec des données très compressibles sur des systèmes de stockage lents, mais c'est l'exception plus que la règle dans mon expérience.

+1 compression m'aiderait vraiment ! Au travail en tant qu'ingénieur logiciel, je sauvegarde l'intégralité de mon dossier personnel, qui contient beaucoup de code source non compressé (et dans les langages dynamiques, comme ruby ​​ou python, c'est presque toujours du code source - même la plupart des dépendances).

À la maison, je sauvegarde l'intégralité de mon / , y compris à nouveau de nombreuses choses qui bénéficient de la compression, telles que les binaires, les fichiers man, les fichiers de ressources, etc.

Bien sûr, je pourrais tous les compresser et effectuer de nombreuses transformations avant de les sauvegarder, mais cela nuirait à la commodité d'exécuter une commande très simple et de pouvoir obtenir une sauvegarde, ainsi que facilement restaurer les choses.

Maintenant, bien sûr, il existe de nombreuses classes de fichiers qui ne se compressent pas bien, mais personne ne dit qu'ils devraient être forcés d'être compressés. Il existe de nombreuses approches pour résoudre ce problème : liste blanche des types de fichiers qui doivent être compressés, liste noire des fichiers qui ne devraient pas l'être, ou même la plus simple : essayez de compresser, et si la taille résultante ne s'améliore pas, stockez sans compression (je crois que ZFS utilise cette approche lorsque la compression sur disque est activée).

Au final, la compression est un exemple du compromis classique espace/temps : voulez-vous payer plus de processeur ou plus de stockage ? Dans mon cas, le stockage domine mes coûts, donc je pense que ce serait bien si mon quad-core chauffait un peu plus, et alors ma facture d'hébergement de fichiers était plus petite.

Enfin, je sauvegarde un peu plus de 4 To sur un fournisseur de cloud et ma vitesse de téléchargement est de toute façon faible, donc une compression bonus rendrait mon processus de sauvegarde plus rapide, pas plus lent - mon processeur peut plus que suivre ma mauvaise connexion VDSL .

Oui, je peux juste être d'accord avec tous les autres ici. La compression est assez importante et je ne vois vraiment aucun argument pourquoi restic ne devrait pas l'avoir.

@mholt je suis tout à fait d'accord avec toi. Tous les mots.
Dans ma chaîne d'outils, la compression précède la déduplication restic car, par exemple, j'utilise TFS comme contrôle de source et toutes les sources sont déjà compressées dans les sauvegardes SQL et les images d'application sont compressées dans les fichiers d'installation msi ou les archives 7z. J'ai seulement besoin d'un moyen simple et rapide d'obtenir le delta quotidien et de l'envoyer vers le cloud pour mettre en œuvre un plan de reprise après sinistre sécurisé.
Je pense que @fd0 doit consacrer son temps à résoudre les problèmes plutôt que d'essayer d'ajouter une autre complexité au produit.

Je viens juste de faire une petite comparaison entre borg en utilisant la compression auto,zstd et restic (pas de compression), d'abord sur / , puis sur /home , à l'exclusion de choses comme les images VM et images docker (puisque je ne les sauvegarde pas non plus dans une sauvegarde du monde réel). La machine de test était ma machine de développement de logiciels quotidienne, qui contient de nombreux fichiers binaires, des images et des fichiers audio compressés, mais aussi une bonne quantité de code source en texte brut, qui devrait se compresser assez bien :

/ : 1053136 fichiers, 92,9 Gio

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

/home : 221338 fichiers, 58,3 Gio

  • borg, zstd : 09:06 min, 30,7 Gio
  • restic: 04:36 min, 39,4 GiB
    J'ai omis borg sans compression ici, car il est à peu près le même que restic en ce qui concerne l'espace de stockage.

Tout d'abord, je tiens à féliciter restic d'avoir été presque exactement deux fois plus rapide sur ce cas de test. Outre que borg est plus lent, il peut être intéressant que la compression n'ajoute qu'environ 2 minutes à la durée globale de la sauvegarde (+11 %), mais réduise considérablement les données à stocker pour le cas / (-35 %). Dans le cas de mon répertoire personnel, les économies de stockage sont d'environ 20 %.

(Le test a été effectué sur un disque externe dans ce cas. Lors d'une sauvegarde sur un stockage distant, le temps de sauvegarde dépend principalement de la bande passante de téléchargement, du moins lorsque la vitesse du processeur et des E/S est bien supérieure à celle du réseau. J'ai testé this and borg avec compression est en fait plus rapide que restic alors, car la compression entraîne moins de transfert de données). Dans l'ensemble, je suis très favorable à ce que restic gagne en support de compression, idéalement en utilisant la détection automatique pour vérifier si un morceau bénéficie de la compression.

@nioncode Si mes calculs sont corrects, vous sauvegardez environ

Je sais que l'archivage des machines virtuelles peut être un cas d'utilisation, mais j'essaie d'éviter d'avoir à le faire.
J'essaie d'automatiser l'ensemble de la construction de la machine virtuelle à partir des fichiers iso et de configuration.
En cas de reprise après sinistre, je souhaite pouvoir restaurer l'intégralité de la machine virtuelle en utilisant la sauvegarde des fichiers d'installation, des documents et des bases de données. Et j'essaie de le faire sans interaction avec l'utilisateur.
De cette façon, je peux éviter d'avoir à compresser et à sauvegarder de nombreux fichiers de corbeille contenus dans une machine virtuelle, tels que des fichiers temporaires, des fichiers non compressés tels que des fichiers exe et dll, etc.
Je sais, ce n'est pas simple, mais je peux éviter de compresser et dédupliquer les mêmes Go de fichiers inutiles, économisant de l'espace disque et de la bande passante.

N'encombrons pas ce fil sur qui fait les choses comment. Cela a suffi.

La compression est une fonctionnalité que beaucoup de gens veulent (moi y compris) et elle peut économiser à la fois le stockage de sauvegarde et le temps de téléchargement en cas de connectivité Internet lente à moyenne, pour certaines personnes même 30% ou plus.

Cependant, tout le monde n'en a pas besoin et certaines personnes ont adapté leur flux de travail de manière intelligente pour y faire face - ou ont simplement l'argent ou la bande passante ou les deux pour ne pas s'en soucier.

En tout cas, les deux parties ont parlé.

@ bjoe2k4 ou sont préoccupés par les implications négatives sur la sécurité de la compression des données avant de les chiffrer, ce qui donne des informations sur les données en texte brut, comme cela a également été évoqué à plusieurs reprises dans ce fil de discussion au cours des dernières années. :)

À moins que la compression ne devienne obligatoire, les problèmes de sécurité de la compression ne sont qu'un compromis qu'un utilisateur peut faire. Je ferai des sauvegardes plus rapides et des coûts mensuels et ponctuels réduits par rapport à ce risque théorique (un risque qui ne pourrait probablement pas être exploité de toute façon car mes ensembles de données sont volumineux et les changements imprévisibles, de sorte que le bruit étoufferait toute tentative de générer un signal de compression).

Je ne crois pas que quiconque parle de rendre la compression obligatoire.

Mon cas d'utilisation spécial consiste à sauvegarder de GRANDS ensembles de vidages CSV et SQL. Ces fichiers seraient TRÈS compressibles... et je ne veux pas/ne peux pas les précompresser.

J'aimerais vraiment avoir la fonction de compression car je paie pour chaque Go de stockage en ligne

Étant donné que cette discussion devient un peu plus active maintenant, j'aimerais partager quelques découvertes que j'ai eues avec une version restic corrigée de certains de mes amis. Ils ont ajouté une compression à restic (plus ou moins rapide et sale pour autant que je sache) et je les informerai de ce message afin qu'ils puissent commenter les détails de l'implémentation si quelqu'un est intéressé.
Mon cas d'utilisation est un logiciel bancaire vraiment moche qui a son propre format de base de données. Nous devons utiliser ce logiciel pour des raisons réglementaires et les données dont nous disposons sont de plusieurs To de fichiers assez volumineux qui peuvent être compressés à 90 % de leur taille d'origine. Donc, bien évidemment, la compression nous permettrait d'économiser beaucoup en stockage de sauvegarde, en temps de sauvegarde et en temps de restauration.
Mes conclusions en comparant restic en amont, le restic patché avec compression et notre solution de sauvegarde actuelle avec tar peuvent être trouvées ici : https://gist.github.com/joerg/b88bf1de0ce824894ffc38f597cfef5f

| Outil | Temps de sauvegarde (m:s) | Temps de restauration (m:s) | Espace de sauvegarde (G) | Espace de sauvegarde (%) | Sauvegarde (Mo/s) | Restaurer (Mo/s) |
| --------------------------- | ----------------- | ------------------ | ---------------- | ---------------- | ------------- | -------------- |
| Goudron | 4:42 | 5:19 | 11 | 9,6% | 404 | 357 |
| Restic S3 local Amont | 10:04 | 30:56 | 102 | 89,5% | 189 | 61 |
| Compresser local Restic S3 | 5:43 | 19:28 | 8.6 | 7,5% | 332 | 98 |
| Reste Local Amont | 8:33 | 26:06 | 102 | 89,5% | 222 | 73 |
| Compression locale de Restic | 5:21 | 16:57 | 8.6 | 7,5% | 355 | 112 |
| Restic S3 à distance en amont | 17:12 | 46:06 | 102 | 89,5% | 110 | 41 |
| Compresseur à distance Restic S3 | 5:27 | 21:42 | 8.6 | 7,5% | 349 | 88 |

Je pense que restic gagnerait massivement avec une compression optionnelle de toute nature, car elle réduit à peu près tout.

Tous les fichiers n'auront pas un taux de compression intéressant. La compression d'un fichier vidéo ne vaut probablement rien, mais la compression d'un dump SQL l'est très certainement. C'est pourquoi les systèmes de fichiers comme Btrfs essaient d'abord de compresser les premiers 128 Ko d'un fichier et s'il y a un taux de compression important, ils compressent alors l'intégralité du fichier. Ce n'est certainement pas parfait mais c'est rapide et devrait fonctionner pour la plupart des cas d'utilisation s'il est décidé de compresser les fichiers individuellement.

Pour ceux qui sont contre plusieurs machines (qui soit prennent plus d'espace disque local dans le cas de la compression vers une nouvelle archive, soit rendent les fichiers inutilisables par leurs applications associées s'ils sont compressés sur place) avant d'effectuer une opération de sauvegarde.

Je préférerais pouvoir utiliser restic comme outil de sauvegarde DR, mais j'utilise actuellement borg (exigences de RAM lentes et massives, etc.) car la compression + déduplication qui en résulte m'économise de nombreux gigaoctets de transfert réseau par opération de sauvegarde et facilement sur un terraoctet d'espace de stockage (que je paie au mois) dans le cloud sur l'intégralité de mon jeu de sauvegarde. Je serais en mesure de conserver les sauvegardes plus longtemps ou de réduire mes coûts de stockage si restic prenait en charge la compression.

Bonjour @joerg , merci de partager vos tests.
Avez-vous essayé de sauvegarder avec restic la sortie de la tâche de compression Tar ?
Je suis curieux de savoir comment comparer "Restic S3 Remote Compress" et "Tar" + "Restic S3 Remote Upstream".
De plus ce que tu dis ne semble pas vraiment vrai :

Je pense que restic gagnerait massivement avec une compression optionnelle de toute nature car elle réduit à peu près tout

En voyant les résultats des tests, il semble que le temps CPU nécessaire à restic soit 2 fois plus long pour la sauvegarde locale et 6 fois plus long pour la restauration. Pas vraiment bon par rapport à Tar.

tar n'est pas un algorithme de compression. bien sur c'est rapide.
EDIT : oh et d'ailleurs. si vous tar un répertoire, il n'utilisera pas plusieurs threads par fichier et il ne fonctionnera pas non plus avec deux fichiers ou plus à la fois, à la place, il analysera le répertoire et ajoutera un fichier, puis passera au suivant. assez lent. mais le problème est le fichier d'archive qui n'est pas conçu pour être ajouté avec plusieurs threads.

En voyant les résultats des tests, il semble que le temps CPU utilisé par restic soit 2 fois plus lent en sauvegarde locale et 6 fois plus lent en restauration. Pas vraiment bon par rapport à Tar.

Je ne suis pas complètement sûr de votre point ici. restic est plus lent que Tar, bien sûr, mais restic avec compression est toujours plus rapide que restic sans, donc restic en bénéficierait clairement.

Tar est une comparaison utile à partir d'un « meilleur cas sur ce matériel », mais il manque la plupart des autres fonctionnalités de restic (les instantanés et la déduplication des données viennent à l'esprit). L'ajout de la compression semble seulement améliorer les temps de sauvegarde, les temps de restauration et les coûts de stockage, toutes choses qui sont importantes pour un produit de sauvegarde.

@joerg Vos amis peuvent-ils ouvrir une Pull Request et rendre publics leurs correctifs pour restic avec compression ? Quel algorithme de compression utilisent-ils ?

@joerg @thedaveCA
Je m'excuse, j'ai mal compris le sens de l' affirmation de

Veuillez noter que nous n'utilisons pas d'archives tar nues, mais des archives tar compressées avec une implémentation zip parallèle spéciale, sinon l'archivage de téraoctets de données prendrait des jours au lieu des "seulement" heures qu'il faut actuellement : https://gist.github. com/joerg/b88bf1de0ce824894ffc38f597cfef5f#tarpigz
@shibumi Je les ai informés de ce problème et de ma publication, donc c'est maintenant à eux de décider si et dans quelle mesure ils veulent être impliqués dans cela. Personnellement, j'espère qu'ils ouvriront cette pull request...

La compression est interdite pour le cryptage. Il permet à un attaquant de deviner si un référentiel crypté contient un certain fichier alors qu'une section (bloc) d'un fichier se compresse à la même taille indépendamment de la clé de cryptage utilisée. Il s'agit d' une vulnérabilité très connue des protocoles de chiffrement, et c'est pourquoi la compression a été supprimée de TLS 1.3.

Ne créons pas un problème connu où il n'y en a pas, n'est-ce pas ?

(Je pense que ce problème a déjà été mentionné, et probablement même pas une fois. Ce problème est toujours ouvert, où j'ai l'impression que pour cette seule raison, il devrait être fermé une fois pour toutes.)

Pourquoi spammer le problème ? :( Cela a été discuté tellement de fois que c'est presque hors sujet. Vous ne serez pas FORCÉ d'activer la compression !!

De plus, je pense que votre idée d'attaque nécessite que l'attaquant soit capable de contrôler les données à compresser et à crypter (je ne suis pas sûr cependant !). https://en.m.wikipedia.org/wiki/CRIME

Mais dans tous les cas, même s'il s'agit d'un problème de sécurité, quelqu'un peut vouloir utiliser la compression uniquement sur un stockage qui est sous son propre contrôle pour simplement économiser de l'espace de stockage.

Avoir même une fonctionnalité optionnelle qui affaiblit le cryptage invite un faux sentiment de sécurité. Restic prétend être un programme de sauvegarde _secure_. L'ajout d'une compression facultative annulera cette promesse car vous ne pouvez pas être en sécurité parfois, seulement à temps plein, tout le temps. Et il y aura des rapports CVE, c'est sûr. Qui veut pour son logiciel ce type de "popularité" ?

Mais je pense que l'ajout d'une compression d'une manière qui ne sera jamais utilisée avec le cryptage est une option viable.

FWIW en 2017, j'ai fait une démo où j'ai supprimé le cryptage de Restic et montré que la compression peut être très efficace . Cent fois efficace. La compression IIRC peut être ajoutée comme une sorte de wrapper, tout comme le cryptage, mais je n'ai pas regardé le code depuis longtemps, donc les choses peuvent être plus difficiles ou plus faciles ces jours-ci.

en fait, CRIME a besoin de connaître la longueur du texte chiffré, ce qui est fondamentalement impossible dans restic.
il n'y a pas non plus de programme de sauvegarde "sécurisé". si les fichiers de sauvegarde sont accessibles par des tiers, il y a toujours une chance que quelqu'un puisse falsifier ou pire, lire les données.
alors dire que la compression aggrave les choses, c'est tout simplement stupide.

en fait, CRIME a besoin de connaître la longueur du texte chiffré

Le CRIME a besoin mais vous n'en avez pas besoin. Imaginez que vous êtes un journaliste d'investigation et que votre source vous donne un ensemble de fichiers top secrets. Vous les sauvegardez avec un cryptage et personne ne saura que vous avez ces fichiers.

Maintenant, imaginez que vous n'étiez pas assez intelligent pour activer la compression, et maintenant tout le monde, qui possède également ces fichiers, à en juger par la taille des morceaux compressés puis cryptés, saura que vous avez ces fichiers top secrets dans cette archive sans même besoin de connaître la clé de cryptage. C'est très loin d'être sûr. Les gens peuvent aller en prison à cause de cette « caractéristique », être torturés ou pire.

il n'y a pas de programme de sauvegarde "sécurisé"

Cela nécessite alors une mise à jour.

Fast, secure, efficient backup program

Notez également sécurisé par défaut.

restic ne stocke que des morceaux emballés, de sorte que la taille des morceaux n'est pas évidente pour
quelqu'un n'ayant pas les clés.

Le vendredi 09 août 2019 à 02:09:23 -0700, Alexey Kopytko a écrit :

La compression est interdite pour le cryptage. Il permet à un attaquant de deviner si un référentiel crypté contient un certain fichier alors qu'une section (bloc) d'un fichier se compresse à la même taille indépendamment de la clé de cryptage utilisée. Il s'agit d' une vulnérabilité très connue des protocoles de chiffrement, c'est pourquoi la compression a été supprimée de TLS 1.3.

Ne créons pas un problème connu où il n'y en a pas, n'est-ce pas ?

--
Vous recevez ceci parce que vous avez été mentionné.
Répondez directement à cet e-mail ou consultez-le sur GitHub :
https://github.com/restic/restic/issues/21#issuecomment -519844526

--
(Escriu-me xifrat si saps PGP / Ecrire chiffré si vous connaissez PGP)
Clé PGP 7CBD1DA5 - https://emailselfdefense.fsf.org/

Pour ceux qui veulent en savoir plus sur ces problèmes de sécurité, il existe un bon article le décrivant http://www.iacr.org/cryptodb/archive/2002/FSE/3091/3091.pdf
À mon avis, il pourrait y avoir un défaut si le fichier est fragmenté, puis compressé et crypté. Mais si le fichier est compressé avant d'être fragmenté, c'est un fichier binaire comme un autre et ces attaques en clair deviennent inutiles.

Mais si le fichier est compressé avant d'être fragmenté, c'est un fichier binaire comme un autre et ces attaques en clair deviennent inutiles.

C'est exact. Mais cela n'aidera pas exactement à une déduplication efficace si je comprends bien, car un algorithme de compression peut utiliser un vocabulaire différent pour chaque version d'un fichier, ce qui donne un résultat binaire très différent. Ce qui évidemment ne dédupliquera pas. Autrement dit, cela n'a de sens que de compresser les morceaux résultants.

restic ne stocke que des morceaux emballés, de sorte que la taille des morceaux n'est pas évidente pour quelqu'un qui n'a pas les clés

C'est un soulagement.

Mon argument est toujours valable : il existe de nombreuses façons d'ajouter une faiblesse cachée dans un programme lorsqu'il implémente la compression avec le cryptage, il est donc préférable de ne pas en ajouter du tout. Même les _experts_ de chiffrement qui décident de TLS ont choisi de supprimer la compression. Je suppose qu'ils avaient un raisonnement similaire.

d'ailleurs.:

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

...
aussi CRIME ne fonctionne différentes des fichiers cryptés.
c'est-à-dire plusieurs exécutions de sauvegarde (vers différents référentiels, où l'attaquant les a toutes obtenues)
et cela ne fonctionne également que par une petite quantité de données.

Le CRIME a besoin mais vous n'en avez pas besoin. Imaginez que vous êtes un journaliste d'investigation et que votre source vous donne un ensemble de fichiers top secrets. Vous les sauvegardez avec un cryptage et personne ne saura que vous avez ces fichiers.

Maintenant, imaginez que vous n'étiez pas assez intelligent pour activer la compression, et maintenant tout le monde, qui possède également ces fichiers, à en juger par la taille des morceaux compressés puis cryptés, saura que vous avez ces fichiers top secrets dans cette archive sans même besoin de connaître la clé de cryptage. C'est très loin d'être sûr. Les gens peuvent aller en prison à cause de cette « caractéristique », être torturés ou pire.

C'est n'importe quoi. car cela ne fonctionne qu'avec une petite taille d'échantillon. il est également possible d'aller en prison sans compression. surtout à un moment donné, lorsqu'un attaquant a récupéré vos fichiers de sauvegarde, il pourrait être en mesure de les forcer brutalement à l'avenir.
il pourrait y avoir d'autres problèmes de sécurité qui apparaissent dans le futur, etc...
la discussion s'est simplement transformée en alarmiste insignifiante.

@sanmai , je ne reçois pas cet exemple avec

Imaginez que vous êtes un journaliste d'investigation ... Maintenant, imaginez que vous n'étiez pas assez intelligent pour activer la compression, et maintenant tous les autres, qui ont également ces fichiers, à en juger par la taille des morceaux compressés puis cryptés, sauront que vous avez ces fichiers top secrets dans cette archive sans même avoir besoin de connaître la clé de cryptage.

Ce que cela veut dire? Que quelqu'un peut deviner qu'un instantané crypté contient ces fichiers simplement en regardant la taille ? Cela suppose que les fichiers sont compressés seuls ou avec d'autres fichiers connus. Mais alors la même supposition peut être faite avec un shapshot non crypté.

En fait, que diriez-vous de gzipper les fichiers avant de les sauvegarder ? Cela ouvre-t-il également une faille de sécurité ?

Je pense que cet exemple n'a aucun sens : si vous prétendez que vous pouvez déterminer si un instantané contient des versions compressées de certains fichiers (arbitraires) que vous connaissez, vous pouvez également déterminer s'il contient ces fichiers non compressés.

Je ne pense pas que la compression puisse rendre le cryptage beaucoup moins sécurisé.

La plupart des attaques par canal latéral de compression impliquent plusieurs facteurs :
1) L'attaquant peut contrôler l'entrée
2) L'attaquant peut observer la taille de la sortie
3) De petites modifications des données d'entrée entraînent des modifications mesurables de la taille de sortie
4) L'attaquant peut modifier l'entrée et réessayer des centaines de milliers de fois

Contrairement aux systèmes basés sur le Web, dans la grande majorité des cas impliquant des sauvegardes statiques, (1) et (2) se tiendront rarement en même temps. De plus, pour la compression par blocs (3) n'est pas vraiment garantie, et pour la plupart des régimes de sauvegarde (4) ne tient certainement pas. Étant donné que la fréquence de sauvegarde est généralement d'une fois par jour environ, il faudrait des milliers d'années pour pouvoir manipuler les données et surveiller la taille de la sortie compressée pour remarquer des différences significatives, et cela en supposant qu'aucune autre donnée ne change, ce qui, dans la plupart des cas, serait.

Si vous faisiez des sauvegardes où la taille de sortie était visible, vous pourriez envisager de désactiver la compression. Sinon, il n'y a vraiment pas d'attaques pratiques contre lui et cela ne le rendrait pas moins sûr de l'avoir activé.

restic fait déjà de la déduplication, ce qui l'expose de toute façon aux mêmes attaques théoriques que les canaux secondaires de compression, et personne ne s'en est plaint à ma connaissance.

Le fait est qu'il y a des centaines ou des milliers d'utilisateurs qui bénéficieraient d'une fonction de compression sans aucun inconvénient. Pouvons-nous s'il vous plaît laisser ce problème vieux de 5 ans aux développeurs qui y travaillent ?

pour être honnête.... je préfère le concept de restic... mais j'ai fait des tests dans mon usecase (beaucoup de fichiers CSV et de dumps SQL) et j'ai dû passer à borg.

J'ai testé avec quatre générations de sauvegarde incrémentielle et mes fichiers obtiennent une compression de 7:1 et avec la déduplication, j'obtiens > 20:1. Je ne peux pas l'ignorer puisque j'ai déjà dit que je paie pour mon stockage de sauvegarde en ligne par Go.

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

Ce que cela veut dire? Que quelqu'un peut _deviner_ qu'un instantané crypté contient ces fichiers simplement en regardant la taille ? Cela suppose que les fichiers sont compressés seuls ou avec d'autres fichiers connus. Mais alors la même supposition peut être faite avec un shapshot non crypté.

Exactement. Découpez un fichier texte brut en morceaux égaux, compressez puis cryptez. Découpez à nouveau, compressez et cryptez. Comme les tailles des fichiers cryptés ne changent pas du point de vue AES, vous constaterez que dans les deux cas, vous disposez d'une plage de tailles qui se correspondent comme une empreinte digitale. Ils (et j'entends par eux principalement les administrations de régimes oppressifs comme l'Iran ou la Russie) peuvent raisonnablement supposer que ces fichiers sont présents ici, ce qui donne donc la raison, disons, de continuer à torturer le suspect. Je ne comprends pas pourquoi vous êtes tous si offensés par ces idées, ne sont-elles pas simples à comprendre ? Ce n'est pas un CRIME en soi, n'est-ce pas ?

Mais comme indiqué précédemment par @viric , techniquement, Restic n'est pas affecté par ces vulnérabilités car la taille des morceaux n'est pas vue sans clé de cryptage. Pourtant, si la compression est ajoutée à un moment donné, Restic peut toujours ne pas être affecté maintenant, mais peut le devenir plus tard.

L'ajout de la compression expose-t-il Restic à une vulnérabilité supplémentaire, étant donné qu'il effectue déjà la déduplication ?

Si votre problème est qu'un attaquant devine la taille des blocs compressés pour en déduire la taille non compressée, d'accord, mais la compression aggrave-t-elle la situation ? Un attaquant n'aurait-il pas les mêmes informations de base ?

Si un attaquant pouvait voir les tailles non compressées ET compressées de chaque fichier, l'identification pourrait devenir plus réaliste, mais cela ne serait pas possible dans restic.

En fin de compte, la déduplication vous expose déjà à toutes les attaques théoriques sur lesquelles la compression peut avoir un impact, et bien sûr, la compression peut être désactivée pour maintenir l'état actuel des choses si cela correspond mieux à votre situation.

Je ne comprends tout simplement pas pourquoi vous discutez de problèmes de sécurité hypothétiques concernant la possibilité de deviner la présence d'un fichier en voyant la taille d'un morceau crypté..,,

Vous utilisez ZIP ou GZ ? Ensuite ça devrait aller.

Vous pensez que les autorités iraniennes peuvent deviner mon contenu par tailles ? Alors n'utilisez pas la compression (!). Cela ne signifie tout simplement pas que la compression ne devrait pas être disponible.

Je pense que nous avons couvert tous les angles pertinents de l'ajout de compression à restic, merci beaucoup pour toutes vos contributions.

Je pense que nous devrions ajouter la compression et l'activer par défaut, mais autoriser les utilisateurs à désactiver la compression. Veuillez patienter jusqu'à ce que j'aie plus de temps pour y travailler.

Il me semble que cette discussion devient incontrôlable, alors je verrouille ce problème pour l'instant. Si vous souhaitez poursuivre cette discussion, rendez-vous sur le forum . Merci!

Cette page vous a été utile?
0 / 5 - 0 notes