El almacenamiento de medios es donde los buenos sistemas de ficheros van a morir en silencio. Montas un pool decente, copias unos terabytes de vídeo, añades un segundo cliente y de repente “ayer funcionaba” se convierte en la frase más repetida en tu casa u oficina.
ZFS puede hacer que las cargas de trabajo multimedia sean aburridas—en el mejor sentido—si dejas de tratarlo como un sistema de ficheros genérico y empiezas a ajustarlo para lo que realmente son los medios: lecturas secuenciales grandes, escrituras secuenciales grandes y metadatos que explotan conforme la biblioteca crece.
Qué necesitan realmente las cargas de trabajo multimedia (y qué no)
Aclaremos algo: la mayoría de los “servidores multimedia” no están limitados por IOPS. Por lo general están limitados por el throughput o sufren picos de latencia por metadatos y lecturas aleatorias pequeñas. Un archivo de película típico es grande y se lee mayormente de forma secuencial. Incluso múltiples streams concurrentes suelen ser lecturas secuenciales desde offsets distintos.
Lo que rompe las cosas es lo que rodea a los medios:
- Escaneos de biblioteca: muchas lecturas pequeñas y búsquedas de metadatos; un escaneo de Plex/Jellyfin/Emby puede parecer una carga de archivos pequeños disfrazada de carga multimedia.
- Miniaturas, vistas previas, subtítulos: archivos pequeños que causan E/S aleatoria y churn de metadatos.
- Descargas/transcodificaciones: escrituras secuenciales más tareas intensivas en CPU, a veces en los mismos datasets que los medios finalizados (no lo hagas).
- COPIAS DE SEGURIDAD y replicación: lecturas secuenciales sostenidas que compiten con el streaming.
Entonces la jugada es: optimiza la ruta de archivos grandes sin sabotear la ruta de metadatos y archivos pequeños. ZFS te da perillas para hacer exactamente eso, por dataset. Úsalas.
Línea de base opinada: si guardas archivos multimedia grandes y mayormente de solo lectura, deberías pensar en recordsize, compression, sync, atime y special vdev / localización de metadatos antes de perder tiempo discutiendo RAIDZ vs mirrors en Reddit.
Primera broma corta (1/2): Afinar almacenamiento es como hacer dieta: las ganancias más rápidas vienen de dejar los hábitos obviamente malos, no de comprar una báscula más bonita.
Registros grandes: cómo se comporta realmente recordsize
Recordsize no es “tamaño de bloque” y no es una promesa
ZFS almacena datos de archivos en bloques de tamaño variable hasta un máximo. Para sistemas de ficheros (datasets de tipo filesystem), ese máximo es recordsize. El valor por defecto suele ser 128K. Para medios, eso suele ser conservador.
Comportamiento clave: ZFS usará bloques más pequeños cuando tenga que hacerlo. Si configuras recordsize=1M, no forzarás que cada E/S sea de 1M. Los archivos pequeños y los bloques finales siguen siendo más pequeños. Las reescrituras aleatorias también pueden producir bloques menores debido al comportamiento copy-on-write.
Por qué los registros grandes ayudan a los medios
La reproducción multimedia adora las lecturas secuenciales largas. Los registros más grandes pueden significar:
- Menos operaciones de E/S para el mismo throughput (menos overhead por E/S).
- Mejores oportunidades de compresión (más datos por decisión de compresión).
- Menos bloques indirectos para archivos grandes (menos metadatos que perseguir).
Pero los registros más grandes no son gratis:
- Mayor amplificación de lectura para lecturas aleatorias pequeñas (leer un registro de 1M para obtener 4K puede ser absurdo).
- Posibles reescrituras más costosas si tu carga edita en sitio (raro para archivos multimedia finalizados, común para imágenes VM—problema distinto).
- Más presión de RAM en algunos patrones de caché (ARC mantiene buffers más grandes; no siempre es problema, pero no lo ignores).
Qué configurar para medios
Para archivos multimedia finalizados (películas, episodios, archivos de música), establece recordsize=1M en el dataset que los almacena. Si tu OpenZFS lo soporta y tu carga es extremadamente secuencial, recordsize=2M puede funcionar, pero 1M es el punto dulce en la práctica: gran ganancia, raras rarezas.
No configures un recordsize global para todo. Tu directorio de descargas, miniaturas y metadatos de aplicaciones no deben ser arrastrados al mundo de “registros grandes”. Mantenlos en datasets separados con recordsize apropiado (a menudo 128K por defecto o incluso más pequeño para cargas altamente orientadas a metadatos).
¿Y qué pasa con volblocksize?
Si exportas LUNs iSCSI o almacenamiento respaldado por zvol, este artículo te cubre solo parcialmente. volblocksize se fija al crear el zvol y se comporta de forma distinta. El almacenamiento multimedia suele ser basado en ficheros (SMB/NFS), así que céntrate en recordsize.
Gran compresión: cuándo gana, cuándo engaña
La compresión no es solo ahorrar espacio
En CPUs modernas, la compresión a menudo aumenta el throughput porque intercambia ciclos de CPU por menos lecturas/escrituras de disco. Para medios eso suena inútil porque “el vídeo ya está comprimido”. Cierto, pero incompleto.
Incluso en bibliotecas de medios encontrarás:
- Archivos de texto asociados (subtítulos, metadatos NFO): compresibles.
- Imágenes: a veces ya comprimidas, a veces no (PNG puede comprimir un poco más; imágenes RAW comprimen mucho).
- Artefactos de descargas (logs, temporales): altamente compresibles.
- Formatos de audio: FLAC está comprimido, WAV no.
Así que la compresión “gana” por defecto más a menudo de lo que se espera. Y cuando no ahorra mucho espacio, aún puede reducir E/S para los archivos auxiliares y metadatos.
Elige el algoritmo como un adulto
Mis elecciones habituales para datasets multimedia:
compression=lz4para compresión siempre activa, de bajo riesgo y baja latencia.compression=zstdpara datasets con muchos metadatos, documentos o contenido mixto. Empieza alrededor dezstd-3azstd-6. Niveles altos pueden estar bien, pero prueba la capacidad de CPU.
Para archivos de vídeo finalizados, la compresión no reducirá dramáticamente la película. Pero normalmente tampoco perjudica. El único “no hagas esto” real es elegir un nivel de compresión alto en una máquina ya ocupada transcodificando.
Segunda broma corta (2/2): Si activas compresión al máximo en un servidor que ya transcodifica 4K, básicamente has inventado un calentador eléctrico con sentimientos.
Qué puede romper la compresión
La compresión rara vez rompe la corrección; ZFS es sólido aquí. Lo que rompe es tu presupuesto de latencia si conviertes una máquina con poco uso de CPU en una máquina que funde CPUs. Los síntomas parecen “disco lento” porque todo se encola detrás de la CPU.
Además: las ratios de compresión pueden engañar. Un dataset puede mostrar una relación “meh” mientras aún ahorra mucha E/S en las partes no vídeo que causan picos de latencia.
Diseño de datasets para medios: mantenlo aburrido y rápido
Separa datasets por comportamiento de E/S
No pongas todo bajo un dataset llamado tank/media y lo des por hecho. Quieres propiedades distintas para comportamientos distintos. Un diseño práctico:
tank/media— archivos multimedia finalizados (lecturas secuenciales grandes).recordsize=1M,compression=lz4(o zstd moderado),atime=off.tank/downloads— escrituras activas, archivos parciales, desempaquetado. Dejarecordsizepor defecto o 128K; la compresión ayuda mucho aquí.tank/app— estado de aplicaciones (metadatos de Plex/Jellyfin). A menudo se beneficia del recordsize por defecto; considera special vdev si lo tienes.tank/backups— destinos de replicación; ajústalos independientemente para coincidir con patrones de send/receive.
atime: simplemente apágalo para medios
atime actualiza las fechas de último acceso. En medios, eso solo son escrituras adicionales de metadatos sin beneficio. Pon atime=off en datasets multimedia y en cualquier dataset de solo lectura frecuente. La única vez que quieres atime=on es si una aplicación lo usa para lógica (poco común hoy en día).
sync, dispositivos log y la realidad multimedia
La mayoría de la ingestión de medios es asíncrona por naturaleza: descargas, copias de archivos, rips. Si sirves medios por SMB/NFS, el comportamiento del cliente y la configuración del protocolo dictan cuánto tráfico de escritura sincrónica obtienes.
Guía:
- No pongas
sync=disableda la ligera. Hace que los benchmarks luzcan bien y que los informes de incidentes luzcan peor. - Si tienes un SLOG SSD y tu carga realmente emite escrituras sync (bases de datos, stores de VM o NFS estricto),
sync=standardmás un buen SLOG puede ayudar. Para datasets de solo lectura mayormente, suele ser irrelevante.
Special vdev: la mejora subestimada para medios
Los archivos multimedia grandes son secuenciales, pero los metadatos de una gran biblioteca no lo son. Un special vdev (SSDs rápidos dedicados a metadatos y bloques pequeños) puede hacer que la navegación y los escaneos sean ágiles sin mover terabytes a flash.
Reglas de compromiso:
- Trata el special vdev como crítico. Si falla y no lo espejaste, tu pool puede quedar inservible.
- Configura
special_small_blockscon criterio si quieres que datos de archivos pequeños vayan al special, no solo metadatos.
Ashifts, tamaños de sector y por qué tu pool dura para siempre
ashift se establece al crear el vdev y es doloroso de cambiar. Si usas discos con sector 4K (la mayoría), usa ashift=12 (o más alto si realmente tienes 8K). Configurarlo mal no siempre se ve como “lento”. A menudo se siente “más lento de lo que debería” más amplificación de escritura adicional.
Este es uno de esos ajustes de “paga ahora o paga para siempre”.
Una cita de fiabilidad (idea parafraseada)
Idea parafraseada (Werner Vogels): Todo falla, todo el tiempo—diseña sistemas que esperen fallos y sigan funcionando.
Hechos interesantes y contexto histórico (porque importa)
- ZFS nació en Sun Microsystems como un sistema de ficheros de “pool de almacenamiento”, fusionando gestión de volúmenes y semántica de sistema de ficheros en un único modelo administrativo.
- Copy-on-write no fue un truco; permitió snapshots consistentes sin congelar el sistema de ficheros, por eso los flujos de replicación son tan limpios.
- Checksums end-to-end son fundamentales: ZFS verifica la integridad de los datos desde el disco hasta la ruta de lectura de la aplicación, no solo “el RAID dice que está bien”.
- El ARC no es “solo caché”; es una caché adaptativa residente en memoria que puede almacenar datos y metadatos y que influye fuertemente en el rendimiento percibido.
- LZ4 se volvió el valor por defecto en muchas distribuciones porque es lo bastante rápido como para ser esencialmente “gratis” en CPUs modernas para cargas generales.
- Los valores por defecto de recordsize eran conservadores porque los sistemas de ficheros de propósito general deben comportarse razonablemente para cargas mixtas, no porque 128K sea mágicamente correcto para vídeo.
- RAIDZ existe en parte para reducir la penalización de escritura de paridad comparado con RAID5 clásico en ciertos patrones, pero aún tiene compensaciones para E/S aleatoria.
- La característica de special vdev es relativamente nueva comparada con ZFS clásico; cambió la economía de acelerar cargas de trabajo ricas en metadatos.
Tareas prácticas: comandos, salidas y decisiones (12+)
Cada tarea abajo incluye: un comando, una salida realista, qué significa y qué decisión tomas a partir de ello. Supuestos: Linux con herramientas OpenZFS instaladas, pool llamado tank y datasets como se describieron antes.
Task 1: Confirmar salud del pool y señales obvias
cr0x@server:~$ zpool status -v tank
pool: tank
state: ONLINE
status: Some supported features are not enabled on the pool.
action: Upgrade the pool to enable all features.
scan: scrub repaired 0B in 06:12:31 with 0 errors on Sun Dec 15 03:10:12 2025
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
raidz2-0 ONLINE 0 0 0
ata-WDC_WD140EDFZ-... ONLINE 0 0 0
ata-WDC_WD140EDFZ-... ONLINE 0 0 0
ata-WDC_WD140EDFZ-... ONLINE 0 0 0
ata-WDC_WD140EDFZ-... ONLINE 0 0 0
ata-WDC_WD140EDFZ-... ONLINE 0 0 0
ata-WDC_WD140EDFZ-... ONLINE 0 0 0
errors: No known data errors
Significado: El pool está online; el scrub está limpio; sin errores de lectura/escritura/checksum. “Some supported features not enabled” es informativo.
Decisión: Si el estado no es ONLINE o ves errores CKSUM, deja de tunear y comienza por arreglar hardware/cables primero. Afinar rendimiento en un pool enfermo es teatro de rendimiento.
Task 2: Verificar propiedades del dataset que importan para medios
cr0x@server:~$ zfs get -o name,property,value -s local,default recordsize,compression,atime,sync tank/media
NAME PROPERTY VALUE
tank/media recordsize 128K
tank/media compression off
tank/media atime on
tank/media sync standard
Significado: Este dataset está en valores genéricos: 128K records, sin compresión, atime habilitado.
Decisión: Para medios finalizados, cambia a recordsize=1M, compression=lz4, atime=off. Deja sync tal como está a menos que entiendas el comportamiento de sync de tus clientes.
Task 3: Aplicar ajustes amigables para medios (de forma segura, por dataset)
cr0x@server:~$ sudo zfs set recordsize=1M compression=lz4 atime=off tank/media
Significado: Los archivos nuevos usarán hasta 1M por registro; los bloques existentes no se reescriben mágicamente.
Decisión: Si necesitas que los archivos existentes se beneficien, planifica un flujo de reescritura (Task 8).
Task 4: Verificar que los ajustes se aplicaron
cr0x@server:~$ zfs get -o name,property,value recordsize,compression,atime tank/media
NAME PROPERTY VALUE
tank/media recordsize 1M
tank/media compression lz4
tank/media atime off
Significado: El dataset ahora está ajustado para lecturas secuenciales grandes con compresión de bajo overhead.
Decisión: Pasa a la validación: ¿realmente vemos bloques más grandes y mejor throughput?
Task 5: Observar patrones de E/S en tiempo real durante reproducción o copia
cr0x@server:~$ iostat -xm 2 3
Linux 6.8.0 (server) 12/25/2025 _x86_64_ (16 CPU)
Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz w/s wkB/s w_await wareq-sz aqu-sz %util
sda 18.0 2400.0 0.0 0.0 8.1 133.3 0.5 64.0 2.0 128.0 0.2 14.0
sdb 17.5 2320.0 0.0 0.0 7.9 132.6 0.6 80.0 2.1 133.3 0.2 13.5
md0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
Significado: Se están realizando lecturas con tamaños medios de petición alrededor de ~128K a nivel de dispositivo de bloque. Eso no es necesariamente “malo”, pero sugiere que ZFS aún puede estar emitiendo E/S más pequeñas (o la carga no es puramente secuencial).
Decisión: Revisa estadísticas del lado ZFS (ARC, prefetch, tamaños de registro) y si los archivos fueron escritos antes de cambiar recordsize.
Task 6: Comprobar ARC y presión de memoria
cr0x@server:~$ arcstat 2 3
time read miss miss% dmis dm% pmis pm% mmis mm% arcsz c
12:01:10 520 40 7 8 20 30 75 2 5 48.2G 52.0G
12:01:12 610 55 9 10 18 42 76 3 5 48.3G 52.0G
12:01:14 590 60 10 12 20 45 75 3 5 48.3G 52.0G
Significado: El tamaño del ARC es ~48G con un objetivo c ~52G. La tasa de fallos es baja; existen misses de prefetch (el streaming multimedia activará prefetch).
Decisión: Si el ARC es pequeño o se reduce constantemente, investiga límites de memoria y otros servicios. Los servidores multimedia que también ejecutan contenedores y transcodificación pueden dejar al ARC sin recursos y luego culpar a los discos.
Task 7: Confirmar tamaños de bloque en disco reales de un archivo multimedia
cr0x@server:~$ zdb -bbbb tank/media "movie.mkv" | head -n 12
Indirect blocks:
0 L0 512K 1/1/200 16384L/32768P F=1 B=1000/1000
1 L0 512K 1/1/200 16384L/32768P F=1 B=1000/1000
2 L0 512K 1/1/200 16384L/32768P F=1 B=1000/1000
3 L0 512K 1/1/200 16384L/32768P F=1 B=1000/1000
Significado: Este archivo usa bloques de 512K, no de 1M. Eso sigue siendo mayor que 128K y puede reflejar cómo fue escrito (o ajustes anteriores).
Decisión: Si necesitas bloques de 1M, reescribe o vuelve a copiar el archivo después de establecer recordsize=1M (Task 8). No persigas fantasmas: recordsize es un máximo, no una garantía.
Task 8: Reescribir medios existentes para adoptar nuevo recordsize/compresión
cr0x@server:~$ rsync -aH --inplace --no-whole-file /tank/media/ /tank/media_rewrite/
sending incremental file list
movie.mkv
episode01.mkv
episode02.mkv
sent 119,845,232,110 bytes received 1,842 bytes 112,394,820.31 bytes/sec
total size is 119,842,001,002 speedup is 1.00
Significado: Estás copiando archivos a un dataset (o directorio) nuevo para que se reposicionen con las nuevas propiedades. (Usa un dataset separado como tank/media_new para semántica limpia.)
Decisión: Tras verificar, intercambia puntos de montaje o renombra datasets. Evita reescribir en sitio a menos que estés confiado y tengas backups; las bibliotecas multimedia son lo suficientemente grandes como para que los errores sean costosos.
Task 9: Comprobar la efectividad de la compresión en el dataset
cr0x@server:~$ zfs get -o name,property,value compressratio,compression tank/media
NAME PROPERTY VALUE
tank/media compression lz4
tank/media compressratio 1.08x
Significado: El ahorro global es ~8%. Para un dataset “mayormente vídeo”, eso es plausible: los sidecars y metadatos comprimen; el vídeo apenas lo hace.
Decisión: Mantén la compresión activa. Obtienes ahorro con CPU mínima. Si la CPU está limitada, quédate con lz4 en lugar de niveles pesados de zstd.
Task 10: Medir throughput real con una prueba de lectura (e interpretarla con cuidado)
cr0x@server:~$ dd if=/tank/media/movie.mkv of=/dev/null bs=8M status=progress
40097546240 bytes (40 GB, 37 GiB) copied, 38 s, 1.1 GB/s
48273149952 bytes (48 GB, 45 GiB) copied, 46 s, 1.0 GB/s
50331648000 bytes (50 GB, 47 GiB) copied, 49 s, 1.0 GB/s
Significado: Estás leyendo alrededor de 1.0 GB/s. Eso puede ser ARC (caché) o discos, dependiendo de la repetición y el estado del sistema.
Decisión: Repetir tras vaciar cachés no es directo con ZFS. En su lugar, prueba con varios archivos grandes y observa zpool iostat para confirmar lecturas físicas (Task 11).
Task 11: Observar throughput y colas de vdev de ZFS
cr0x@server:~$ zpool iostat -v tank 2 3
capacity operations bandwidth
pool alloc free read write read write
---------- ----- ----- ----- ----- ----- -----
tank 48.2T 26.1T 320 12 1.02G 45.3M
raidz2-0 48.2T 26.1T 320 12 1.02G 45.3M
sda - - 55 2 174M 7.5M
sdb - - 54 2 171M 7.4M
sdc - - 53 2 170M 7.6M
sdd - - 54 2 171M 7.6M
sde - - 52 2 168M 7.6M
sdf - - 52 2 167M 7.6M
---------- ----- ----- ----- ----- ----- -----
Significado: Las lecturas se reparten entre los discos, agregando ~1.02 GB/s. Eso es físico. Bien.
Decisión: Si el ancho de banda es bajo pero los clientes están haciendo buffering, revisa red y CPU. Si los discos muestran muchas ops pero bajo ancho de banda, estás haciendo E/S aleatoria pequeña y debes centrarte en metadatos/special vdev/ajuste de datasets de app.
Task 12: Averiguar si los metadatos son el verdadero cuello de botella (poca agilidad en directorios)
cr0x@server:~$ sudo zpool iostat -r tank 1 5
read IOs
pool raidz2-0 sda sdb sdc sdd sde sdf
---------- ------- ---- ---- ---- ---- ---- ----
tank 900 150 148 151 149 151 151
tank 1200 200 198 201 199 201 201
tank 1100 184 182 185 183 184 182
Significado: IOPS altos sin mención de ancho de banda sugieren muchas lecturas pequeñas (metadatos, miniaturas, archivos pequeños).
Decisión: Considera special vdev o mover metadatos de app a un pool/dataset respaldado por SSD. También revisa primarycache y dimensionamiento del ARC.
Task 13: Comprobar fragmentación patológica y presión de espacio libre
cr0x@server:~$ zpool list -o name,size,alloc,free,frag,cap,health tank
NAME SIZE ALLOC FREE FRAG CAP HEALTH
tank 74.3T 48.2T 26.1T 38% 64% ONLINE
Significado: 38% de fragmentación y 64% de capacidad usada no es alarmante. La fragmentación importa más en alta utilización y con escrituras aleatorias.
Decisión: Si estás por encima del ~80% de capacidad y la frag aumenta, espera caídas de rendimiento durante escrituras y resilvers. Planea expansión antes de que el pool sea una maleta apretada.
Task 14: Validar alineación de sectores (ashift) en vdevs
cr0x@server:~$ zdb -C tank | grep -E "ashift|vdev_tree" -n | head
56: vdev_tree:
72: ashift: 12
Significado: ashift=12 indica sectores de 4K. Bueno para discos modernos.
Decisión: Si ashift es 9 en discos 4K, el rendimiento y la durabilidad sufren. Arreglarlo requiere reconstruir vdevs/pool; decide temprano, no después de 50TB.
Task 15: Comprobar si escrituras sync están matando inesperadamente la ingestión
cr0x@server:~$ zpool iostat -w tank 2 3
capacity operations bandwidth
pool alloc free read write read write
---------- ----- ----- ----- ----- ----- -----
tank 48.2T 26.1T 10 220 4.2M 38.0M
---------- ----- ----- ----- ----- ----- -----
Significado: Muchas escrituras pero ancho de banda moderado puede indicar escrituras sync pequeñas o churn de metadatos.
Decisión: Revisa tu carga (manejos SMB durables, NFS sync, comportamiento de la app). Si realmente tienes escrituras sync y te importa la latencia de ingest, considera un SLOG espejado en SSDs con protección contra pérdida de energía. Si no sabes, no toques sync=disabled.
Task 16: Confirmar que los snapshots no están silenciosamente inflando el uso
cr0x@server:~$ zfs list -o name,used,usedbysnapshots,refer,avail -r tank/media | head
NAME USED USEDBYSNAPSHOTS REFER AVAIL
tank/media 22.1T 3.4T 18.7T 26.1T
Significado: 3.4T está retenido por snapshots. No es “malo”, pero explica por qué los borrados no liberan espacio.
Decisión: Si la presión de espacio sube, implementa retención de snapshots (mantén pocos, podar el resto) especialmente en datasets con churn como downloads y metadatos de apps.
Guía rápida de diagnóstico: encuentra el cuello de botella en minutos
Esta es la lista de verificación que realmente uso cuando alguien dice “el streaming hace buffering” o “las copias van lentas”. El objetivo es evitar horas de ajustes cuando el problema es un cable, un pool lleno o un disco malo haciendo danza interpretativa.
Primero: ¿el pool está sano y no está resilverizando?
- Ejecuta
zpool status -v. Si ves DEGRADED, resilvering o errores de checksum, el rendimiento es secundario. Arregla la salud primero. - Comprueba si un scrub/resilver está en curso y saturando la E/S.
Segundo: ¿es disco, CPU o red?
- Discos:
zpool iostat -v 2yiostat -xm 2. Busca un dispositivo con await/%util alto relativo a los demás. - CPU:
topompstat -P ALL 2. Busca un cuello de botella single-thread o CPU total al 100% (transcoding + compresión + checksums pueden sumarse). - Red:
ip -s linky contadores del switch. Busca errores/descartes o un enlace negociado a 1Gb cuando pensabas que era 10Gb.
Tercero: ¿accidentalmente haces E/S aleatoria pequeña?
- IOPS altos y bajo ancho de banda en
zpool iostates el indicador. - Metadatos de apps y generación de miniaturas: muévelos a SSD/special vdev o aisla en datasets.
- Revisa
atimey desactívalo para datasets de solo lectura frecuente.
Cuarto: ¿el pool está demasiado lleno o fragmentado?
zpool listpara capacidad y fragmentación.- Si estás por encima del ~80–85% de uso, deja de esperar milagros. Planea expansión, elimina con conciencia de snapshots o añade vdevs.
Quinto: confirma que tu afinado coincide con el dataset
zfs get recordsize,compression,atimepara el dataset en cuestión.- Si cambiaste recordsize recientemente, verifica archivos nuevos, no los antiguos. Los bloques antiguos persisten.
Tres mini-historias corporativas desde la trinchera
1) Incidente causado por una suposición incorrecta: “Son solo lecturas secuenciales, RAIDZ está bien”
Un equipo de producción construyó un NAS compartido para editores. La carga “parecía multimedia”, así que lo dimensionaron para throughput: pool HDD grande, RAIDZ2, muchos discos, enlace de red ancho. Todos felices durante la primera copia y la primera semana de reproducción.
Luego la biblioteca creció. El gestor de activos empezó a generar proxies, miniaturas, vistas de forma de onda e índices de metadatos. Los editores empezaron a avanzar/retroceder en líneas de tiempo y saltar por archivos. El patrón de E/S se convirtió en una mezcla desagradable: lecturas secuenciales para reproducción más lecturas aleatorias para miniaturas más escrituras aleatorias para actualizaciones de metadatos.
La suposición equivocada fue que “multimedia = secuencial”. Multimedia más herramientas = carga mixta. RAIDZ2 no era “malo”, pero el pool no tenía un lugar rápido para metadatos, y los picos de latencia hicieron que la UI pareciera rota. Parecía un problema de red porque los clientes hacían buffering y las sesiones SMB seguían conectadas. Naturalmente, todos culparon al switch. Por supuesto.
La solución fue aburrida: separar datasets, mover metadatos de app a SSDs, añadir un special vdev espejado y dejar de martillar el mismo dataset con medios finalizados y metadatos constantemente cambiantes. El ajuste de recordsize ayudó, pero la verdadera victoria fue dar a los metadatos un carril rápido.
Después de eso, el rendimiento se volvió predecible. No “predicción máxima” — predecible de verdad. Del tipo que para los hilos de Slack.
2) Optimización que salió mal: desactivar sync para “acelerar la ingestión”
Un grupo corporativo de comunicaciones ingestaba cientos de GB por día de metraje de cámara. Alguien corrió un benchmark rápido, vio escrituras lentas y encontró la perillita: sync=disabled. Lo activaron, la ingestión se duplicó. Un héroe nace.
Semanas después, un evento eléctrico afectó el edificio. La UPS hizo lo que pudo, pero el host perdió energía a mitad de una ingestión. Tras el reinicio, el pool se importó bien. El sistema de ficheros montó. Pero los archivos más recientes estaban corruptos de formas sutiles—algunos clips con fallos de reproducción, otros con segmentos finales faltantes, algunos fallaban la verificación de checksum en la app de edición.
No apareció un único error tipo “ZFS se rompió”. Ese es el truco. Desactivar sync no rompe el pool; rompe tus promesas. Aplicaciones que creían que fsync() significaba “en almacenamiento estable” fueron engañadas. Hicieron lo correcto; el almacenamiento no.
La remediación tomó tiempo: re-ingestar desde la fuente, implementar protección contra pérdida de energía y restaurar sync=standard. Añadieron un pequeño SLOG espejado en SSDs con protección contra pérdida de energía, recuperando la mayor parte del rendimiento de ingest sin perder la semántica.
Afinar el rendimiento mintiendo a las aplicaciones no es afinar. Es deuda con intereses.
3) Práctica aburrida pero correcta que salvó el día: scrubs mensuales + alertas
Un archivo interno de streaming corría en un pool ZFS grande. Nada lujoso: controladoras decentes, boot espejado, datos en RAIDZ2 y un special vdev espejado para metadatos. El equipo tenía una práctica religiosa: scrubs programados y alertas que realmente despachaban a alguien que importaba.
Un mes, un scrub reportó un puñado de errores de checksum en un solo disco. El sistema curó los datos usando redundancia, pero la alerta saltó. El disco no estaba obviamente muerto; SMART parecía “bien”, porque SMART ama el optimismo.
Reemplazaron el disco durante horario laboral, con calma, antes de que escalara a una falla de múltiples discos durante un resilver. Una semana después, un segundo disco del mismo lote empezó a devolver errores de lectura. Sin el primer reemplazo, eso podría haber sido un mal día.
Sin afinamientos heroicos. Sin sysctl secretos. Solo scrubs, alertas y voluntad de reemplazar un disco que se estaba comportando mal temprano. La fiabilidad es principalmente negarse a sorprenderse.
Errores comunes: síntoma → causa raíz → solución
1) “El streaming se interrumpe cuando alguien hace un escaneo de biblioteca”
Síntoma: La reproducción se pausa o la UI se vuelve lenta durante escaneos, generación de miniaturas o actualización de metadatos.
Causa raíz: La carga de metadatos/archivos pequeños compite con las lecturas de streaming en los mismos vdevs; el ARC es thrasheado por lecturas aleatorias pequeñas.
Solución: Separa datasets; mueve metadatos de app a SSD o añade special vdev espejado; mantén los archivos multimedia en un dataset de registros grandes; considera limitar la concurrencia de escaneo en la app.
2) “Puse recordsize=1M pero nada mejoró”
Síntoma: No hay cambio medible tras afinar.
Causa raíz: Los archivos existentes mantienen su layout de bloques antiguo; recordsize se aplica principalmente a escrituras nuevas.
Solución: Reescribe/re-copia archivos en un dataset con los nuevos ajustes (rsync o zfs send/recv). Verifica con zdb en un archivo de muestra.
3) “Las escrituras son lentas e iostat muestra escrituras pequeñas con alta latencia”
Síntoma: La ingestión se ve limitada a decenas de MB/s; picos de latencia.
Causa raíz: Escrituras sync desde SMB/NFS/comportamiento de apps, sin SLOG, o discos lentos obligados a confirmar frecuentemente.
Solución: Mantén sync=standard. Si las escrituras sync son reales e importantes, añade un SLOG espejado y protegido contra pérdida de energía; si no, ajusta clientes/apps que fuerzan sync.
4) “El pool se volvió más lento con el tiempo aunque los discos están sanos”
Síntoma: Decaimiento gradual de rendimiento, especialmente en escrituras y durante mantenimiento.
Causa raíz: Alta ocupación del pool y fragmentación; mucho churn bajo snapshots; la amplificación de escritura en RAIDZ empeora con alta utilización.
Solución: Mantén pools por debajo de ~80–85% usados; poda snapshots; añade vdevs antes de estar desesperado; aísla datasets con churn como downloads.
5) “El navegador SMB es lento pero el streaming está bien”
Síntoma: Listar directorios y abrir carpetas tarda segundos; una vez iniciada la reproducción está bien.
Causa raíz: Latencia de metadatos. El recorrido de directorios y llamadas stat son lecturas pequeñas aleatorias; quizá atime también está activado.
Solución: atime=off; special vdev para metadatos; asegura que el ARC tenga suficiente RAM; evita poner estado de apps intensivo en metadatos en los mismos discos giratorios que los medios si puedes evitarlo.
6) “Errores de checksum aparecen durante scrub”
Síntoma: zpool status muestra bytes reparados o conteos CKSUM crecientes.
Causa raíz: Disco fallando, cable/backplane defectuoso, problemas de controlador o (menos común) inestabilidad de memoria.
Solución: Trátalo como incidente de hardware. Reasienta/reemplaza cables, cambia bahías, corre tests SMART largos, reemplaza discos sospechosos. No ‘afines’ errores de checksum.
Listas de verificación / plan paso a paso
Plan A: Pool de medios nuevo, hecho bien
- Elige topología de vdev basada en dominio de fallo y tiempo de reconstrucción: RAIDZ2 para pools HDD grandes es un valor por defecto razonable; mirrors si necesitas mejor I/O aleatorio y resilvers más rápidos.
- Fija ashift correctamente al crear (típicamente 12 para HDDs modernos 4K).
- Crea datasets por carga: media, downloads, metadatos de app, backups.
- Establece propiedades de dataset:
- Media:
recordsize=1M,compression=lz4,atime=off. - Downloads: compresión activada; recordsize por defecto; considera
sync=standardsiempre. - App: recordsize por defecto; considera SSD/special vdev.
- Media:
- Implementa snapshots con retención (especialmente para app y downloads). Mantén la política simple para que realmente se ejecute.
- Scrubs programados + alertas. Si no alertas, no estás haciendo scrubs; estás documentando tus arrepentimientos.
- Prueba con flujos reales: streams simultáneos + escaneo + ingest. Las pruebas sintéticas solo te dicen cómo sería tu vida sintética.
Plan B: Pool existente con ajustes genéricos
- Confirma salud:
zpool status. Arregla errores primero. - Separa datasets: crea
tank/media,tank/app,tank/downloadssi no los tienes. - Aplica propiedades multimedia solo a
tank/media. - Reescribe o recopia archivos para adoptar recordsize/compresión.
- Mueve metadatos de app fuera de discos giratorios si la navegación es lenta (pool SSD o special vdev).
- Reevalúa capacidad y fragmentación; haz un plan de expansión antes de llegar al 90% usado.
Plan C: Ya estás en llamas (buffering en producción)
- Detén tareas en segundo plano: pausa escaneos, pausa backups, pospone scrubs/resilvers si es seguro y la política lo permite.
- Ejecuta
zpool iostat -v 2y encuentra cualquier disco claramente lento; reemplaza/rehubica si está fallando. - Revisa negociación de red y errores.
- Confirma la carga: ¿estás transcodificando? La CPU podría ser tu “problema de disco”.
- Después de estabilizar, implementa separación de datasets y aceleración de metadatos.
Preguntas frecuentes
1) ¿Debería siempre poner recordsize=1M para medios?
Para archivos multimedia grandes y finalizados, sí. Para cualquier cosa con lecturas/escrituras aleatorias pequeñas (metadatos de apps, descargas en curso, miniaturas), no. Separa datasets y ajusta por carga.
2) ¿La compresión dañará el rendimiento de streaming de vídeo?
Usualmente no con lz4. El vídeo ya está comprimido, así que los ahorros son pequeños, pero el coste en CPU es bajo. El riesgo es usar zstd en niveles altos en una CPU que ya está ocupada transcodificando.
3) Si la relación de compresión es solo 1.02x, ¿es inútil?
No. Incluso pequeñas ganancias globales pueden ocultar ahorros significativos en archivos secundarios y metadatos. Además, los bloques comprimidos pueden reducir los bytes leídos del disco para las partes compresibles, reduciendo picos de latencia.
4) ¿Cuál es la mejor disposición: RAIDZ2 o mirrors?
Para medios a granel en HDDs, RAIDZ2 es un valor por defecto sensato por capacidad y seguridad. Los mirrors suelen sentirse más rápidos para I/O aleatorio y resilvers, pero cuestan más en discos. Si tu cuello de botella es latencia de metadatos, un special vdev puede ser una mejora mayor que cambiar la topología.
5) ¿Necesito un L2ARC para un servidor multimedia?
Raramente. El streaming suele ser secuencial y no se beneficia mucho de L2ARC a menos que tengas lecturas repetidas del mismo contenido y RAM insuficiente. Si la navegación es lenta, arregla la localización de metadatos primero.
6) ¿Debería desactivar atime en todas partes?
En datasets multimedia y de solo lectura frecuente, sí. En datasets donde algún flujo depende de la semántica atime (poco común), déjalo activado. Si no sabes, desactívalo para medios y deja por defecto los datasets de apps hasta que pruebes lo contrario.
7) ¿Es aceptable sync=disabled alguna vez?
Sólo cuando aceptas explícitamente el riesgo de pérdida de datos por corte de energía y conoces la semántica de la carga. Para uso empresarial o cualquier cosa por la que llorarías, mantén sync=standard y usa hardware apropiado (UPS, SLOG si es necesario).
8) ¿Qué tan lleno puedo mantener un pool ZFS?
Intenta mantenerte por debajo de ~80–85% para rendimiento y resiliencia predecibles. Por encima de eso, la fragmentación y las restricciones de asignación pueden amplificar la latencia, especialmente en RAIDZ durante escrituras y mantenimiento.
9) ¿Puedo cambiar ashift después de crear el pool?
No in-place de una manera sensata. El método práctico es reconstruir: reemplazar vdevs por otros con tamaño correcto o migrar datos a un pool nuevo. Elige ashift correctamente desde el día cero.
10) ¿Cómo afectan los snapshots al almacenamiento de medios?
Los snapshots son baratos hasta que no lo son. Los archivos multimedia no cambian a menudo, por lo que los snapshots no crecen mucho—a menos que guardes downloads o bases de datos de apps con churn en el mismo dataset. Usa datasets separados y retención de snapshots acorde al churn.
Conclusión: pasos prácticos siguientes
Si quieres las “grandes ganancias” sin convertir tu almacenamiento en un proyecto experimental de arte, haz tres cosas:
- Separa datasets por comportamiento: medios finalizados, descargas y metadatos de app no deberían compartir un único conjunto de propiedades.
- Haz los medios aburridos:
recordsize=1M,compression=lz4,atime=offen el dataset de medios. - Diagnóstica con evidencia:
zpool status,zpool iostat,iostat, estadísticas ARC y capacidad/fragmentación antes de girar perillas.
Luego, si la navegación y los escaneos siguen sintiéndose como vadear por melaza, deja de culpar a los discos y comienza a tratar los metadatos como una carga de trabajo de primera clase: datasets respaldados por SSD o un special vdev espejado pueden cambiar la experiencia más que cualquier ajuste de recordsize.