Replicación ZFS sobre WAN: acelerar send en enlaces lentos

¿Te fue útil?

La replicación sobre WAN es donde ZFS deja de ser una característica de sistema de archivos elegante y se convierte en una prueba de personalidad operativa. En local, zfs send | zfs recv se siente como una cinta transportadora. Sobre un enlace de 50–200 ms con pérdida de paquetes y middleboxes “útiles”, se convierte en una máquina de pinball: el rendimiento colapsa, la CPU se dispara, SSH se atasca y tu RPO empieza a negociar con la realidad.

Esta es una guía de campo para hacer que los sends de ZFS sean rápidos en enlaces lentos sin convertir tu plataforma de almacenamiento en una feria de ciencias. Está escrita para quienes envían bytes por trabajo: SREs, ingenieros de almacenamiento y el desafortunado de guardia que heredó una “replicación simple” que solo funciona cuando nadie la mira.

1. El modelo mental de replicación WAN

El rendimiento de la replicación ZFS no es un único control. Es una canalización con restricciones en competencia: I/O de disco en el emisor, CPU para compresión/encriptado, memoria y buffering, comportamiento de congestión TCP a través de latencia, sobrecarga de SSH y comportamiento de escritura en el receptor. Si solo ajustas un componente, a menudo solo mueves el cuello de botella a otro sitio—y a veces haces que el nuevo cuello de botella sea más difícil de ver.

La forma más fácil de mantenerse cuerdo es tratar la replicación como un servicio de producción con SLOs:

  • RPO: cuánto dato puedes permitirte perder (dirige la frecuencia de snapshots y el tamaño del send).
  • RTO: qué tan rápido puedes restaurar (dirige la retención, las pruebas y si necesitas que las propiedades de zfs receive sean correctas).
  • Presupuesto: ancho de banda, margen de CPU y cuánto complejidad operativa puedes tolerar a las 3 AM.

Luego define la canalización en tu cabeza:

  1. Selección de snapshot: ¿qué cambió desde la última vez?
  2. Send: ZFS lee bloques y emite un stream.
  3. Transformación: compresión opcional, cifrado opcional (ya sea nativo de ZFS o SSH).
  4. Transporte: TCP a través de un camino de alta latencia.
  5. Receive: ZFS escribe bloques, actualiza metadatos y confirma TXGs.

En una LAN, el disco y la CPU dominan. En una WAN, la latencia y la pérdida de paquetes amplifican cada pequeña ineficiencia. Un enlace con 100 ms de RTT no es solo “un poco más lento que local”: cambia cómo TCP aumenta, con qué rapidez se vacían los buffers y lo castigadora que puede ser una sola retransmisión.

Primer chiste (obligatorio y merecido): la replicación WAN es como mudarse usando un scooter—técnicamente posible, pero cada correa faltante se convierte en una decisión de vida.

2. Datos interesantes y contexto histórico

Seis a diez puntos concretos de contexto que importan en la práctica:

  1. ZFS send/receive es anterior a muchos productos de backup “cloud-native”. El diseño original de OpenSolaris ZFS incorporó la replicación por snapshot como una operación de primera clase, no como un añadido.
  2. Los sends incrementales son basados en bloques, no en archivos. Por eso pueden ser espectacularmente eficientes—pero también por eso ciertas cargas (imágenes de VM con churn) pueden generar deltas sorprendentemente grandes.
  3. El throughput TCP está limitado por el bandwidth-delay product (BDP). Si tus buffers de socket son más pequeños que el BDP, estás dejando capacidad sobre la mesa incluso cuando todo lo demás es perfecto.
  4. Los valores por defecto de SSH son conservadores para sesiones interactivas. No están diseñados para transferencias masivas sostenidas de varias horas, especialmente a través de alta latencia.
  5. OpenZFS añadió soporte de resumable send para que una replicación interrumpida pueda continuar sin reiniciar desde el principio—una de las mejores características de “calidad de vida ops” en la pila.
  6. La compresión ha cambiado de moda varias veces. Con CPUs modernas, la compresión ligera (como LZ4) suele ser “lo suficientemente gratis” y puede ser la diferencia entre saturar un enlace o arrastrarse.
  7. Las decisiones de recordsize y volblocksize tienen eco en la replicación. Los bloques secuenciales grandes se replican eficientemente; los bloques pequeños y aleatorios pueden aumentar metadatos y overhead—especialmente visible sobre WAN.
  8. La replicación es sensible al comportamiento de escritura del receptor. Un pool receptor con un SLOG saturado, expectativas de ashift mal alineadas o cargas pesadas de sync puede estrangular toda la canalización.

3. Línea base: qué significa realmente “lento”

Antes de ajustar ZFS, averigua qué puede hacer realmente tu enlace. La gente rutinariamente afirma “tenemos un circuito de 1 Gbps” y luego replica a 30–80 Mbps y culpa a ZFS. La mitad de las veces el circuito es real; el throughput utilizable no lo es—porque QoS, overhead de VPN, pérdida de paquetes o una mala configuración de BDP silenciosamente te comen el almuerzo.

Lo que necesitas saber:

  • RTT: 20 ms es un planeta diferente a 120 ms.
  • Pérdida: 0.1% de pérdida puede hundir el throughput TCP en algunos caminos.
  • MTU/MSS: la fragmentación y el blackholing son asesinos silenciosos.
  • BDP: ancho de banda × RTT; compáralo con los tamaños de buffer de socket.

Sólo después de entender la red interpretas números de replicación. Si no, estás afinando un sistema de archivos para compensar un firewall que piensa que los paquetes grandes son una falta moral.

4. La canalización de replicación: donde la velocidad muere

4.1 Estrategia de snapshots: deltas más inteligentes y menos frecuentes

En enlaces WAN, la replicación es un juego de consistencia y tamaño de delta. Muchos snapshots pequeños reducen el tamaño máximo del delta y el riesgo de “un send enorme” que obstruya el canal—pero demasiados snapshots aumentan la rotación de metadatos y la sobrecarga de gestión.

Operativamente, el patrón ganador es:

  • Snapshots frecuentes para RPO corto (p. ej., 5–15 minutos) en datasets críticos.
  • Snapshots menos frecuentes para datasets voluminosos/de bajo valor.
  • Retención que mantenga al menos una línea base conocida por cada destino de replicación.

4.2 Emisor: patrón de lectura, CPU y flags de ZFS send

zfs send puede ser lo suficientemente rápido como para saturar NVMe localmente y aun así tener la forma incorrecta para WAN. Las grandes palancas:

  • Sends incrementales: -i o -I, más un nombrado de snapshots sensato.
  • Sends raw: -w mantiene los bloques cifrados/comprimidos tal como están (cuando el dataset tiene cifrado) y evita reprocesamiento; a menudo una gran ganancia para CPU.
  • Bloques grandes: la replicación se beneficia de lecturas secuenciales más grandes; si tu carga es inherentemente aleatoria, el buffering importa más.
  • Incluir propiedades: decidir entre -p o -R afecta la corrección, no solo la velocidad—errores aquí crean replicaciones “rápidas” que no restauran correctamente.

4.3 Transformación: opciones de compresión y cifrado

En enlaces lentos, la compresión suele comprar más de lo que cuesta—hasta que deja de hacerlo. La restricción es el margen de CPU en ambos extremos. LZ4 es la elección por defecto “probablemente segura”; la compresión pesada puede convertirse en cuello de botella de CPU, y doble-comprimir puede desperdiciar ciclos sin ganancia.

Cifrado: vas a cifrar sobre WAN. La única pregunta es dónde. Si ya usas cifrado nativo de ZFS, zfs send -w (raw) te permite evitar ciclos de descifrar/volver a cifrar. Si confías en SSH para cifrar, ajusta SSH para transferencias masivas y considera cifrados que sean rápidos en tu hardware.

4.4 Transporte: latencia, buffers y por qué tu throughput se aplana

TCP necesita datos en vuelo para mantener el canal lleno. En un enlace de 200 Mbps con 100 ms RTT, el BDP es aproximadamente 2.5 MB (200 megabits/sec ≈ 25 MB/sec; × 0.1 sec ≈ 2.5 MB). Si los buffers de socket del emisor/receptor son más pequeños que eso, físicamente no puedes alcanzar la tasa de línea.

Ahora añade pérdida. TCP interpreta la pérdida como congestión, reduce la ventana y vuelve a subir lentamente. A través de largos RTTs, la recuperación es lenta. Por eso un enlace que “se siente bien” para tráfico web puede ser miserable para replicación sostenida.

4.5 Receptor: escrituras, TXGs y el misterio de “mi receive es más lento que el send”

El rendimiento en el receptor suele ser el cuello de botella oculto. Culpables comunes:

  • Contención del pool: otras cargas que causan escrituras aleatorias y presión de sync.
  • Comportamiento de sync: datasets con sync=always o un dispositivo SLOG estresado pueden limitar los commits.
  • Recordsize pequeño: el receptor tiene que hacer más trabajo de metadatos por la misma cantidad de datos de usuario.
  • Expectativas de ashift incorrectas: no es una configuración de replicación, pero sí un factor de diseño del pool que afecta la amplificación de escrituras.

5. Tareas prácticas (comandos + interpretación)

Estas son tareas reales que puedes ejecutar en sistemas OpenZFS-on-Linux típicos. Ajusta nombres de datasets e interfaces. Cada tarea incluye qué observar, porque “ejecutar comando” no es operaciones.

Tarea 1: Confirmar inventario de datasets y snapshots

cr0x@sender:~$ zfs list -t filesystem,volume -o name,used,avail,refer,mountpoint
cr0x@sender:~$ zfs list -t snapshot -o name,creation,used -s creation | tail -n 20

Interpretación: Estás verificando lo que vas a replicar y si los snapshots existen en una cadena consistente. Si faltan snapshots o son irregulares, los sends incrementales fallarán o forzarán sends completos costosos.

Tarea 2: Estimar el tamaño del delta entre snapshots

cr0x@sender:~$ zfs list -t snapshot -o name,used,refer -s creation tank/app
cr0x@sender:~$ zfs send -nPv -i tank/app@snaphourly-001 tank/app@snaphourly-002
total estimated size is 38.2G
send from @snaphourly-001 to tank/app@snaphourly-002 estimated size is 38.2G

Interpretación: Si tu delta “horario” es de 38 GB, no tienes un problema de replicación—tienes una carga de trabajo o una desalineación en la cadencia de snapshots. Esta salida es tu control de realidad para el RPO.

Tarea 3: Medir throughput de send en local (elimina la WAN de la ecuación)

cr0x@sender:~$ zfs send -Pv tank/app@snaphourly-002 | pv > /dev/null
  12.5GiB 0:00:18 [ 702MiB/s] [         <=>  ]

Interpretación: Si el send local es rápido, el I/O del emisor y el propio ZFS send no son tu cuello de botella. Si esto es lento, arregla el pool emisor, la presión de ARC o la estructura de snapshots antes de culpar a la red.

Tarea 4: Medir throughput de receive en local

cr0x@receiver:~$ zfs create -o mountpoint=none tank/replica-test
cr0x@sender:~$ zfs send -Pv tank/app@snaphourly-002 | ssh receiver 'pv | sudo zfs recv -u tank/replica-test/app'

Interpretación: Esto prueba end-to-end pero aún no tu WAN. Si el receive es lento aquí, el pool receptor es el culpable (o la CPU para descompresión/cifrado).

Tarea 5: Confirmar RTT TCP, señales de pérdida y saneamiento de la ruta

cr0x@sender:~$ ping -c 20 receiver
cr0x@sender:~$ ip route get receiver
cr0x@sender:~$ ss -ti dst receiver | head -n 40

Interpretación: Ping da un RTT toscamente. ss -ti muestra el estado TCP incluyendo retransmisiones, ventana de congestión y pacing. Si ves retransmisiones aumentando durante la replicación, arregla el camino de red o MTU antes de ajustar ZFS.

Tarea 6: Comprobar MTU y detectar problemas comunes de PMTUD

cr0x@sender:~$ ip link show dev eth0
cr0x@sender:~$ tracepath receiver | head -n 20

Interpretación: Si estás en una VPN, tu MTU efectiva suele ser más pequeña de lo que crees. tracepath hintará cambios en PMTU. La rareza de Path MTU suele presentarse como “bloqueos aleatorios” o throughput inconsistente.

Tarea 7: Inspeccionar CPU emisor y receptor durante la replicación

cr0x@sender:~$ mpstat -P ALL 1 10
cr0x@sender:~$ pidstat -t 1 -p $(pgrep -n "zfs|ssh|mbuffer|pv" | tr '\n' ',')

Interpretación: Si un solo núcleo está pegado (a menudo SSH crypto o compresión), estás limitado por CPU. El ajuste WAN no ayudará si tu canalización no puede generar o consumir bytes lo bastante rápido.

Tarea 8: Usar mbuffer para suavizar jitter de WAN y mantener el canal lleno

cr0x@sender:~$ zfs send -Pv -i tank/app@snapA tank/app@snapB | mbuffer -q -m 1G -s 128k | ssh receiver 'mbuffer -q -m 1G -s 128k | sudo zfs recv -u tank/replica/app'

Interpretación: mbuffer desacopla el pacing emisor/receptor y absorbe jitter. Si esto mejora materialmente el throughput, tu cuello de botella probablemente sea variabilidad del transporte o stalls de escritura en el receptor, no el ZFS send en sí.

Tarea 9: Habilitar resumable sends y capturar el resume token

cr0x@sender:~$ zfs send -v -s -i tank/app@snapA tank/app@snapB | ssh receiver 'sudo zfs recv -s -u tank/replica/app'
cr0x@receiver:~$ zfs get -H -o value receive_resume_token tank/replica/app
1-ETcK...truncated...GQ

Interpretación: Si el enlace cae, puedes reanudar en lugar de reiniciar. Esto es obligatorio en WANs inestables. Un token no vacío significa que hay un receive resumible pendiente.

Tarea 10: Reanudar una replicación interrumpida

cr0x@receiver:~$ token=$(zfs get -H -o value receive_resume_token tank/replica/app)
cr0x@sender:~$ zfs send -v -t "$token" | ssh receiver 'sudo zfs recv -s -u tank/replica/app'

Interpretación: Si reanudar funciona y el throughput vuelve, has probado que la interrupción fue transporte o un transitorio en el lado remoto, no corrupción en la cadena de snapshots.

Tarea 11: Verificar integridad de replicación comparando snapshots

cr0x@receiver:~$ zfs list -t snapshot -o name,creation -s creation tank/replica/app | tail -n 5
cr0x@sender:~$ zfs list -t snapshot -o name,creation -s creation tank/app | tail -n 5

Interpretación: Los nombres y el orden de los snapshots deben coincidir con el conjunto de replicación que pretendes. Si no lo hacen, puede que no estés replicando silenciosamente lo que crees que sí.

Tarea 12: Confirmar qué propiedades se reciben y si deberían ser locales

cr0x@receiver:~$ zfs get -o name,property,value,source compression,encryption,keylocation,atime,recordsize tank/replica/app

Interpretación: Las propiedades pueden afectar el rendimiento y el comportamiento de restauración. Por ejemplo, forzar atime=on en un réplica para pruebas de DR puede crear ruido de escritura en segundo plano en el peor momento.

Tarea 13: Averiguar si el receptor está bloqueado por sync o presión de TXG

cr0x@receiver:~$ zpool iostat -v 1 10
cr0x@receiver:~$ cat /proc/spl/kstat/zfs/arcstats | head -n 5
cr0x@receiver:~$ cat /proc/spl/kstat/zfs/txgs | head -n 50

Interpretación: zpool iostat muestra si el pool está saturado y si un vdev en particular está atrasado. Las estadísticas de TXG pueden dar pistas sobre retrasos en commits. Si el pool es el cuello de botella, puedes optimizar la red para siempre y seguirás arrastrándote.

Tarea 14: Afinar SSH para transferencias masivas (con cuidado) y observar el impacto en CPU

cr0x@sender:~$ zfs send -Pv -i tank/app@snapA tank/app@snapB | \
ssh -T -o Compression=no -o IPQoS=throughput receiver 'pv | sudo zfs recv -u tank/replica/app'

Interpretación: Desactivar la compresión de SSH evita doble-comprimir datos ya comprimidos. IPQoS=throughput puede evitar que algunas redes traten el stream como tráfico interactivo. Siempre mide CPU y throughput antes y después; “afinar” puede ser una forma costosa de sentirse productivo.

Tarea 15: Validar que el lado receptor no esté montando e indexando accidentalmente

cr0x@receiver:~$ zfs get -o name,property,value mounted,mountpoint canmount tank/replica/app
cr0x@receiver:~$ zfs recv -u tank/replica/app < /dev/null

Interpretación: Para réplicas de DR, a menudo quieres canmount=off o mountpoint=none y zfs recv -u para evitar el montaje automático que activa escáneres, indexadores o agentes de monitorización “útiles” que crean escrituras durante la replicación.

6. Guía rápida de diagnóstico

Cuando la replicación está lenta, no empieces por cambiar flags al azar. Usa una guía corta que aísle el cuello de botella en minutos.

Paso 1: ¿Está limitado por la red o por el host?

  • Comprueba RTT y retransmisiones mientras una replicación se ejecuta.
  • Comprueba saturación de CPU en emisor y receptor.
  • Comprueba iostat del pool receptor por utilización sostenida y latencia.
cr0x@sender:~$ ss -ti dst receiver | sed -n '1,25p'
cr0x@sender:~$ mpstat -P ALL 1 5
cr0x@receiver:~$ zpool iostat -v 1 5

Decisión: Si aparecen retransmisiones y colapso de cwnd, trátalo primero como un problema de red. Si la CPU está al máximo, trátalo como un problema de CPU/crypto/compresión. Si el pool receptor está al 90–100% con alta espera, trátalo como un problema de almacenamiento.

Paso 2: ¿El tamaño del send es inesperadamente grande?

cr0x@sender:~$ zfs send -nPv -i tank/app@last tank/app@now

Decisión: Si el tamaño del delta es más grande de lo esperado, arregla la cadencia de snapshots, el churn de la carga o la elección de snapshot base incremental (-i vs -I). El tuning de WAN no puede reducir el delta.

Paso 3: ¿El buffering estabiliza el throughput?

cr0x@sender:~$ zfs send -Pv -i tank/app@last tank/app@now | mbuffer -m 1G -s 128k | \
ssh receiver 'mbuffer -m 1G -s 128k | sudo zfs recv -u tank/replica/app'

Decisión: Si el throughput se vuelve más suave y mayor, estabas viendo stalls de la canalización (commits del receptor, jitter de la red o pacing de SSH). Mantén mbuffer y luego investiga el comportamiento de escritura del receptor.

Paso 4: ¿Puedes reanudar de forma fiable?

cr0x@receiver:~$ zfs get -H -o value receive_resume_token tank/replica/app

Decisión: Si no puedes reanudar en enlaces inestables, estás a un fallo transitorio de un reenvío completo y un fin de semana desagradable. Arregla la resumibilidad antes de perseguir mejoras marginales de velocidad.

7. Tres mini-historias del mundo corporativo

Historia 1: El incidente causado por una suposición errónea

La configuración parecía razonable en una pizarra: replicar datasets de producción a un sitio DR cada noche sobre un circuito privado. El equipo supuso que “circuito privado” implicaba “throughput estable”, y “nocturno” implicaba “suficiente”. Nadie documentó un RPO; vivía como una vibra.

Entonces llegó un lanzamiento de producto. La carga cambió de escrituras constantes de base de datos a muchos blobs tipo objeto y churn de imágenes de VM. Los deltas incrementales aumentaron en silencio, porque ZFS hizo exactamente lo que se le dijo: capturar cambios y luego enviarlos más tarde. El job de replicación empezó a tardar más, alargando la ventana hasta la mañana. La gente lo notó pero encogió los hombros—después de todo, “seguía ejecutándose”.

Durante un evento de mantenimiento no relacionado, el sitio primario tuvo una caída que requirió promoción de DR. El dataset de DR estaba mucho más atrasado de lo que esperaban. Habían replicado “cada noche”, pero el send de esa noche no había terminado. Su RPO no era 24 horas; era “cuandoquiera que el send termine”, que no es un número que puedas poner en un registro de riesgos en serio.

La solución no fue un tuning ingenioso. Fue ingeniería aburrida: aumentar la frecuencia de snapshots para reducir deltas, añadir monitorización de “lag de replicación en snapshots/tiempo” y establecer una política de que la replicación debe completarse dentro de una ventana definida—o disparar paging. También empezaron a ejecutar zfs send -nPv como parte de las revisiones de cambios para grandes variaciones de carga.

Historia 2: La optimización que salió mal

Otra compañía tenía un enlace transcontinental lento y un mandato: “hacer la replicación más rápida”. Alguien decidió subir la compresión en todas partes—en los datasets, en la canalización de send y en SSH. Parecía estupendo en una prueba rápida: los primeros minutos mostraron mayor throughput y menos bytes en la wire.

Luego llegó la realidad. La CPU en el emisor aumentó, pero peor, la CPU en el receptor se volvió espasmódica. El throughput de replicación oscilaba: ráfagas de progreso seguidas de largos periodos planos. El equipo interpretó las planicies como “problemas de red” y pidió un circuito más grande. El equipo de red, previsiblemente, pidió pruebas.

La prueba apareció en mpstat y pidstat: unos pocos cores estaban pegados haciendo compresión y crypto, y la canalización de escritura del receptor no daba abasto. La doble compresión desperdiciaba ciclos porque muchos datos (blobs comprimidos de aplicaciones) no se comprimían más. La compresión de SSH, en particular, añadió latencia y coste de CPU sin ganancia.

La solución fue contraintuitiva: apagar la compresión de SSH, mantener la compresión ligera en datasets (LZ4) y usar buffering para suavizar stalls del receptor. El throughput mejoró, la CPU se enfrió y—lo mejor—el sistema se volvió predecible. La lección: si no puedes explicar dónde van los ciclos de CPU, no estás optimizando; estás jugando a la ruleta con hojas de cálculo más bonitas.

Historia 3: La práctica aburrida pero correcta que salvó el día

La tercera organización tenía una costumbre dolorosamente conservadora: insistían en que todos los jobs de replicación WAN fueran resumibles, registrados y probados mensualmente con una interrupción de enlace simulada. También mantenían un fragmento de runbook pequeño pegado en su canal de incidentes: “resume token primero, panic segundo”. No era glamoroso, y nadie recibió un ascenso por ello.

Un trimestre, un proveedor tuvo pérdida de paquetes intermitente durante días. No una caída total—suficiente para desbalancear flujos TCP de larga duración y ocasionalmente resetear sesiones. Los jobs de replicación empezaron a fallar a mitad de transmisión. Pero como los jobs usaban sends resumibles, se reanudaron automáticamente o con un solo comando de operador. Nadie se vio forzado a “reiniciar desde cero” transferencias que habrían saturado el enlace durante semanas.

Durante el mismo período, un equipo de seguridad impuso timeouts de firewall más estrictos que mataban sesiones SSH “inactivas”. La canalización de replicación se pausaba durante la presión de TXG del receptor, aparecía inactiva para el firewall y se cortaba. De nuevo: la replicación resumible convirtió esto de crisis a molestia.

Cuando la dirección preguntó por qué el DR se mantuvo sano durante la “inestabilidad de red”, la respuesta honesta no fue “afinamos TCP perfectamente”. Fue “asumimos que la WAN es poco fiable y diseñamos para eso”. En operaciones empresariales, esto es lo que parece competencia: es silencioso.

8. Errores comunes (síntomas + soluciones)

Error 1: Tratar el throughput como la única métrica

Síntoma: Celebras una replicación rápida y luego descubres que faltan snapshots, no se replicaron propiedades o las restauraciones fallan.

Solución: Define la corrección: qué datasets, qué snapshots, recursivo vs no, propiedades incluidas y si es replicación en crudo cifrada. Usa comparaciones zfs list -t snapshot y pruebas de restauración periódicas.

Error 2: Sends completos sobre WAN porque “los incrementales son difíciles”

Síntoma: La replicación nunca termina después del primer seed; el enlace queda saturado por días; el RPO deriva sin fin.

Solución: Usa convenciones de nombres de snapshot y sends incrementales. Si necesitas seedear, hazlo una vez (idealmente enviando discos o usando una ruta temporal de alto ancho de banda), luego ejecuta incrementales.

Error 3: Doble compresión (dataset + pipeline + SSH)

Síntoma: Picos de CPU, throughput oscilante y ajustes “más rápidos” que empeoran.

Solución: Elige un solo lugar para comprimir. A menudo: LZ4 en datasets, compresión SSH desactivada. Mide con herramientas de CPU.

Error 4: No usar buffering frente a una WAN con jitter

Síntoma: El throughput parece una sierra: ráfagas y luego stalls; sesiones SSH a veces caen durante fases tranquilas.

Solución: Añade buffering (mbuffer) en ambos extremos con asignación de memoria sensata. Esto suaviza stalls cortos del receptor y el jitter de la red.

Error 5: Ignorar la salud del pool receptor

Síntoma: El emisor parece rápido en local, pero el rendimiento end-to-end sobre WAN es pobre aun cuando el enlace está subutilizado.

Solución: Revisa zpool iostat -v, latencia y contención. La replicación es una carga intensiva en escrituras en el receptor; trátala como tal.

Error 6: No usar resumable send en enlaces poco fiables

Síntoma: Una transferencia de 6 horas muere a las 5:45 y reinicia desde el principio. La moral cae más rápido que el throughput.

Solución: Usa zfs send -s y zfs recv -s. Captura y monitoriza los resume tokens.

Error 7: Jobs de replicación solapados que se pelean entre sí

Síntoma: Múltiples datasets se replican “en paralelo”, pero el throughput total es peor y las apps sensibles a latencia se quejan.

Solución: Serializa streams grandes o usa concurrencia controlada. Tu enlace WAN y el pool receptor no se hacen más rápidos porque añadiste más pipes; solo añadiste contención.

Error 8: Asumir “la WAN está bien” porque las pruebas de velocidad van bien

Síntoma: Las pruebas de velocidad en navegador pasan, pero los flujos de replicación de larga duración se arrastran.

Solución: Observa el comportamiento TCP (ss -ti), retransmisiones y MTU/PMTUD. Los flujos largos revelan problemas de ruta que las pruebas cortas ocultan.

Segundo chiste (obligatorio): Si crees que la pérdida de paquetes en la WAN es “prácticamente cero”, tengo un puente para venderte—por VPN, con un MTU de 9000.

9. Listas de verificación / plan paso a paso

9.1 Plan paso a paso para una nueva configuración de replicación WAN

  1. Define la intención: objetivos RPO/RTO por clase de dataset (crítico, importante, best-effort).
  2. Normaliza el nombrado de snapshots: nombres predecibles, cadencia consistente y política de retención.
  3. Seedear la línea base: hacer un send completo una vez durante una ventana de mantenimiento o vía ruta alternativa; confirma el layout en el receptor.
  4. Hazlo resumible por defecto: zfs send -s y zfs recv -s.
  5. Añade buffering: despliega mbuffer con tamaño de memoria conservador (p. ej., 512MB–2GB) según RAM del host.
  6. Elige estrategia de compresión: normalmente LZ4 en datasets, sin compresión SSH. Si usas cifrado nativo, prefiere sends raw cuando corresponda.
  7. Limita si es necesario: evita aplastar el tráfico de negocio; el rate limiting a veces es una característica, no una concesión.
  8. Verifica la corrección: asegúrate de que las cadenas de snapshots, propiedades y datasets esperados lleguen. Mantén receives desmontados a menos que sean necesarios.
  9. Instrumenta el lag de replicación: mide “edad del snapshot replicado más reciente” y alerta cuando exceda umbrales.
  10. Prueba restauraciones: monta un clone de réplica o promueve un entorno de prueba periódicamente. La replicación de la que no has restaurado es teoría.

9.2 Lista operativa para “la replicación va lenta hoy”

  1. Comprueba contención del pool receptor: zpool iostat -v 1 5.
  2. Comprueba retransmisiones TCP/cwnd: ss -ti dst receiver.
  3. Comprueba pinning de CPU: mpstat y pidstat.
  4. Estima tamaño del delta: zfs send -nPv -i.
  5. Prueba buffering si no se usa: añade mbuffer.
  6. Comprueba el estado de resume token; reanuda en lugar de reiniciar.

10. FAQ

Q1: ¿Debería usar raw send (zfs send -w) sobre WAN?

Si usas cifrado nativo de ZFS y quieres replicar datasets cifrados sin descifrarlos, raw send suele ser lo correcto. También puede reducir la carga de CPU porque ZFS puede transmitir bloques almacenados cifrados/comprimidos. Operativamente, preserva los límites de cifrado, que es exactamente lo que quieres para copias fuera del sitio.

Q2: ¿Es mbuffer obligatorio?

No es obligatorio, pero es una de las herramientas con mayor ROI para replicación WAN porque suaviza ráfagas y stalls. Si tu throughput es espasmódico o tus sesiones SSH mueren durante fases “tranquilas”, el buffering es una solución práctica.

Q3: ¿Por qué la replicación se atasca siempre en el mismo punto?

A menudo es presión del pool en el receptor o un timeout de middlebox de red. Comprueba zpool iostat del receptor por un vdev que llegue al 100% de utilización o muestre esperas largas, y comprueba si tu firewall o NAT tiene timeouts de inactividad agresivos que matan sesiones de larga duración.

Q4: ¿Debería ejecutar múltiples sends en paralelo para usar mejor el enlace?

A veces, pero con cautela. Los streams paralelos pueden ayudar si un solo stream no puede llenar el canal debido a limitaciones por flujo, pero también aumentan la contención en discos y CPU y pueden empeorar la latencia cola. Prueba un stream bien afinado primero; si no puede saturar y los hosts están ociosos, entonces prueba paralelismo controlado.

Q5: ¿Cuál es la mejor frecuencia de snapshots para replicación WAN?

La que mantenga tus deltas incrementales cómodamente dentro de tu ventana de replicación con margen para reintentos. Si tu enlace puede mover X GB/hora y tu carga cambia Y GB/hora, la cadencia de snapshots debe mantener cada delta por debajo de lo que puedes enviar más overhead.

Q6: ¿Debería replicar recursivamente con -R?

-R es correcto cuando necesitas una jerarquía completa (hijos, snapshots, propiedades) replicada de forma consistente. También es la forma en que la gente accidentalmente replica más de lo que pretendía. Úsalo cuando lo quieras y verifica el árbol de datasets en el receptor.

Q7: ¿Cómo sé si estoy limitado por CPU por el cifrado SSH?

Ejecuta una replicación y observa mpstat/pidstat. Si uno o varios núcleos están pegados en el proceso ssh y tu enlace está subutilizado, la crypto de SSH es sospechosa principal. Considera raw sends con cifrado nativo (si aplica) o ajusta opciones de SSH y la capacidad de CPU del host.

Q8: ¿Es seguro poner sync=disabled en el receptor para acelerar zfs recv?

Es rápido, y es un riesgo. Para una réplica DR donde puedes tolerar perder los últimos segundos de datos recibidos en vuelo durante un crash, los equipos a veces lo eligen conscientemente. Pero no lo hagas a la ligera: estás cambiando la semántica de durabilidad en el receptor. Si lo haces, documéntalo, delimítalo y prueba el comportamiento ante fallos.

Q9: ¿Por qué la estimación de zfs send -nPv no coincide con lo que realmente envío?

Es una estimación y puede variar según compartición de bloques, metadatos y características del stream. Sigue siendo útil para detectar tendencias y decidir “¿es este delta una locura?”, no para contabilidad de facturación.

Q10: ¿Cuál es la mejor forma de evitar reenvíos catastróficos?

Replicación resumible más monitorización de resume tokens y lag. Los enlaces WAN fallarán; tu plan debe asumirlo y mantener el progreso.

Conclusión

La replicación ZFS rápida sobre una WAN lenta no se reduce a una bandera mágica. Se trata de volver la canalización aburrida: cadencia de snapshots predecible, streams incrementales, buffering para el jitter, elecciones correctas de cifrado/compresión y un receptor que realmente pueda escribir lo que estás enviando. Las mejores configuraciones no solo van rápido en días buenos—siguen moviéndose en días malos, se reanudan tras interrupciones y te alertan temprano cuando la realidad se aleja de tu RPO.

Si solo tomas una lección operativa: mide cada etapa, aísla el cuello de botella rápidamente y optimiza la restricción que realmente tienes—no la que te resulta más familiar.

← Anterior
PostgreSQL vs YugabyteDB: Postgres distribuido — ¿impresionante o excesivo?
Siguiente →
Escenarios de desastre de ZFS: qué falla primero y qué puedes recuperar

Deja un comentario