Virtualización

ZFS en Proxmox: deduplicación vs compresión, y cuándo activar cada una

Por Bruno CG · · 11 min de lectura
ZFS en Proxmox: deduplicación vs compresión, y cuándo activar cada una

Hay dos perillas en ZFS que la gente confunde constantemente: la compresión y la deduplicación. Ambas “ahorran espacio”, pero lo hacen de formas radicalmente distintas y con costes radicalmente distintos. La regla corta, que desarrollamos abajo, es: la compresión es casi siempre la respuesta correcta, y la dedup casi nunca lo fue —hasta ahora—. Decimos “hasta ahora” porque el Fast Dedup de OpenZFS, que Proxmox VE 9.2 trae con ZFS 2.4, cambia la conversación lo suficiente como para merecer un repaso honesto.

Por qué la dedup clásica era una trampa

La deduplicación de ZFS compara cada bloque que se escribe contra una tabla de hashes (la DDT, Deduplication Table) para no guardar dos veces el mismo contenido. Suena a magia: dos bloques idénticos, una sola copia en disco. El problema es lo que cuesta por debajo.

Cada entrada de la DDT ocupa unos 320 bytes, y para que la dedup no destroce el rendimiento esa tabla tiene que caber en RAM. Si no cabe, cada escritura y buena parte de las lecturas acaban yendo a disco a consultar la tabla, y el pool se arrastra. La cuenta de RAM, por tanto, depende del tamaño de bloque, no es un número fijo:

  • Con recordsize de 128 KB, 1 TB de datos son ~8 millones de bloques: ~2,5 GB de RAM para la DDT.
  • Con bloques de 16 KB, esa misma RAM se multiplica por ocho: ~20 GB/TB.
  • Con bloques de 4 KB —el peor caso patológico—, te vas a ~80 GB/TB.

Verás citar por ahí cifras de “50-80 GB de RAM por TB” como si fueran lo normal. No lo son: ése es el extremo de bloques de 4 KB. La regla de oro práctica para datos deduplicables de verdad está más bien en 1 a 5 GB de RAM por TB, según el recordsize, lo repetitivo que sea el dato y cuánto crezca la DDT. Pero el matiz que de verdad importa es otro: con la dedup clásica, esa tabla crecía sin límite, y cuando rebasaba la RAM, la degradación no era gradual sino catastrófica. Esa es la razón por la que durante años el consejo unánime —el nuestro incluido— fue: en Proxmox, deja la dedup apagada.

La compresión, en cambio, casi siempre gana

La compresión es la otra perilla, y aquí no hay casi debate. LZ4 es esencialmente gratis: consume una fracción de CPU imperceptible en hardware moderno, y sobre imágenes de disco de VM, ISOs y sistemas de ficheros de contenedor suele recortar entre un 20% y un 35% sin que lo notes. ZSTD (por ejemplo zstd a nivel medio) sube el ahorro a cambio de algo más de CPU, y es la elección cuando el espacio aprieta más que el cómputo.

Dos detalles que mucha gente pasa por alto:

  • Se aplica solo a lo que escribes después. Cambiar compression no recomprime los datos ya existentes; solo afecta a los bloques nuevos. Por eso conviene fijarla antes de la primera escritura.
  • La compresión va antes que la dedup en el pipeline de ZFS, así que ambas se acumulan sin penalizarse mutuamente.
# Compresión por defecto en el dataset, antes de empezar a escribir
zfs set compression=lz4 rpool/data
# Verificar que tomó efecto
zfs get compression rpool/data

Nuestro consejo de partida no ha cambiado: LZ4 activado en todos los datasets, y subir a ZSTD selectivamente donde el ahorro compense. Para la inmensa mayoría de despliegues Proxmox, esto solo ya cubre el “ahorrar espacio” sin tocar la dedup.

Qué cambia con Fast Dedup (OpenZFS 2.3 / 2.4)

Aquí está la novedad que reabre el debate. Proxmox VE 9.2 incluye ZFS 2.4, y desde OpenZFS 2.3 la deduplicación tiene una reimplementación —Fast Dedup— que ataca justo lo que la hacía peligrosa: el crecimiento sin freno y el coste de las escrituras. Lo hace con cuatro mecanismos:

  1. Cuota de la tabla de dedup (dedup_table_quota) — un límite duro al tamaño de la DDT. Cuando se alcanza, las escrituras nuevas simplemente dejan de deduplicar en lugar de tumbar el pool. Esto convierte el consumo de RAM en algo acotado y predecible, que es exactamente lo que faltaba.
  2. Log de dedup — agrupa las actualizaciones de la DDT y reduce las escrituras aleatorias contra ella.
  3. Prefetch — permite cargar la DDT en ARC bajo demanda (zpool prefetch -t ddt).
  4. Prune — permite podar entradas únicas y antiguas de la DDT para liberar espacio bajo la cuota.
# Habilitar la característica y fijar una cuota dura a la DDT
zpool set feature@fast_dedup=enabled tank
zpool set dedup_table_quota=64G tank

# Activar dedup solo en el dataset que de verdad lo aprovecha
zfs set dedup=on tank/plantillas

# Cargar la DDT en cache y podar entradas antiguas cuando haga falta
zpool prefetch -t ddt tank
zpool ddtprune -d 90 tank     # entradas más viejas de 90 días

En las pruebas publicadas, las escrituras de Fast Dedup son del orden de un 41% más rápidas que las de la dedup clásica. Importante: siguen siendo más lentas que no deduplicar. Fast Dedup no convierte la dedup en gratis; la convierte en gobernable. Esa es la diferencia que cuenta.

Cuándo sí activar dedup (y dónde no)

La dedup nunca fue universalmente mala: era universalmente cara para el caso equivocado. Con cuota y poda, vuelve a tener sentido de forma selectiva, a nivel de dataset, donde el ratio lo justifica:

  • Almacenes de plantillas y clones de VM y entornos VDI: muchísimos bloques idénticos entre clones de la misma imagen base. Aquí los ratios medidos superan con holgura 3:1 y la dedup paga su coste.
  • Bibliotecas de ISOs: cincuenta copias de la misma ISO de instalación colapsan a una. Lectura intensiva, escritura escasa: el escenario ideal.
  • Datasets de solo lectura (repositorios, documentación, plantillas): la dedup se amortiza porque casi no hay escrituras compitiendo por la DDT.

Y dónde no: en el dataset que aloja tus discos de VM y raíces de contenedor en producción (vmdata y similares), donde lo que mandan son escrituras aleatorias rápidas y baja latencia. Ahí la compresión sigue siendo la herramienta correcta y la dedup, aunque ahora acotada, sigue añadiendo latencia que no quieres.

# Patrón recomendado: compresión en todo, dedup solo donde el ratio lo justifica
zfs set compression=lz4   rpool/vmdata     # discos de VM: rápido, sin dedup
zfs set dedup=off         rpool/vmdata
zfs set dedup=on          rpool/plantillas # clones/plantillas: alto ratio

Tres ajustes de ZFS que sí mueven la aguja

Más allá de las dos perillas grandes, hay tres parámetros que tocamos en casi todo pool de producción:

  • recordsize: el valor por defecto de 128 KB va bien para muchas cargas, pero para datasets con E/S aleatoria de VMs suele rendir mejor un tamaño menor. Ajústalo al patrón real de la carga, no por superstición.
  • atime=off: actualizar la marca de último acceso en cada lectura genera escrituras inútiles en un almacén de VMs. Desactivarlo es de las optimizaciones más limpias que existen.
  • ARC bien dimensionado: en ZFS, la RAM que de verdad acelera tu pool es el ARC. Antes de gastar RAM en una DDT, asegúrate de que el ARC tiene lo que necesita.
zfs set atime=off rpool/vmdata

ZFS dedup vs deduplicación de PBS: no las dupliques

Un punto que evita trabajo de más: si haces backup con Proxmox Backup Server, PBS ya deduplica por su cuenta a nivel de chunks, con un mecanismo propio independiente del de bloques de ZFS. Activar dedup de ZFS sobre el datastore de PBS no suma; solo añade coste. La combinación que mejor resultado da, y la que recomendamos por defecto, es: compresión LZ4/ZSTD en ZFS + deduplicación de chunks de PBS, dejando la dedup de bloques de ZFS apagada en ese almacén.

Los compromisos que conviene aceptar

Ninguna configuración de almacenamiento es perfecta. Las concesiones honestas:

  • Dedup vs RAM: incluso con cuota, cada TB deduplicado consume RAM para la DDT que se la quitas al ARC. Si tu pool es modesto y la RAM total es ajustada, deja la dedup apagada: el ahorro de disco no compensa robarle cache a tus VMs.
  • Compresión vs CPU: LZ4 es tan barato que ni se nota; ZSTD a niveles altos puede morder CPU durante ventanas de backup o migración. Mídelo en tu hardware.
  • Cambiar ajustes con datos ya escritos: compresión, recordsize y dedup solo afectan a escrituras nuevas. Para aplicarlos a datos existentes hay que reescribirlos (por ejemplo, moviéndolos con zfs send | zfs receive), no basta con cambiar la propiedad.

En resumen

Empieza por compresión LZ4 en todos los datasets —es la victoria fácil y casi siempre suficiente—. Mantén la dedup apagada en tu pool de VMs. Y, ahora que Proxmox VE 9.2 trae Fast Dedup con cuota y poda, plantéate activar dedup de forma selectiva en datasets de alto ratio —plantillas, clones, VDI, ISOs— donde antes el riesgo no compensaba. La diferencia de esta generación de ZFS no es que la dedup sea gratis; es que por fin es predecible. Y lo predecible sí se puede operar.

Nosotros diseñamos y operamos el almacenamiento de los cloud privados sobre Proxmox con esta disciplina: compresión por defecto, dedup solo donde los números la justifican y la RAM puesta donde más rinde. Si prefieres delegar esa afinación, es justo parte de nuestro servicio gestionado.

Preguntas frecuentes

¿Debo activar la deduplicación de ZFS en Proxmox? Por defecto, no, en el pool de VMs: usa compresión LZ4. Con el Fast Dedup de ZFS 2.4 (Proxmox VE 9.2) puedes activarla de forma selectiva en datasets de alto ratio —plantillas, clones, VDI, ISOs— con una cuota de tabla que la mantiene acotada.

¿Cuánta RAM necesita la dedup de ZFS? Depende del tamaño de bloque: ~2,5 GB por TB con recordsize de 128 KB, mucho más con bloques pequeños. La regla práctica es 1-5 GB/TB. Las cifras de 50-80 GB/TB que se citan corresponden al peor caso de bloques de 4 KB.

¿Qué es Fast Dedup y qué aporta? Es la reimplementación de la dedup en OpenZFS 2.3/2.4. Añade cuota de tabla (dedup_table_quota), log, prefetch y poda (zpool ddtprune), lo que hace el consumo de RAM acotado y las escrituras ~41% más rápidas que la dedup clásica. No la hace gratis, la hace predecible.

¿LZ4 o ZSTD? LZ4 por defecto: rápido y casi sin coste. ZSTD cuando el espacio aprieta más que la CPU y aceptas algo más de uso de procesador.

¿Tiene sentido dedup de ZFS si ya uso Proxmox Backup Server? No sobre el datastore de PBS: PBS ya deduplica por chunks. Combina compresión de ZFS con la dedup de PBS y deja apagada la dedup de bloques de ZFS en ese almacén.


Fuentes: OpenZFS — documentación de afinado de cargas, Klara Systems — ZFS Fast Dedup para Proxmox VE 9.x y la documentación de almacenamiento ZFS de Proxmox VE.