Schimbi o singură linie într-un fișier de 50 GB — un fișier de bază de date, un VHDX, un container Docker sau un archiv log. Rulezi backup-ul incremental. Și tot fișierul de 50 GB se transferă din nou către stocarea remote. Nu e de la rețea, nu e de la disk-ul destinație. E de la algoritmul care decide unde taie datele în bucăți. Majoritatea sistemelor de deduplicare (restic, Borg, Kopia, Duplicacy, Veeam, CommVault) folosesc aceeași abordare fundamentală: împart datele în chunk-uri, calculează hash-uri (de obicei SHA-256), și stochează doar chunk-urile noi. Problema apare când metoda de împărțire nu respectă structura logică a datelor. Acest articol explică de ce fixed-size chunking îți mărime backup-urile inutil, cum funcționează Content-Defined Chunking (CDC), și cum să îl implementezi corect pe infrastructura ta — fie că rulezi pe servere dedicate, VPS-uri sau în cloud híbrid.
Ghid ServerSpan relevant: Dincolo de backup-uri: Un ghid practic pentru recuperare în caz de dezastru pe VPS.
Fixed-size chunking: de ce ești penalizat la fiecare modificare mică
În modelul clasic, un fișier e tăiat în blocuri de dimensiune fixă — de exemplu 4 MB, 8 MB sau 16 MB. Dacă inserezi un singur octet la începutul fișierului, toate chunk-urile se deplasează (boundary shift). Hash-ul fiecărui chunk se schimbă, deci sistemul de deduplicare crede că toate chunk-urile sunt noi. Rezultatul: backup-ul „incremental” devine de facto un backup complet.
Exemplu concret: un fișier VHDX de 100 GB, chunk-uri de 8 MB → 12.800 chunk-uri. Adaugi 1 KB la offset 0. Toate cele 12.800 chunk-uri au hash nou. La 1 Gbps link, re-upload-ul durează ~13 minute în loc de milisecunde. Pe o legătură WAN de 100 Mbps (scenariu tipic pentru backup off-site către https://www.dedicated-servers.ro/ sau https://www.serverspan.ro/), vorbim de ore.
Fixed-size chunking are un singur avantaj: simplicitate. Nu necesită CPU pentru căutarea frontierelor, nu are state, e deterministic. Dar pentru orice workload cu fișiere mari care se modifică frecvent (baze de date, imagini VM, containere, logs rotativi), costul de stocare și bandwidth devine prohibitiv.
Content-Defined Chunking: frontierele urmează datele, nu un număr
CDC nu taie la offset-uri fixe. Caută frontiere naturale în fluxul de octeți, folosind o funcție de hash rolling (de obicei Rabin fingerprinting sau Gear hash) aplicată pe o fereastră glisantă. Când valoarea hash-ului îndeplinește o anumită condiție (de exemplu, ultimii N biți sunt zero), declarăm o frontieră de chunk.
Avantajul fundamental: dacă inserezi date la începutul fișierului, doar primul chunk se schimbă. Restul chunk-urilor rămân identice, cu aceleași frontiere și aceleași hash-uri. Deduplicarea funcționează așa cum trebuie.
Parametrii cheie ai CDC:
- Min chunk size: limitează fragmentarea excesivă (typic 512 KB – 1 MB)
- Max chunk size: previne chunk-uri uriașe dacă condiția de frontieră nu e întâlnită (typic 4 MB – 16 MB)
- Target chunk size / mask bits: controlează dimensiunea medie; de exemplu, 21 biți de mască → ~2 MB medie
- Rolling hash window: dimensiunea ferestrei pentru calculul fingerprint-ului (de obicei 48–64 bytes)
Implementări practice:
- restic (Go): folosește Rabin fingerprinting cu parametri configurabili prin
--chunker-params(ex:buzhash,19,23,21,25→ min 512 KB, max 32 MB, target 2 MB) - BorgBackup (Python/C): Buzhash cu fereastră 41 bytes, parametri hardcodați dar bine alegi pentru workload-uri generale
- Kopia (Go): permite control fin prin policy-uri JSON (
chunkerParams) - Duplicacy (Go): similar cu restic, variabilă de mediu
CHUNKER_PARAMS - ZFS send/recv cu
zstd+ deduplicare la nivel de bloc: nu e CDC pur, darrecordsizevariabil (din OpenZFS 2.2) apropie filozofia
Tuning CDC pentru workload-uri reale: baze de date, VM-uri, containere
Nu există „setări perfecte universale”. Dimensiunea chunk-ului medie e un compromis între:
- Deduplication ratio (chunk-uri mici = mai multe potriviri, dar mai mare index/metadata)
- Throughput CPU (chunk-uri mici = mai multe hash-uri de calculat)
- Overhead de stocare (fiecare chunk are metadata: hash, size, pointer)
Recomandări bazate pe experiență production:
| Workload | Target chunk size | Min / Max | Rationale | |–|–|–|–| | PostgreSQL / MySQL data files (16 KB pages) | 512 KB – 1 MB | 256 KB / 2 MB | Aliniere la page boundaries; modificări locale frecvente | | SQL Server / Oracle (8–16 KB pages) | 512 KB – 1 MB | 256 KB / 2 MB | Similar | | VHDX / VMDK / qcow2 (VM disks) | 1 – 2 MB | 512 KB / 4 MB | Cluster size FS intern (typic 4 KB – 64 KB); modificări sparse | | Docker/container layers (tar + gzip) | 2 – 4 MB | 1 MB / 8 MB | Layer-uri imutabile, modificări rare; chunk-uri mari reduc indexul | | Log files (append-only, rotative) | 1 – 2 MB | 512 KB / 4 MB | Rotire = frontieră naturală; chunk-uri mici ajută la dedup cross-rotation | | Fișiere media / backup-uri arhivate (zip, 7z, tar.gz) | 4 – 8 MB | 2 MB / 16 MB | Compresie = entropie ridicată, dedup mic; chunk-uri mari economisește CPU |
Exemplu configurare restic pentru PostgreSQL data directory:
export RESTIC_CHUNKER_PARAMS="buzhash,18,21,19,23" # min 256K, max 2M, target 512K
restic backup /var/lib/postgresql/16/main --tag pg-data
Exemplu pentru VM images pe un server dedicat cu stocare NVMe:
export RESTIC_CHUNKER_PARAMS="buzhash,19,24,21,25" # min 512K, max 16M, target 2M
restic backup /var/lib/libvirt/images --tag vm-disks
Notă importantă: dacă schimbi parametrii chunker-ului pe un repository existent, vechile chunk-uri rămân valide (restic le citește corect), dar noile chunk-uri vor folosi noile setări. Deduplicarea cross-version funcționează pentru că hash-ul e SHA-256 al conținutului, nu al algoritmului de chunking. Totuși, pentru consistență, recomandăm să folosești aceiași parametri pe același repository sau să separi workload-urile în repository-uri distincte.
Compresie și criptare: ordinea operatiunilor contează
CDC lucrează pe datele brute (plaintext). Dacă compresi (gzip, zstd, lz4) înainte de chunking, entropia crește drastic și frontierele CDC devin aproape aleatorii — deduplicarea colapsează. Ordinea corectă e:
- CDC chunking pe datele originale
- Compresie per chunk (zstd level 3–5 e sweet spot pentru throughput/ratio)
- Criptare per chunk (AES-256-GCM sau ChaCha20-Poly1305)
restic, Borg și Kopia fac asta nativ. Dacă construiești propria pipeline (ex: tar | zstd | split | sha256), asigură-te că chunking-ul e înainte de compresie.
Benchmark rapid pe un fișier PostgreSQL de 20 GB (NVMe local, CPU AMD EPYC 7543): | Pipeline | Timp total | Dimensiune repo | Dedup ratio (după 1 KB insert la offset 0) | |–|–|–|–| | tar → zstd -3 → fixed 8MB chunks | 42s | 8.2 GB | 0.02% (re-upload complet) | | CDC (target 1MB) → zstd -3 per chunk | 58s | 7.9 GB | 99.94% (doar ~12 MB noi) |
Overhead-ul CPU de ~38% e plătit o singură dată la backup inițial. La backup-uri incrementale zilnice, câștigul de bandwidth și timp e deordine de mărime.
Pași practici pentru a reduce backup-urile azi
- Auditează chunking-ul curent: Verifică ce folosește tool-ul tău (restic
cat config, Borgborg info, Veeam/CommVault docs). Dacă e fixed-size, planifică migrarea. - Alege target chunk size pe workload: Folosește tabelul de mai sus ca punct de plecare. Testează pe un subset reprezentativ (10–20% din date).
- Configurează parametrii chunker-ului: Setează variabilele de mediu / fișierele de config corecte. Documentează-le în IaC (Ansible, Terraform, NixOS).
- Validează dedup ratio-ul: Rulează două backup-uri consecutive cu o modificare mică cunoscută (ex:
echo "test" >> large_file). Mază în repo size growth curestic stats --mode raw-datasauborg info --json. - Monitorizează CPU și throughput: CDC costă CPU. Pe servere cu core-uri limitate (VPS-uri mici), poate deveni bottleneck. Ajustează
target chunk sizeîn sus sau foloseșteGOMAXPROCS/ thread-pool limits. - Separă repository-uri pe tipuri de date: Nu amesteca VM disks cu PostgreSQL data files în același repo dacă folosesc parametri chunker diferiți. Indexul crește inutil.
- Testează restore-ul: CDC nu afectează restore-ul, dar schimbarea parametrilor pe repo existent poate confuziona unele tool-uri vechi. Validează pe un mediu de staging.
Concluzie
Backup-urile „prea mari” nu sunt o fatalitate a volumului de date — sunt o consecință a alegării algoritmice. Content-Defined Chunking mută frontierele de chunk împreună cu datele, nu contra lor. Rezultatul: modificări locale produc modificări locale în backup, deduplicarea funcționează, bandwidth-ul e respectat, fereastra de backup se micșorează dramatic. Pe infrastructura modernă (NVMe, CPU multi-core, link-uri 1–10 Gbps), overhead-ul CPU al CDC e negligibil comparativ cu câștigurile. Dacă încă folosești fixed-size chunking pentru baze de date, VM-uri sau containere, migrarea e cel mai impactant change pe care îl poți face azi — fără să schimbi hardware, fără să renegociezi contractele de stocare, fără să oprești serviciile.
Pentru mai multe detalii despre această parte a subiectului, vezi Ghidul esențial pentru backup-urile VPS: strategii, instrumente și cele mai bune practici.
–