Zstandard (zstd) est un algorithme de compression moderne développé par Facebook qui offre un excellent compromis entre vitesse et taux de compression. Cet article compare zstd à gzip/bzip2/xz et montre comment l'intégrer dans vos workflows de backup et d'archivage.
Plan
- Pourquoi Zstandard ?
- Installation et premiers pas
- Comparaison benchmarks : zstd vs gzip vs bzip2 vs xz
- Niveaux de compression et tuning
- Cas d'usage : backups, logs, archives
- Intégration dans les outils existants
- Dictionnaires de compression
- Conclusion
Pourquoi Zstandard ?
Limitations des algorithmes traditionnels
gzip (1992) :
- ✅ Rapide en décompression
- ❌ Compression lente
- ❌ Ratio moyen
- ❌ Pas de multithreading
bzip2 (1996) :
- ✅ Bon ratio de compression
- ❌ Très lent (compression ET décompression)
- ❌ Pas de multithreading
xz/lzma (2009) :
- ✅ Excellent ratio
- ❌ Très lent
- ❌ Gourmand en RAM
- ✅ Multithreading limité
Avantages de Zstandard (2016)
- ⚡ Compression rapide : 3-5x plus rapide que gzip
- ⚡ Décompression ultra-rapide : comparable à gzip, plus rapide que tout le reste
- 📦 Ratio excellent : entre gzip et xz
- 🔧 Niveaux ajustables : de 1 (ultra-rapide) à 22 (max compression)
- 🚀 Multithreading natif
- 💾 Faible utilisation mémoire
- 📚 Dictionnaires : compression encore meilleure pour petits fichiers similaires
Installation et premiers pas
Installation
# Debian/Ubuntu
apt install zstd
# RHEL/Rocky/Fedora
dnf install zstd
# Compilation from source (dernière version)
wget https://github.com/facebook/zstd/releases/download/v1.5.5/zstd-1.5.5.tar.gz
tar xzf zstd-1.5.5.tar.gz
cd zstd-1.5.5
make -j$(nproc)
make install
Commandes de base
# Compresser un fichier
zstd fichier.txt
# Crée fichier.txt.zst
# Décompresser
zstd -d fichier.txt.zst
# ou
unzstd fichier.txt.zst
# Compresser avec niveau spécifique (1-22, défaut 3)
zstd -3 fichier.txt # Défaut
zstd -10 fichier.txt # Meilleur ratio
zstd -1 fichier.txt # Ultra-rapide
# Compresser vers stdout (pipe)
zstd -c fichier.txt > fichier.txt.zst
# Décompresser vers stdout
zstd -dc fichier.txt.zst
# Supprimer l'original après compression
zstd --rm fichier.txt
# Compresser un dossier (tar + zstd)
tar -c dossier/ | zstd > dossier.tar.zst
# ou avec la syntaxe tar moderne
tar --zstd -cf dossier.tar.zst dossier/
# Décompresser
tar --zstd -xf dossier.tar.zst
# Multithreading (utiliser tous les CPU)
zstd -T0 fichier.txt
Comparaison benchmarks : zstd vs gzip vs bzip2 vs xz
Test sur fichier texte de 1 GB (logs)
# Générer fichier test
dd if=/dev/urandom bs=1M count=1024 | base64 > testfile.txt
# Benchmark compression
time gzip -9 -k testfile.txt # gzip niveau max
time bzip2 -9 -k testfile.txt # bzip2 niveau max
time xz -9 -k testfile.txt # xz niveau max
time zstd -10 -k testfile.txt # zstd niveau 10
time zstd -19 -k testfile.txt # zstd niveau max pratique
# Benchmark décompression
time gunzip -c testfile.txt.gz > /dev/null
time bunzip2 -c testfile.txt.bz2 > /dev/null
time unxz -c testfile.txt.xz > /dev/null
time unzstd -c testfile.txt.zst > /dev/null
Résultats typiques (fichier texte 1 GB)
| Algorithme | Temps compression | Temps décompression | Taille | Ratio |
| Non compressé | - | - | 1000 MB | 100% |
| gzip -9 | 145s | 12s | 315 MB | 31.5% |
| bzip2 -9 | 385s | 98s | 268 MB | 26.8% |
| xz -9 | 890s | 45s | 245 MB | 24.5% |
| zstd -3 (défaut) | 28s | 8s | 325 MB | 32.5% |
| zstd -10 | 52s | 8s | 285 MB | 28.5% |
| zstd -19 | 420s | 9s | 250 MB | 25.0% |
Conclusions :
- zstd -3 : 5x plus rapide que gzip, ratio équivalent
- zstd -10 : 3x plus rapide que gzip, meilleur ratio que gzip et bzip2
- zstd -19 : ratio proche de xz, mais 2x plus rapide en compression et 5x en décompression
Test sur base de données (dump PostgreSQL)
# Dump PostgreSQL
time pg_dump mydb | gzip -9 > dump.sql.gz # 45s, 2.1 GB
time pg_dump mydb | bzip2 -9 > dump.sql.bz2 # 98s, 1.8 GB
time pg_dump mydb | xz -9 > dump.sql.xz # 245s, 1.6 GB
time pg_dump mydb | zstd -10 > dump.sql.zst # 28s, 1.9 GB
# Restauration
time gunzip -c dump.sql.gz | psql mydb # 18s
time bunzip2 -c dump.sql.bz2 | psql mydb # 42s
time unxz -c dump.sql.xz | psql mydb # 25s
time unzstd -c dump.sql.zst | psql mydb # 12s
Gagnant : zstd -10
- 60% plus rapide que gzip en compression
- 30% plus rapide en décompression
- Meilleur ratio que gzip
Niveaux de compression et tuning
Niveaux disponibles
# Niveau 1 : ultra-rapide (backup incrémental)
zstd -1 fichier.txt
# Compression : ~500 MB/s
# Ratio : ~35%
# Niveau 3 : défaut (équilibre)
zstd -3 fichier.txt
# Compression : ~300 MB/s
# Ratio : ~32%
# Niveau 10 : bon compromis
zstd -10 fichier.txt
# Compression : ~100 MB/s
# Ratio : ~28%
# Niveau 19 : max pratique
zstd -19 fichier.txt
# Compression : ~15 MB/s
# Ratio : ~25%
# Niveau 22 : maximum (rarement utile)
zstd -22 fichier.txt
# Compression : ~5 MB/s
# Ratio : ~24.5%
Recommandations par cas d'usage
Backups quotidiens (vitesse prioritaire) :
zstd -3 -T0 backup.tar
# Multithreading + niveau défaut
Backups archivage long terme (taille prioritaire) :
zstd -19 -T0 archive.tar
# Niveau élevé mais raisonnable
Logs rotatifs (compromis) :
zstd -10 app.log
# Bon ratio, rapide
Streaming / temps réel (ultra-rapide) :
zstd -1 --rsyncable stream.data
# Niveau 1 + mode rsyncable pour delta sync
Cas d'usage : backups, logs, archives
Backups complets avec tar + zstd
#!/bin/bash
# backup-zstd.sh - Backup avec zstd
BACKUP_DIR="/var/backups"
SOURCE_DIRS="/etc /var/www /home"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/backup_$DATE.tar.zst"
# Backup avec zstd niveau 10, multithreading
tar -c $SOURCE_DIRS | zstd -10 -T0 > "$BACKUP_FILE"
# Vérifier intégrité
zstd -t "$BACKUP_FILE"
if [ $? -eq 0 ]; then
echo "✓ Backup OK : $BACKUP_FILE"
# Taille du backup
du -h "$BACKUP_FILE"
# Rotation : garder 7 jours
find "$BACKUP_DIR" -name "backup_*.tar.zst" -mtime +7 -delete
else
echo "✗ Erreur backup"
exit 1
fi
Rotation logs avec zstd
# /etc/logrotate.d/myapp
/var/log/myapp/*.log {
daily
rotate 30
missingok
notifempty
compress
compresscmd /usr/bin/zstd
compressoptions -10
compressext .zst
uncompresscmd /usr/bin/unzstd
delaycompress
sharedscripts
postrotate
systemctl reload myapp > /dev/null 2>&1 || true
endscript
}
Compression à la volée (pipes)
# MySQL dump compressé
mysqldump --all-databases | zstd -10 > mysql_dump.sql.zst
# PostgreSQL dump
pg_dumpall | zstd -10 > postgres_dump.sql.zst
# Transfert réseau avec compression
tar -c /data | zstd -3 | ssh user@server "cat > backup.tar.zst"
# Décompression à la volée
zstd -dc backup.tar.zst | tar -xC /restore/
Backup incrémental rsync + zstd
#!/bin/bash
# backup-incremental-zstd.sh
BACKUP_DIR="/backups"
SOURCE="/"
LAST_BACKUP=$(ls -t "$BACKUP_DIR"/backup_*.tar.zst | head -1)
DATE=$(date +%Y%m%d_%H%M%S)
if [ -f "$LAST_BACKUP" ]; then
# Backup incrémental
rsync -av --link-dest="$LAST_BACKUP" \
"$SOURCE" "$BACKUP_DIR/backup_$DATE/" | \
zstd -1 > "$BACKUP_DIR/backup_${DATE}_incremental.tar.zst"
else
# Premier backup complet
tar -c "$SOURCE" | zstd -10 -T0 > "$BACKUP_DIR/backup_$DATE.tar.zst"
fi
Intégration dans les outils existants
rsync avec zstd
# Option 1 : Compression rsync native (si rsync 3.2.0+)
rsync -avz --compress-choice=zstd source/ dest/
# Option 2 : Pipe manuel
tar -c source/ | zstd -3 | ssh user@server "zstd -d | tar -xC /dest/"
Git avec zstd
# Configurer zstd pour Git
git config --global core.compression 0
git config --global core.looseCompression 0
# Utiliser zstd pour pack objects
git config --global pack.compression 0
git repack -a -d --depth=250 --window=250
# Compresser repo existant
cd .git/objects/pack
for pack in *.pack; do
git unpack-objects < "$pack"
done
rm *.pack *.idx
git repack -a -d -f --depth=250 --window=250
Docker images avec zstd
# Sauvegarder image avec zstd
docker save myapp:latest | zstd -10 > myapp.tar.zst
# Restaurer
zstd -dc myapp.tar.zst | docker load
# Export conteneur
docker export container_id | zstd -10 > container.tar.zst
Proxmox backups (vzdump)
# /etc/vzdump.conf
compress: zstd
# Niveau de compression zstd (défaut: 3)
zstd: 10
Déduplication avec zstd
# Borg backup avec zstd
borg create --compression zstd,10 \
/path/to/repo::backup-{now} \
/data
# Restic avec zstd
restic -r /backup/repo backup /data \
--compression max
Dictionnaires de compression
Pour petits fichiers similaires (logs, configs, JSONs), les dictionnaires améliorent drastiquement le ratio.
Créer un dictionnaire
# Collecter échantillons (fichiers similaires)
ls /var/log/app/*.log | head -100 > training_files.txt
# Générer dictionnaire
zstd --train -o app.dict training_files.txt
# Taille dictionnaire (typiquement 100KB-1MB)
ls -lh app.dict
Utiliser le dictionnaire
# Compression avec dictionnaire
zstd -D app.dict fichier.log
# Décompression avec dictionnaire
zstd -D app.dict -d fichier.log.zst
# Batch avec dictionnaire
for file in /var/log/app/*.log; do
zstd -D app.dict "$file"
done
Gains typiques avec dictionnaire
Sans dictionnaire :
- 100 fichiers JSON de 5 KB chacun = 500 KB
- Compressés : 200 KB (ratio 40%)
Avec dictionnaire :
- 100 fichiers JSON de 5 KB chacun = 500 KB
- Compressés : 80 KB (ratio 16%)
Gain : 2.5x meilleur ratio
Monitoring et statistiques
Afficher statistiques compression
# Stats détaillées
zstd --verbose -10 fichier.txt
# Tester plusieurs niveaux
for level in {1..19}; do
echo -n "Level $level: "
time zstd -$level -c fichier.txt > /dev/null 2>&1
done
# Comparer tailles
ls -lh fichier.txt*
Script de benchmark complet
#!/bin/bash
# benchmark-compression.sh
FILE="$1"
ORIGINAL_SIZE=$(stat -f%z "$FILE" 2>/dev/null || stat -c%s "$FILE")
echo "Fichier : $FILE"
echo "Taille originale : $(numfmt --to=iec $ORIGINAL_SIZE)"
echo ""
echo "Algorithme | Temps comp | Temps décomp | Taille | Ratio"
echo "-----------|------------|--------------|--------|------"
# gzip
START=$(date +%s.%N)
gzip -9 -c "$FILE" > "$FILE.gz"
COMP_TIME=$(echo "$(date +%s.%N) - $START" | bc)
COMP_SIZE=$(stat -f%z "$FILE.gz" 2>/dev/null || stat -c%s "$FILE.gz")
START=$(date +%s.%N)
gunzip -c "$FILE.gz" > /dev/null
DECOMP_TIME=$(echo "$(date +%s.%N) - $START" | bc)
RATIO=$(echo "scale=1; $COMP_SIZE * 100 / $ORIGINAL_SIZE" | bc)
echo "gzip -9 | ${COMP_TIME}s | ${DECOMP_TIME}s | $(numfmt --to=iec $COMP_SIZE) | ${RATIO}%"
# zstd
START=$(date +%s.%N)
zstd -10 -c "$FILE" > "$FILE.zst"
COMP_TIME=$(echo "$(date +%s.%N) - $START" | bc)
COMP_SIZE=$(stat -f%z "$FILE.zst" 2>/dev/null || stat -c%s "$FILE.zst")
START=$(date +%s.%N)
zstd -dc "$FILE.zst" > /dev/null
DECOMP_TIME=$(echo "$(date +%s.%N) - $START" | bc)
RATIO=$(echo "scale=1; $COMP_SIZE * 100 / $ORIGINAL_SIZE" | bc)
echo "zstd -10 | ${COMP_TIME}s | ${DECOMP_TIME}s | $(numfmt --to=iec $COMP_SIZE) | ${RATIO}%"
# Cleanup
rm -f "$FILE.gz" "$FILE.zst"
Checklist migration vers zstd
✅ Audit actuel :
- Identifier les gros fichiers compressés avec gzip/bzip2
- Lister scripts utilisant gzip/tar.gz
- Vérifier version zstd (>= 1.4.0)
✅ Tests :
- Benchmarker sur fichiers réels
- Tester niveaux 3, 10, 19
- Valider intégrité (zstd -t)
- Tester décompression
✅ Migration :
- Backups : remplacer gzip par zstd -10
- Logs : configurer logrotate avec zstd
- Archives : recompresser avec zstd -19
- Scripts : remplacer .gz par .zst
✅ Monitoring :
- Mesurer gain espace disque
- Mesurer temps backup
- Vérifier CPU usage
- Documenter pour l'équipe
Conclusion
Zstandard (zstd) est l'algorithme de compression moderne qui devrait remplacer gzip dans la plupart des cas d'usage. Il offre 3-5x plus de vitesse avec un meilleur ratio de compression.
Quand utiliser zstd :
- ✅ Backups quotidiens (niveau 3-10)
- ✅ Rotation logs (niveau 10)
- ✅ Archives long terme (niveau 19)
- ✅ Transferts réseau (niveau 1-3)
- ✅ Docker images, dumps DB
Quand garder autre chose :
- gzip : compatibilité legacy obligatoire
- xz : ratio absolu prioritaire (firmware, ISO)
- bzip2 : jamais (obsolète)
Gains typiques :
- Vitesse compression : +300-500%
- Vitesse décompression : +30-50%
- Ratio : +10-20% meilleur que gzip
- Espace disque sauvegardé : 20-40% sur backups


