Meilleure compression pour l'envoi / recv ZFS


15

J'envoie des instantanés ZFS incrémentiels sur une ligne T1 point à point et nous en sommes au point où une journée d'instantanés peut à peine passer par-dessus le fil avant le démarrage de la prochaine sauvegarde. Notre commande send / recv est:

zfs send -i tank/vm@2009-10-10 tank/vm@2009-10-12 | bzip2 -c | \
ssh offsite-backup "bzcat | zfs recv -F tank/vm"

J'ai beaucoup de cycles CPU à revendre. Existe-t-il un meilleur algorithme de compression ou une méthode alternative que je peux utiliser pour envoyer moins de données sur la ligne?


1
Avez-vous vérifié qu'il s'agit bien du lien le plus lent? C'est peut-être la lecture / écriture du disque.
kbyrd

Oui, j'obtiens 80-100 Mbps de connexion à la box via NFS. La connexion réseau est de 1,5 Mbps
Sysadminicus

3
Avez-vous essayé d'utiliser lzma --best?
Amok

1
Comme l'a souligné Amuck, LZMA est actuellement le meilleur algorithme général de compression de données largement disponible.
Chris S

Par exemple, des statistiques qui montrent que cela zfs receivepeut être un coupable:received 953MB stream in 36 seconds (26.5MB/sec)
poige

Réponses:


2

Il semble que vous ayez essayé tous les meilleurs mécanismes de compression et que la vitesse de la ligne soit toujours limitée. En supposant qu'il soit hors de question d'exécuter une ligne plus rapide, avez-vous envisagé de simplement exécuter les sauvegardes moins fréquemment afin qu'elles aient plus de temps pour s'exécuter?

En dehors de cela, existe-t-il un moyen de réduire la quantité de données en cours d'écriture? Sans savoir que votre application empile, il est difficile de dire comment, mais simplement faire des choses comme s'assurer que les applications écrasent les fichiers existants au lieu d'en créer de nouveaux pourrait aider. Et assurez-vous de ne pas enregistrer les sauvegardes des fichiers temporaires / cache dont vous n'aurez pas besoin.


9

Voici ce que j'ai appris en faisant exactement la même chose que vous. Je suggère d'utiliser mbuffer. Lors de tests dans mon environnement, cela n'a aidé que du côté de la réception, sans cela, l'envoi ralentirait pendant que la réception rattraperait.

Quelques exemples: http://everycity.co.uk/alasdair/2010/07/using-mbuffer-to-speed-up-slow-zfs-send-zfs-receive/

Page d'accueil avec options et syntaxe http://www.maier-komor.de/mbuffer.html

La commande d'envoi de mon script de réplication:

zfs send -i tank/pool@oldsnap tank/pool@newsnap | ssh -c arcfour remotehostip "mbuffer -s 128k -m 1G | zfs receive -F tank/pool"

cela exécute mbuffer sur l'hôte distant en tant que tampon de réception afin que l'envoi s'exécute le plus rapidement possible. J'ai exécuté une ligne de 20 Mbits et j'ai constaté que le fait d'avoir mbuffer du côté de l'envoi ne m'a pas aidé non plus, ma boîte zfs principale utilise également tout son ram comme cache, donc donner même 1g à mbuffer me obligerait à réduire certaines tailles de cache.

De plus, et ce n'est pas vraiment mon domaine d'expertise, je pense qu'il vaut mieux laisser ssh faire la compression. Dans votre exemple, je pense que vous utilisez bzip, puis utilisez ssh qui, par défaut, utilise la compression, donc SSH essaie de compresser un flux compressé. J'ai fini par utiliser arcfour comme chiffre car c'est le moins gourmand en CPU et c'était important pour moi. Vous pouvez avoir de meilleurs résultats avec un autre chiffrement, mais je suggérerais certainement de laisser SSH faire la compression (ou de désactiver la compression ssh si vous voulez vraiment utiliser quelque chose qu'il ne prend pas en charge).

Ce qui est vraiment intéressant, c'est que l'utilisation de mbuffer lors de l'envoi et de la réception sur localhost accélère également les choses:

zfs send tank/pool@snapshot | mbuffer -s 128k -m 4G -o - | zfs receive -F tank2/pool

J'ai trouvé que 4g pour les transferts localhost semble être le bonbon pour moi. Cela montre simplement que l'envoi / la réception zfs n'aime pas vraiment la latence ou toute autre pause dans le flux pour fonctionner au mieux.

Juste mon expérience, j'espère que cela vous aidera. Il m'a fallu un certain temps pour comprendre tout cela.


1
Merci beaucoup pour ce post. En regardant zfs envoyer de plus près, j'ai très rapidement eu le sentiment qu'il avait un mauvais comportement (aka "design") lors de l'envoi vers une cible liée à la latence. Après une douzaine de résultats, il est impossible de blâmer zfs pour rien. Je vous suis très reconnaissant d'avoir pris le temps de l'examiner et de publier vos résultats.
Florian Heigl

2

Ceci est une réponse à votre question spécifique:

Vous pouvez essayer rzip , mais cela fonctionne de manière un peu différente de compress / bzip / gzip:

rzip s'attend à pouvoir lire l'intégralité du fichier, il ne peut donc pas être exécuté dans un pipeline. Cela augmentera considérablement vos besoins de stockage local et vous ne pourrez pas exécuter de sauvegarde et envoyer la sauvegarde sur le fil dans un seul tuyau. Cela dit, les fichiers résultants, au moins selon ce test, sont un peu plus petits.

Si votre contrainte de ressources est votre canal, vous exécuterez des sauvegardes 24h / 24 et 7j / 7, vous devrez donc simplement copier des instantanés en permanence et espérer que vous continuerez de toute façon.

Votre nouvelle commande serait:

remotedir=/big/filesystem/on/remote/machine/
while 
  snaploc=/some/big/filesystem/
  now=$(date +%s)
  snap=snapshot.$now.zfssnap
  test -f $snaploc/$snap
do
  sleep 1
done

zfs send -i tank/vm@2009-10-10 tank/vm@2009-10-12 > $snaploc/$snap &&
rzip $snaploc/$snap &&
ssh offsite-backup "
        cat > $remotedir/$snap.rzip && 
        rzip -d $remotedir/$snap.rzip && 
        zfs recv -F tank/vm < $remotedir/$snap &&
        rm $remotedir/$snap " < $snaploc/$snap &&
rm $snaploc/$snap

Vous voudrez mettre une meilleure correction d'erreur, et vous voudrez envisager d'utiliser quelque chose comme rsync pour transférer les fichiers compressés, donc si le transfert échoue au milieu, vous pouvez reprendre là où vous vous étiez arrêté.


2

Les choses ont changé au fil des ans depuis la publication de cette question:

1: ZFS prend désormais en charge la réplication compressée, ajoutez simplement l'indicateur -c à la commande d'envoi zfs et les blocs compressés sur le disque resteront compressés lorsqu'ils passeront par le canal à l'autre extrémité. Il peut encore y avoir plus de compression à gagner, car la compression par défaut dans ZFS est lz4

2: Le meilleur compresseur à utiliser dans ce cas est zstd (ZStandard), il a maintenant un mode `` adaptatif '' qui changera le niveau de compression (entre les 19+ niveaux pris en charge, plus les nouveaux niveaux zstd-fast à plus grande vitesse) basé sur la vitesse du lien entre zfs send et zfs recv. Il compresse autant qu'il le peut tout en gardant la file d'attente de données en attente de sortir au minimum. Si votre lien est rapide, il ne perdra pas de temps à compresser davantage les données, et si votre lien est lent, il continuera à travailler pour compresser davantage les données et vous faire gagner du temps à la fin. Il prend également en charge la compression filetée, donc je peux profiter de plusieurs cœurs, ce que gzip et bzip ne font pas, en dehors des versions spéciales comme pigzip.


1

Je suppose que vous ne pouvez tout simplement pas augmenter la bande passante brute de votre site ...

Vous pouvez voir l'avantage de ne pas utiliser la compression sur l'hôte.

Si vous utilisez quelque chose comme un optimiseur WAN, il sera en mesure d'optimiser le transfert beaucoup mieux si vous ne compressez pas le fichier avant de l'envoyer, c'est-à-dire que vous faites exactement ce que vous faites mais supprimez le bzip2 du tuyau. Après quelques exécutions de votre sauvegarde, l'optimiseur Wan aura mis en cache une très grande partie de ce qu'il voit dans le transfert et vous verrez d'énormes améliorations dans les vitesses de transfert.

Si vous êtes sur un budget limité, vous pourrez peut- être voir une amélioration similaire en utilisant rsync et rsyncing l' instantané non compressé , à savoir:

zfs send -i tank/vm@2009-10-10 tank/vm@2009-10-12 > /path/to/snapshotdir/snapshotfile
rsync /path/to/snapshotdir/snapshotfile offsite-backup:/remote/path/to/snapshotfile
ssh offsite-backup 'zfs recv -F tank/vm < /remote/path/to/snapshotfile'

Ce serait plus rapide car rsync ne transfèrerait que les différences entre l'instantané d'hier et celui d'aujourd'hui. Selon le fonctionnement du processus d'instantané, il peut toujours y avoir beaucoup de redondance entre les deux, même s'il ne s'agit pas du tout du même fichier.

L'optimiseur Wan est de loin un moyen plus probable de résoudre ce problème (eh bien, le métro Ethernet est le moyen le plus probable de résoudre ce problème, mais nous laisserons cela de côté). Le rsync est juste un coup sauvage dans le noir qui mérite d'être testé (localement; rsync vous dira combien de temps il a économisé sur une copie directe) sur vos données locales avant d'écrire le gros chèque pour la fibre ou une installation sur le lit de la rivière.


1

Pour ce que ça vaut. Je ne ferais pas d'envoi direct | compresser | décompresser | recevoir, cela peut entraîner des problèmes au niveau de la réception si la ligne de transfert s'enclenche et que vos pools seront hors ligne pendant une longue période pendant la réception. Nous envoyons dans un fichier local, puis gzipons l'instantané et transférons en utilisant rsync (avec lit de rivière), puis nous recevons du fichier. Le lit du fleuve n'optimise pas le trafic MAIS s'il y a un problème avec le transfert et qu'il doit être redémarré le lit du fleuve accélère le renvoi.

Nous avons envisagé de ne pas compresser l'instantané incrémentiel, d'utiliser la compression Rsync et de n'utiliser aucune compression autre que le lit de la rivière. Il est difficile de dire lequel est le meilleur, mais lorsque nous transférons des archivelogs d'Oracle avec une compression rsync, le taux de transfert est à peu près le double de celui des fichiers standard et du lit de la rivière (avec RSync).

Si vous avez un lit de rivière, utilisez rsync et non ssh car le lit de rivière comprend rsync et essaiera de l'optimiser et ajoutera les données au cache (voir ci-dessus, redémarrage des transferts).


1

D'après mon expérience, elle zfs sendest assez explosive, bien qu'elle soit beaucoup plus rapide (en moyenne) que l'étape de compression suivante. Ma sauvegarde insère un tampon considérable après zfs sendet plus après gzip:

zfs send $SNAP | mbuffer $QUIET -m 100M | gzip | mbuffer -q -m 20M | gpg ... > file

Dans mon cas, le périphérique de sortie est connecté par USB (pas par le réseau), mais la mise en mémoire tampon est importante pour une raison similaire: le temps de sauvegarde global est plus rapide lorsque le lecteur USB est occupé à 100%. Vous ne pouvez pas envoyer moins d'octets dans l'ensemble (comme vous le demandez), mais vous pouvez toujours terminer plus tôt. La mise en mémoire tampon empêche l'étape de compression liée au processeur de devenir liée aux E / S.


1

J'utilise pbzip2 tout le temps (bzip2 parallèle) lors de l'envoi sur WAN. Puisqu'il est threadé, vous pouvez spécifier le nombre de threads à utiliser avec l'option -p. Installez d'abord pbzip2 sur les hôtes d'envoi et de réception, les instructions d'installation se trouvent à http://compression.ca/pbzip2/ .

zfs send -i tank/vm@2009-10-10 tank/vm@2009-10-12 | pbzip2 -c | \
ssh offsite-backup "pbzip2 -dc | zfs recv -F tank/vm"

La clé principale est de créer des instantanés à intervalles fréquents (~ 10 minutes) pour réduire la taille de votre instantané, puis envoyer chaque instantané. ssh ne reprendra pas à partir d'un flux d'instantanés rompu, donc si vous avez un énorme instantané à envoyer, dirigez le flux vers pbzip2 puis divisez-le en morceaux de taille gérable, puis rsync divisez les fichiers en hôte de réception, puis canalisez vers zfs recv les fichiers pbzip2 concaténés.

zfs send -i tank/vm@2009-10-10 tank/vm@2009-10-12 | pbzip2 -c | \
split -b 500M - /somedir/snap-inc-10-to-12.pbzip2--

cela produira des fichiers nommés en morceaux de 500 Mo:

/somedir/snap-inc-10-to-12.pbzip2--aa
/somedir/snap-inc-10-to-12.pbzip2--ab
/somedir/snap-inc-10-to-12.pbzip2--ac
...

rsync pour recevoir l'hôte plusieurs fois (vous pouvez rsync même avant que l'envoi zfs ne soit terminé ou dès que vous voyez un bloc complet de 500 Mo), appuyez sur ctrl + c à tout moment pour annuler:

while [[ true ]]; do rsync -avP /somedir/snap-inc-10-to-12.pbzip2--* offsite-backup:/somedir ; sleep 1; done;

zfs reçoit:

cat /somedir/snap-inc-10-to-12.pbzip2--* | pbzip2 -dc | zfs recv -Fv tank/vm

Utilisateur libre mentionné: pour ce que ça vaut. Je ne ferais pas d'envoi direct | compresser | décompresser | recevoir, cela peut entraîner des problèmes au niveau de la réception si la ligne de transfert s'enclenche et que vos pools seront hors ligne pendant une longue période pendant la réception. - J'ai déjà rencontré des problèmes avec les anciennes versions de zfs <28 dans l'hôte de réception si un envoi / recv en cours est interrompu par des baisses de réseau mais pas dans la mesure où les pools sont hors ligne. C'est intéressant. Renvoyez l'instantané uniquement si le "zfs recv" est sorti du côté réception. Tuez le "zfs recv" manuellement si nécessaire. zfs send / recv est désormais bien meilleur sous FreeBSD ou Linux.


0

Vous pouvez prendre un chiffrement plus rapide pour ssh, peut-être blowfish-cbc, essayez également les commutateurs -123456789

-1 (or --fast) to -9 (or -best)

1
Depuis la page de manuel unix: Les alias --fast et --best sont principalement destinés à la compatibilité GNU gzip. En particulier, --fast ne rend pas les choses beaucoup plus rapides. Et --best sélectionne simplement le comportement par défaut.
Sysadminicus

1
cela n'a donc aucun effet dans votre cas. Et le chiffre?
Istvan

J'ai eu de la chance avec la compression LZMA, mais il se peut que votre lien soit trop lent.
Amok

0

Vous devrez tester avec vos données. Envoyez-le simplement dans un fichier et compressez-le avec chaque méthode.

Pour nous, gzip a fait une énorme différence et nous avons tout exécuté à travers cela, mais il n'y avait même pas de différence de 1% entre gzip et bzip ou 7z.

Si vous êtes sur un T1 lent, vous devrez le stocker dans un fichier et le resynchroniser.

Pour ceux (pas vous) qui sont un peu plus limités par le CPU que par la bande passante, comme lstvan a dit qu'un chiffre différent comme arcfour128 accélère les choses. Nous l'utilisons en interne pour déplacer des objets.


0

Essayez d'activer la déduplication pour l'envoi zfs avec -D. Les économies dépendent bien sûr de la duplication de vos données.


Puisqu'il utilise -ice qui implique une sauvegarde "incrémentielle", il n'y a pas tant d'espoir que -Dcela donnerait quoi que ce soit.
poige

@poige dépend de l'apparence de leurs données. S'ils génèrent beaucoup de données contenant des blocs en double, c'est une grande victoire. Je ne vois pas comment -i rendrait plus ou moins probable qu'il y ait des blocs en double. Si vous créez normalement des données qui ont beaucoup de duplication, vous allez probablement créer beaucoup de duplication à l'intérieur chaque jour, donc -i n'aide pas ou ne fait pas de mal.
James Moore

Eh bien, si vous avez beaucoup de doublons, toute compression s'en chargera de toute façon.
poige

@poige Ils doivent mesurer leurs données réelles. Vous pouvez certainement avoir des ensembles de données qui se compressent mal et se dédoublent très bien. Par exemple, plusieurs copies du même fichier vidéo compressé se dédoublent vraiment bien, et la compression au niveau du système de fichiers est probablement pire qu'inutile.
James Moore

Ah, ce cas -
ouais

-1

Le "meilleur" algorithme de compression dépend du type de données dont vous disposez - si vous appuyez sur une compression de collection MP3, cela ralentira probablement le processus, tandis que les fichiers texte / journaux peuvent être considérablement compressés avec gzip -9.

Combien de données poussez-vous chaque jour?


-1

Avez-vous envisagé de régler votre pile TCP / IP pour que votre mémoire tampon TCP et les tailles de fenêtre soient un peu plus grandes? vous pouvez utiliser lendd outil sous Solaris pour cela ou l' sysctloutil sous Linux / BSD / Mac OSX. Sur Solaris, vous cherchez les /dev/tcp tcp_max_bufet les /dev/tcp tcp_cwnd_maxvaleurs, et sur Linux sysctl, vous êtes à la recherche net.ipv4.tcp_mem, net.ipv4.tcp_rmemet les net.ipv4.tcp.wmemvaleurs.

De plus, ces liens peuvent être d'une aide supplémentaire:

Réglage des performances TCP Solaris

Il y a un ensemble de liens au bas de cette page qui expliquera comment faire de même pour Linux / BSD / OSX.


1
1. Il s'agit d'une question de 5 ans que vous déterrez. 2. Il n'a pas dit que le lien était sous-utilisé et a posé des questions sur la compression, à laquelle vous ne faites pas référence. 3. La plupart des systèmes d'exploitation ajustent automatiquement la taille de la fenêtre ces jours-ci. L'information à laquelle vous créez un lien était vieille de 3 ans lorsque l'auteur l'a publiée.
Chris S
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.