Cuando la referencia supera a lo personalizado: el mito que a veces es cierto

¿Te fue útil?

El incidente no fue causado por un disco roto. Ni por un bug del kernel. Ni siquiera por una nueva y emocionante cepa de ransomware. Fue causado por alguien que “mejoró” el sistema desviándose de la configuración de referencia —con discreción, confianza y sin un plan de reversión.

Si operas producción, ya has visto esta película. El villano no es la incompetencia. Es la ambición mezclada con información incompleta, más la consoladora mentira de que “personalizado” siempre significa “mejor”. A veces lo más eficiente y fiable que puedes hacer es copiar el diseño de referencia aburrido y dejar de tocarlo.

El mito: lo personalizado siempre vence a la referencia

El mito tiene un buen arco narrativo: empiezas con una referencia del proveedor o un valor por defecto upstream, luego la “optimizas” para tu carga de trabajo. Eliminas la “hinchazón”. Añades una capa de caché ingeniosa. Cambias el planificador de E/S. Modificas profundidades de cola. Ajustas la replicación. Obtienes un gráfico que se desplaza a la derecha. Ganas.

En la realidad, lo personalizado supera a la referencia en benchmarks con más consistencia que en producción. Producción te castiga por todo lo que el benchmark no incluyó: vecinos ruidosos, copias de seguridad diarias, actualizaciones del kernel, rarezas de firmware, trabajos por lotes que llegan tarde, patrones de tráfico que rotan y personas que necesitan poder operar el sistema a las 3 a.m.

Aquí está la verdad operativa: si tu diseño personalizado es realmente mejor, deberías poder explicar no solo por qué es más rápido, sino por qué es más diagnosticable, más recuperable y menos sorprendente ante fallos. Si no puedes, no construiste una mejora: construiste una responsabilidad.

Uno de los mejores heurísticos que he aprendido es este: los diseños de referencia no son “óptimos”, son defendibles. Están construidos para ser reproducibles, soportables y para tener un sobre de falla predecible. Esa última parte importa más de lo que la mayoría de equipos presupuestan.

Qué significa realmente “referencia” (y qué no)

La referencia es un contrato, no una sugerencia

Una buena arquitectura de referencia es un conjunto probado de suposiciones: hardware, firmware, drivers, parámetros del kernel, opciones del sistema de archivos, ajustes de red y procedimientos operativos. Es un contrato entre tú y la realidad: “Si hago estas cosas, el sistema se comporta dentro de estos límites.”

No es perfecta. A veces es conservadora. A veces beneficia al proveedor. A veces está congelada en el tiempo porque los equipos de soporte odian el caos. Pero por lo general es coherente. La coherencia está subestimada.

La referencia no son “valores por defecto”, y los valores por defecto no siempre son referencia

Los valores por defecto upstream a menudo se eligen por seguridad general en una amplia variedad de hardware y casos de uso. Una configuración de referencia del proveedor se elige para resultados predecibles en plataformas y cargas de trabajo específicas. Se solapan, pero no son sinónimos.

Cuando la gente dice “estamos usando la referencia”, lo que a menudo quieren decir es “estamos usando algo cercano, excepto por doce ajustes que hicimos el año pasado y olvidamos documentar.” Eso no es referencia. Eso es folclore.

La referencia no elimina tu responsabilidad

Copiar una compilación de referencia no te exime de pensar. Solo mueve tu pensamiento a los lugares correctos: caracterización de la carga, planificación de capacidad, dominios de falla y observabilidad. Todavía necesitas entender qué hacen las perillas—simplemente no necesitas inventar perillas nuevas para demostrar que eres listo.

Por qué la referencia gana más a menudo de lo que los ingenieros admiten

1) Reduce el espacio de búsqueda

Los incidentes de producción son problemas de búsqueda. Algo está mal; necesitas aislarlo rápido. Cuanto más a medida sea tu sistema, mayor será el espacio de búsqueda y menos podrá apoyarse tu equipo en comportamientos conocidos como buenos. Los diseños de referencia reducen los grados de libertad.

En términos de SRE: reducen el tiempo medio hasta la exoneración. No porque el proveedor siempre tenga razón, sino porque puedes descartar rápidamente clases enteras de mala configuración.

2) Ha sido probado bajo fallo, no solo bajo carga

Mucho del discurso “lo personalizado vence a la referencia” se basa en pruebas de carga: rendimiento, latencia p99, uso de CPU. Pero las pruebas de fallo son donde los diseños de referencia justifican su valor: fallos de disco, conmutación por error de controladora, caídas de enlace, tormentas de resinc, detección de corrupción, tiempos de reconstrucción y qué pasa cuando el pager suena en medio de un mantenimiento.

Los diseños de referencia suelen estar afinados para un comportamiento “degradado pero vivo”. Los diseños personalizados a menudo están afinados para “rápido hasta que no lo es”.

3) Se alinean con soporte y herramientas

Si estás usando una matriz de almacenamiento comercial, una distribución de Kubernetes gestionada o incluso una distro estándar de Linux, estás comprando implícitamente un ecosistema: playbooks de soporte, bugs conocidos, firmware recomendado y expectativas de herramientas.

Deviar lo suficiente y descubrirás una soledad especial: el ticket donde el soporte te pide revertir a la referencia antes de investigar. No son antipáticos. Intentan hacer tu problema reproducible.

4) Producen líneas base estables

La excelencia operativa es gestión de líneas base: “Esto es normal.” Los diseños de referencia te dan un “normal” estable que sobrevive a cambios de personal. Los diseños personalizados a menudo sobreviven solo mientras el ingeniero que los construyó permanece interesado.

5) Reducen la deriva de configuración

La deriva es la fuga lenta de la confiabilidad. Las construcciones personalizadas multiplican las perillas que pueden derivar. Incluso si las gestionas con Infrastructure as Code, cada perilla adicional crea un nuevo lugar de divergencia entre entornos y en el tiempo.

Chiste #1: Si tu afinación de almacenamiento requiere una hoja de cálculo con macros, no construiste un sistema — construiste un test de personalidad.

6) Mantienen a los humanos en el circuito donde deben estar

Un diseño de referencia suele estar pensado para ser operado por humanos normales, no solo por los autores originales. Eso significa logs predecibles, métricas sensatas, timeouts conservadores y procedimientos de recuperación documentados. Los sistemas personalizados a menudo tratan al humano como un pensamiento posterior y luego se sorprenden cuando los humanos se comportan como humanos.

Una cita, porque todos la necesitamos

idea parafraseada — John Ousterhout: la simplicidad es un requisito previo para la fiabilidad; la complejidad es donde viven los bugs y los incidentes.

Cuándo lo personalizado debería ganar (y cómo hacerlo de forma segura)

Lo personalizado gana cuando puedes definir “mejor” como un objetivo medible

“Mejor” no es “más guay”. No es “más moderno”. Es “latencia de escritura p99 por debajo de 2 ms al 60% de utilización del disco”, o “restaurar un volumen de 5 TB en 30 minutos”, o “sobrevivir a la pérdida de una AZ sin intervención manual”.

Si no puedes escribir el objetivo y probarlo, estás a punto de optimizar sensaciones.

Lo personalizado gana cuando la carga es verdaderamente no estándar

Algunas cargas son raras de formas que los diseños de referencia no pueden anticipar: presión extrema de metadatos por archivos pequeños, escrituras log-estructuradas con restricciones de orden estrictas, volúmenes efímeros con alta rotación o lecturas aleatorias mezcladas con escrituras síncronas y tráfico en ráfagas. Si tu carga es realmente especial, la referencia podría estar dejando rendimiento sobre la mesa.

Lo personalizado gana cuando puedes permitirte el impuesto operativo

Cada desviación personalizada tiene un impuesto continuo: más observabilidad, más runbooks, más pruebas, más formación, más upgrades cuidadosos. Si no presupuestas ese impuesto, tu “optimización” te la cobrarán con intereses en el primer incidente.

Lo personalizado gana cuando puedes volverlo aburrido otra vez

Lo único sostenible es aquello que internalizas como producto: documentado, repetible, validado y monitorizado. Si tu diseño personalizado sigue siendo una pieza artesanal única, se derretirá en el peor momento.

Una regla práctica: si vas a divergir, hazlo en una dimensión a la vez. Cambia una perilla, mide, conserva o revierte. Los sistemas no premian pilas creativas de cambios “pequeños”.

Datos interesantes y contexto histórico

  • El pitch original de RAID a finales de los 80 fue sobre usar muchos discos baratos de forma fiable; se convirtió en una línea base de referencia precisamente porque estandarizó el comportamiento frente a fallos.
  • El control de congestión de TCP evolucionó de “afinar por velocidad” a “afinar por equidad y estabilidad” tras los colapsos tempranos de la red; los valores por defecto importan cuando todos comparten la misma red.
  • Las bases de datos aprendieron por las malas que el write-ahead logging y las semánticas de fsync son innegociables para la corrección; muchos diseños “rápidos” simplemente omitían seguridad.
  • La adopción temprana de SSD provocó una ola de afinaciones “personalizadas” que ignoraron la amplificación de escritura y la recolección de basura del firmware, causando acantilados de rendimiento tras semanas en producción.
  • La virtualización normalizó el overcommit pero también hizo la latencia de E/S más difícil de razonar; surgieron configuraciones de referencia para controlar el radio de daño por vecinos ruidosos.
  • Los planificadores de E/S de Linux cambiaron valores por defecto a medida que el almacenamiento pasó de discos giratorios a SSD y NVMe; los consejos de afinación de hace cinco años pueden ser activamente dañinos ahora.
  • La cultura de postmortem en operaciones a gran escala hizo de la “reproducibilidad” un requisito de primera clase; las compilaciones de referencia te ayudan a reproducir el estado que importó.
  • Los servicios gestionados en la nube tuvieron éxito en parte porque eliminaron categorías enteras de afinación personalizada que los usuarios estropeaban —por diseño, no por accidente.

Tres mini-historias del mundo corporativo

Mini-historia #1: Un incidente causado por una suposición equivocada

Una compañía SaaS de tamaño medio operaba una flota de servidores Linux con NVMe local y una base de datos replicada. El equipo heredó una configuración de referencia del proveedor para el SO y el sistema de archivos: opciones de montaje conservadoras, sin sysctls exóticos y una matriz clara de firmware. Un ingeniero nuevo notó “rendimiento sin usar” y hizo una suposición confiada: “Estos son discos NVMe; las barreras y el orden no importan como en los discos giratorios.”

Cambiaron las opciones de montaje del sistema de archivos para reducir la sobrecarga de metadatos síncronos y ajustaron la aplicación para confiar más en la caché de páginas del SO. El benchmark se veía fantástico. El gráfico de latencia p95 quedó más suave. El despliegue se celebró en silencio porque al ingeniero no le gustaba la atención. Una semana después, un evento de energía afectó a un rack. No fue un corte total — solo un rebote brusco.

La base de datos volvió con una pequeña pero real corrupción. No catastrófica, pero suficiente para desencadenar una restauración desordenada y una resinc dolorosa entre réplicas. La recuperación fue “exitosa” en el sentido más estrecho: se restauraron los datos. Pero el informe del incidente parecía una escena de crimen: se debilitaron las garantías de orden, las suposiciones de durabilidad de la aplicación se violaron y la corrupción solo se manifestó bajo un modo de fallo poco glamoroso que nadie probó.

La suposición equivocada no fue que NVMe sea rápido. Fue creer que la velocidad reemplaza la corrección. Las configuraciones de referencia tienden a incorporar supuestos conservadores de corrección porque los proveedores son demandados cuando los datos desaparecen.

La solución también fue aburrida: volver a los valores de durabilidad de referencia, luego optimizar en otros lugares —patrones de consulta, batching y reducir llamadas fsync innecesarias. La lección: si un cambio afecta las semánticas de durabilidad, no puedes llamarlo “afinación de rendimiento”. Es una decisión de producto.

Mini-historia #2: Una optimización que se volvió en contra

Una gran empresa tenía una plataforma Kubernetes con almacenamiento en red respaldado por CSI. El proveedor de almacenamiento suministró un diseño de referencia: ajustes de multipath, profundidades de cola y timeouts afinados para conmutación por error. Alguien del equipo de plataforma leyó un hilo antiguo que sugería que profundidades de cola mayores mejoraban el rendimiento. Aumentaron la profundidad de cola iSCSI y el tamaño de las solicitudes en toda la flota.

Para cargas masivas, el rendimiento mejoró. Los gráficos parecían una vuelta de victoria. Luego la plataforma experimentó una conmutación por error de la controladora durante un mantenimiento rutinario. Debería haber sido inofensivo. En su lugar, la latencia se disparó a segundos. Las aplicaciones hicieron timeout. Los pods se reiniciaron. El responsable en turno recibió páginas por “inestabilidad aleatoria de servicio” en múltiples namespaces.

El análisis posterior mostró que la “optimización” había profundizado la cola de E/S en vuelo. Durante la conmutación por error, esas solicitudes no desaparecieron; se amontonaron detrás de una pausa transitoria. El tiempo de recuperación creció con la cola, así que la conmutación por error se convirtió en un brownout de varios minutos. No es que la conmutación por error fallara — fue que el equipo de plataforma la hizo cara.

El equipo revirtió a las profundidades de cola de referencia, y luego construyó un verdadero sobre de rendimiento: diferentes clases de almacenamiento para rendimiento por lotes frente a cargas sensibles a la latencia, con guardarraíles y SLOs explícitos. También aprendieron que afinar para throughput puede saboteardesapercibidamente la latencia cola —y la latencia cola es lo que encuentran tus clientes.

Mini-historia #3: Una práctica aburrida pero correcta que salvó el día

Una fintech operaba un servicio intensivo en almacenamiento con ZFS sobre Linux. Sus ingenieros tenían opiniones, y sus opiniones tenían opiniones. Aun así, adoptaron una política estricta: los pools de producción deben coincidir con un perfil de referencia evaluado (recordsize, compresión, atime, ashift, ajustes de sync), y las desviaciones requieren una justificación por escrito más un plan de reversión.

La práctica que resultaba más aburrida era su “auditoría de deriva de referencia” mensual. Un ingeniero compararaba la configuración en vivo con la línea base conocida y abría pequeños PRs para reconciliar diferencias. Era el tipo de trabajo que nunca recibía aplausos, lo cual suele ser señal de que importa.

Un mes, la auditoría encontró un pequeño conjunto de nodos con un parámetro del kernel distinto relacionado con el comportamiento de escritura de páginas sucias. Nadie recordaba haberlo cambiado. No había síntomas obvios — aún. El equipo lo revirtió y siguió con su trabajo.

Dos semanas después, un pico de tráfico más un trabajo analítico pesado habría creado la tormenta perfecta: gran acumulación de páginas sucias seguida por una ola de flush de E/S. La compañía nunca sufrió ese fallo en particular. Los mejores incidentes son los que solo ves en contrafactuales.

La lección: las prácticas “aburridas pero correctas” no generan capturas de pantalla de victorias. Crean mañanas donde tu café se mantiene caliente.

Guía rápida de diagnóstico

Cuando el rendimiento o la fiabilidad se tuercen, no tienes tiempo para filosofar sobre personalizado versus referencia. Necesitas encontrar el cuello de botella rápido, decidir si estás en modo “revertir a conocido bueno” y evitar empeorar la situación.

Primero: confirma que el síntoma es real y su alcance

  • ¿Es un solo host, una AZ, una clase de almacenamiento, una carga de trabajo o todo?
  • ¿Es latencia, throughput, errores o saturación?
  • ¿Cambió algo: despliegue, kernel, firmware, red, feature flags?

Segundo: localiza el dominio del cuello de botella

  • Limitado por CPU: alta carga, iowait alto (con cuidado), crecimiento de la cola de ejecución, throttle.
  • Limitado por memoria: reclaim, swapping, tormentas de writeback de páginas sucias.
  • Limitado por disco/array: alta latencia del dispositivo, saturación de cola, caché de escritura desactivada, reconstrucciones.
  • Limitado por red o tejido de almacenamiento: retransmisiones, caídas de enlace, thrash de multipath, inconsistencia de jumbo.
  • Limitado por la aplicación: contención de locks, escrituras síncronas, patrones N+1 de I/O.

Tercero: decide si revertir o seguir depurando

  • Si el sistema se desvía de la referencia y el problema coincide con esa desviación, revierte primero. Depura después.
  • Si el sistema coincide con la referencia y aún falla, captura evidencia: histogramas de latencia, estadísticas de dispositivos, logs de error.
  • Si no puedes reproducir en staging, asume variabilidad de producción y céntrate en observabilidad, no en afinaciones heroicas.

Cuarto: protege las rutas de recuperación

  • Pausa las “optimizaciones” durante la respuesta al incidente. Los cambios son cómo pierdes la película.
  • Preserva logs y métricas; no reinicies por reflejo a menos que restaure el servicio y aceptes perder estado.
  • Mantén un artefacto de rollback y configuración conocida limpio. Los diseños de referencia solo son útiles si puedes volver a ellos rápido.

Tareas prácticas: comandos, salidas, qué significa y la decisión

Estas son tareas reales que puedes ejecutar en Linux para comprobar si tu historia “lo personalizado es mejor” se sostiene. Cada ítem incluye un comando, un fragmento plausible de salida, qué indica y qué decisión tomar a continuación.

Tarea 1: Confirma qué kernel y SO estás ejecutando

cr0x@server:~$ uname -a
Linux server 6.5.0-21-generic #21~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC x86_64 GNU/Linux

Qué significa: Tu comportamiento de rendimiento y E/S depende mucho de la versión y configuración del kernel.

Decisión: Si estás depurando almacenamiento y no estás con el kernel de referencia del proveedor, trátalo como sospechoso. Considera revertir o reproducir en el kernel de referencia antes de afinar más.

Tarea 2: Identifica parámetros de arranque y sysctls ocultos

cr0x@server:~$ cat /proc/cmdline
BOOT_IMAGE=/vmlinuz-6.5.0-21-generic root=UUID=... ro quiet splash transparent_hugepage=never

Qué significa: Algunos parámetros de arranque “pequeños” pueden dominar la latencia (THP, mitigaciones, ajustes de IOMMU).

Decisión: Si tu flota no es consistente con la referencia, estandariza. La deriva aquí crea historias fantasma.

Tarea 3: Comprueba opciones de montaje del sistema de archivos (compromiso durabilidad vs velocidad)

cr0x@server:~$ findmnt -no TARGET,SOURCE,FSTYPE,OPTIONS /var/lib/data
/var/lib/data /dev/nvme0n1p2 ext4 rw,relatime,errors=remount-ro

Qué significa: Las opciones de montaje revelan si alguien desactivó funciones de seguridad o activó opciones exóticas.

Decisión: Si ves opciones arriesgadas que divergen de la referencia, revierte a menos que puedas probar la corrección bajo pérdida de energía y escenarios de crash.

Tarea 4: Comprueba la salud del disco rápidamente antes de culpar a la afinación

cr0x@server:~$ sudo smartctl -a /dev/nvme0n1 | sed -n '1,25p'
smartctl 7.2 2020-12-30 r5155 [x86_64-linux-6.5.0-21-generic] (local build)
=== START OF INFORMATION SECTION ===
Model Number:                       ACME NVMe 3.2TB
Firmware Version:                   1.4.9
Percentage Used:                    74%
Data Units Written:                 987,654,321
Media and Data Integrity Errors:    0

Qué significa: “Percentage Used” cerca del final de vida y mismatches de firmware pueden crear picos de latencia.

Decisión: Si el desgaste es alto o el firmware difiere de la referencia, planifica reemplazo o alinea el firmware antes de perseguir micro-optimizaciones.

Tarea 5: Ver la latencia real del dispositivo y el encolamiento

cr0x@server:~$ iostat -x 1 3
Linux 6.5.0-21-generic (server) 	01/21/2026 	_x86_64_	(32 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          12.30    0.00    4.10    8.20    0.00   75.40

Device            r/s   w/s  rMB/s  wMB/s  avgrq-sz avgqu-sz await r_await w_await  svctm  %util
nvme0n1         1200  1800   95.0  210.0      180     12.5   6.8    3.1     9.2   0.25  97.0

Qué significa: Un await alto y un %util alto implican saturación del dispositivo o encolamiento aguas arriba.

Decisión: Si el dispositivo está al máximo, ajustar la concurrencia de la app o repartir la carga puede ayudar. Si es un array compartido, verifica la salud del tejido y del array; no subas a tope la profundidad de cola sin más.

Tarea 6: Identifica el planificador de I/O y si coincide con tu medio

cr0x@server:~$ cat /sys/block/nvme0n1/queue/scheduler
[none] mq-deadline kyber bfq

Qué significa: NVMe suele rendir bien con none, pero tu carga podría preferir un planificador para equidad.

Decisión: Si cambiaste esto desde la referencia, mide la latencia p99 bajo carga mixta. Si la cola empeora, revierte.

Tarea 7: Comprueba writeback y settings de páginas sucias (clásica trampa de afinación)

cr0x@server:~$ sysctl vm.dirty_background_ratio vm.dirty_ratio vm.dirty_expire_centisecs
vm.dirty_background_ratio = 10
vm.dirty_ratio = 20
vm.dirty_expire_centisecs = 3000

Qué significa: Ajustes agresivos de páginas sucias pueden crear tormentas periódicas de flush y picos en la latencia cola.

Decisión: Si se introdujo un valor personalizado para “mejorar throughput”, verifica la latencia cola. Para sistemas sensibles a latencia, mantén valores conservadores a menos que puedas probar bajo fallo y ráfagas.

Tarea 8: Comprueba si estás haciendo swap (misterio de rendimiento resuelto)

cr0x@server:~$ free -h
               total        used        free      shared  buff/cache   available
Mem:           125Gi        92Gi        4.1Gi       1.2Gi        29Gi        21Gi
Swap:           16Gi       5.3Gi        11Gi

Qué significa: El uso de swap puede convertir el almacenamiento en un generador de latencia aleatoria.

Decisión: Si el swapping es no trivial en un servicio sensible a latencia, corrige la presión de memoria primero. No “afines el almacenamiento” para compensar la falta de RAM.

Tarea 9: Detecta errores de almacenamiento que se esconden como “problemas de rendimiento”

cr0x@server:~$ sudo dmesg -T | egrep -i "blk_update_request|nvme|scsi|reset|timeout|I/O error" | tail -n 8
[Tue Jan 21 09:44:12 2026] nvme nvme0: I/O 123 QID 4 timeout, aborting
[Tue Jan 21 09:44:12 2026] nvme nvme0: Abort status: 0x371
[Tue Jan 21 09:44:14 2026] nvme0n1: I/O Cmd(0x2) @ LBA 0x3c1a0, 8 blocks, I/O Error (sct 0x2 / sc 0x81)

Qué significa: Timeouts y abortos a menudo se presentan primero como picos de latencia y luego como errores.

Decisión: Deja de afinar. Escala la investigación de hardware/firmware, compara con el firmware de referencia y considera un reemplazo proactivo.

Tarea 10: Valida el estado de multipath (para setups SAN/iSCSI/FC)

cr0x@server:~$ sudo multipath -ll | sed -n '1,25p'
mpatha (3600508b400105e210000900000490000) dm-2 ACME,UltraSAN
size=2.0T features='1 queue_if_no_path' hwhandler='0' wp=rw
|-+- policy='service-time 0' prio=50 status=active
| `- 3:0:0:1 sdb 8:16 active ready running
`-+- policy='service-time 0' prio=10 status=enabled
  `- 4:0:0:1 sdc 8:32 active ready running

Qué significa: Si los caminos están fluctuando, verás latencia impredecible y reintentos.

Decisión: Si las políticas de multipath divergen de la referencia, revierte. Si un path está caído, arregla cableado/switch/HBA del host antes de tocar perillas de la aplicación.

Tarea 11: Mide la latencia a nivel de sistema de archivos bajo demanda

cr0x@server:~$ sudo ioping -c 10 -D /var/lib/data
4 KiB from /var/lib/data (ext4 /dev/nvme0n1p2): request=1 time=0.42 ms
4 KiB from /var/lib/data (ext4 /dev/nvme0n1p2): request=2 time=0.51 ms
...
--- /var/lib/data (ext4 /dev/nvme0n1p2) ioping statistics ---
10 requests completed in 9.01 s, 40 KiB read, 1.11 KiB/s
min/avg/max/mdev = 0.39 ms / 0.58 ms / 1.21 ms / 0.23 ms

Qué significa: Esto te da un chequeo rápido de “¿el almacenamiento está lento ahora?” a nivel de sistema de archivos.

Decisión: Si la latencia de ioping es alta mientras las estadísticas del dispositivo parecen bien, sospecha contención en el sistema de archivos, límites de cgroup I/O o problemas del backend de almacenamiento en red.

Tarea 12: Valida el patrón real de I/O con un benchmark controlado (con cuidado)

cr0x@server:~$ sudo fio --name=randread --directory=/var/lib/data --rw=randread --bs=4k --iodepth=32 --numjobs=4 --size=2G --runtime=30 --time_based --group_reporting
randread: (g=0): rw=randread, bs=(R) 4096B-4096B, (W) 4096B-4096B, ioengine=psync, iodepth=32
...
  read: IOPS=185k, BW=723MiB/s (758MB/s)(21.2GiB/30001msec)
    lat (usec): min=68, max=24890, avg=512.20, stdev=301.44
    clat percentiles (usec):
     |  1.00th=[  95], 50.00th=[ 480], 95.00th=[ 910], 99.00th=[1400], 99.90th=[3900]

Qué significa: Obtienes IOPS y percentiles de latencia, no solo velocidad media. Los percentiles son donde vive la producción.

Decisión: Si tu afinación personalizada mejora el promedio pero empeora p99/p99.9, suele ser una pérdida. Mantén la referencia a menos que estés construyendo solo para throughput por lotes.

Tarea 13: Comprueba errores NIC y retransmisiones (el almacenamiento sobre red lo adora)

cr0x@server:~$ ip -s link show dev eth0 | sed -n '1,12p'
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    RX:  bytes packets errors dropped  missed   mcast
    9876543210  1234567      0     12       0  12345
    TX:  bytes packets errors dropped carrier collsns
    8765432109  2345678      0      0       0       0

Qué significa: Las pérdidas en RX pueden traducirse directamente en latencia de almacenamiento en redes públicas NFS/iSCSI/Ceph.

Decisión: Si las pérdidas incrementan, deja de culpar la “afinación de almacenamiento”. Revisa la consistencia de MTU, buffers del switch y ajustes qdisc del host —preferir la configuración de red de referencia.

Tarea 14: Detecta throttling de CPU o tiempo steal en entornos virtualizados

cr0x@server:~$ mpstat -P ALL 1 2 | sed -n '1,18p'
Linux 6.5.0-21-generic (server) 	01/21/2026 	_x86_64_	(32 CPU)

12:03:21 PM  CPU   %usr  %nice   %sys %iowait  %irq  %soft  %steal  %idle
12:03:22 PM  all  14.22   0.00   4.55    7.91  0.00   0.28    3.40  69.64

Qué significa: %steal sugiere que tu VM no está siendo programada; la latencia de almacenamiento puede ser un síntoma, no la causa.

Decisión: Si el steal es no trivial, investiga la contención del host o mueve cargas. No afines almacenamiento para arreglar un problema de scheduler.

Tarea 15: Verifica propiedades de pool y dataset ZFS (si usas ZFS)

cr0x@server:~$ sudo zpool status -v
  pool: tank
 state: ONLINE
  scan: scrub repaired 0B in 00:12:31 with 0 errors on Tue Jan 21 02:00:10 2026
config:

        NAME        STATE     READ WRITE CKSUM
        tank        ONLINE       0     0     0
          raidz1-0  ONLINE       0     0     0
            sda     ONLINE       0     0     0
            sdb     ONLINE       0     0     0
            sdc     ONLINE       0     0     0

errors: No known data errors

Qué significa: Scrubs, errores y vdevs degradados importan más que cualquier “hack de recordsize”.

Decisión: Si ves errores o un estado degradado, prioriza la integridad de datos y la planificación de reconstrucción sobre la afinación de rendimiento.

Tarea 16: Comprueba settings de dataset ZFS que suelen “personalizarse” mal

cr0x@server:~$ sudo zfs get -o name,property,value -s local,received compression,recordsize,atime,sync tank/app
NAME      PROPERTY    VALUE
tank/app  compression zstd
tank/app  recordsize  128K
tank/app  atime       off
tank/app  sync        standard

Qué significa: Estas propiedades cambian la amplificación de escritura, la latencia y las semánticas de durabilidad.

Decisión: Si sync=disabled aparece en producción sin una razón clara y garantías de UPS/PLP, trátalo como un incidente esperando suceder. Revertir a referencia.

Chiste #2: “Lo afinamos para rendimiento pico” es como los ingenieros dicen “lo afinamos para sorpresa pico”.

Errores comunes: síntoma → causa raíz → solución

1) Síntoma: Gran throughput medio, latencia p99 terrible

Causa raíz: Incremento de profundidad de cola, cambio en el merge de solicitudes o ajustes de writeback que permiten grandes ráfagas que se vacían de forma impredecible.

Solución: Reduce la concurrencia hacia la capa de almacenamiento, restaura profundidades de cola de referencia, aplica SLOs de latencia y prueba bajo mezcla de lectura/escritura con trabajos en segundo plano.

2) Síntoma: Paradas aleatorias de varios segundos durante operación “normal”

Causa raíz: Tormentas de flush de páginas sucias, contención del journal del sistema de archivos o operaciones de reconstrucción/scrub en segundo plano que colisionan con carga pico.

Solución: Ajusta writeback de forma conservadora, programa ventanas de mantenimiento y mide el impacto de scrubs/rebuilds. Si la referencia incluye guía de mantenimiento, síguela.

3) Síntoma: El almacenamiento parece bien, pero las apps hacen timeout de todos modos

Causa raíz: Caídas/retransmisiones de red, retrasos en DNS, steal de CPU o contención a nivel de aplicación que se hace pasar por I/O.

Solución: Valida con iostat + estadísticas de red + mpstat; no asumas. Haz regla “pruébalo como almacenamiento” antes de cambiar ajustes de almacenamiento.

4) Síntoma: Tras una conmutación por error o flap de enlace, todo se derrite por minutos

Causa raíz: Exceso de I/O en vuelo debido a colas agresivas; timeouts y comportamientos de reintento no alineados con la referencia.

Solución: Restaura multipath y settings de timeout de referencia; realiza una prueba de conmutación por error controlada para medir el tiempo de brownout. Optimiza para la recuperación, no solo para estado estable.

5) Síntoma: El rendimiento degrada con semanas en SSD/NVMe

Causa raíz: Desgaste, comportamiento de GC del firmware, falta de estrategia TRIM/discard o sobrellenado de discos.

Solución: Mantén margen de utilización, alinea firmware con referencia, valida la estrategia de discard y monitorea latencia a medida que envejecen los discos.

6) Síntoma: “Era rápido en staging” se convierte en un refrán semanal

Causa raíz: Staging carece de concurrencia de producción, modos de fallo y tareas en segundo plano. La afinación personalizada se validó en un mundo de juguete.

Solución: Construye una prueba de carga parecida a producción, incluye backups/rebuilds y mide p99. Si no puedes, mantente cerca de la referencia.

7) Síntoma: El soporte se niega a ayudar o pide más logs

Causa raíz: Te desviaste de la referencia soportada (drivers, firmware, settings), por lo que tu issue no es reproducible en su laboratorio.

Solución: Vuelve a alinearte con la matriz de referencia; documenta cualquier desviación necesaria y cómo la validaste.

8) Síntoma: “Optimizamos” y luego las actualizaciones se volvieron aterradoras

Causa raíz: Perillas personalizadas fuertemente acopladas a un comportamiento específico del kernel/firmware; sin sobre de compatibilidad.

Solución: Reduce la superficie personalizada, codifica la configuración en IaC, añade canarios de upgrade y conserva un artefacto de rollback conocido bueno.

Listas de verificación / plan paso a paso

Lista A: Decidir si quedarse con la referencia

  1. Escribe el objetivo. ¿Latencia? ¿Throughput? ¿Costo? ¿Tiempo de recuperación? Sé preciso.
  2. Enumera las restricciones. Integridad de datos, cumplimiento, soporte, niveles de habilidad on-call.
  3. Mide la línea base en referencia. Captura latencias p50/p95/p99 y puntos de saturación.
  4. Inventario de deriva. Kernel, firmware, sysctls, opciones de montaje, drivers, settings de multipath.
  5. Estima el impuesto operativo. Dashboards extra, runbooks, tests, formación, riesgo de upgrades.
  6. Decide: copiar o bifurcar. Si no puedes financiar el impuesto, no bifurques.

Lista B: Si debes personalizar, hazlo como un adulto

  1. Un cambio a la vez. Trata cada desviación como un experimento con rollback.
  2. Define guardarraíles. Máximo p99 aceptable, máximo brownout en conmutación por error, máximo tiempo de rebuild.
  3. Prueba modos de fallo. Conmutación por error de controladora, flap de enlace, retirada de disco, reboot de nodo en carga.
  4. Canario en producción. Radio de blast pequeño, ruta de revert rápida, monitorización estrecha.
  5. Documenta el porqué. “Cambiamos X porque la métrica Y fallaba, y Z demuestra que mejoró.”
  6. Ensaya la reversión. Si la reversión necesita una reunión, no es una reversión.

Lista C: Mantener la “referencia” como referencia con el tiempo

  1. Fija el artefacto de referencia. Una ruta de repo, un bundle de configuración, una imagen golden firmada.
  2. Audita la deriva mensualmente. Compara ajustes en vivo con la línea base automáticamente.
  3. Controla firmware como código. Trata las actualizaciones de firmware como despliegues, con canarios.
  4. Mantén notas de upgrade. Cambios del kernel y del stack de almacenamiento deben trazarse como releases de app.
  5. Retira el folclore. Si una perilla de afinación no está justificada con datos actuales, elimínala.

Preguntas frecuentes

1) ¿Una arquitectura de referencia siempre es más lenta?

No. A menudo es “lo suficientemente rápida” y estable bajo carga y fallo. Muchos personalizados ganan en pruebas sintéticas y luego pierden por latencia cola y comportamiento de recuperación en producción.

2) ¿Por qué los proveedores recomiendan valores conservadores?

Porque los proveedores reciben la culpa por pérdida de datos e inestabilidad. Los valores conservadores suelen proteger la corrección, la interoperabilidad y la soportabilidad frente al mayor conjunto de errores de cliente.

3) Si tengo una carga muy específica, ¿no debería afinarla?

Sí, pero trata la afinación como ingeniería: mide, aísla variables, valida modos de fallo y presupuestiza el impuesto operativo. “Carga específica” no es licencia para improvisar.

4) ¿Cómo sé si me desvié de la referencia?

Compara versiones de kernel, firmware, sysctls, opciones de montaje, políticas de multipath y versiones de drivers con la línea base. Si no puedes listarlas, ya estás desviado.

5) ¿Cuál es la mayor señal de alarma en ajustes personalizados de almacenamiento?

Cualquier cambio que altere las semánticas de durabilidad sin una decisión explícita de producto: deshabilitar sync, debilitar ordering o confiar en cachés sin protección contra pérdida de energía.

6) No podemos reproducir el rendimiento de producción en staging. ¿Qué debemos hacer?

Asume que staging miente. Usa canarios en producción, captura percentiles de latencia detallados y prueba durante actividad de fondo realista. Mantente cerca de la referencia hasta poder medir de forma segura.

7) ¿Las configuraciones de referencia son inmunes a fallos?

Absolutamente no. Solo reducen las probabilidades de que tú causes el fallo con una elección de configuración evitable, y aceleran la depuración cuando la realidad sigue portándose mal.

8) ¿Cuánta personalización es “demasiada”?

Cuando el equipo ya no puede explicar el comportamiento de fallo del sistema ni recuperarlo de forma fiable. Un buen indicador es cuando los upgrades requieren a un héroe y un fin de semana.

9) ¿Y si la referencia está mal para nuestro hardware?

Entonces tu primer movimiento es alinear hardware/firmware con la matriz validada, o escoger una referencia que coincida con tu plataforma. No “afines alrededor” de componentes incompatibles.

10) ¿Podemos mezclar referencia y personalizado?

Sí. El enfoque sensato es “núcleo de referencia, perímetros personalizados”: mantiene el sustrato de almacenamiento y el comportamiento de fallo estándar, personaliza en el patrón de acceso de la aplicación y la capa de caché.

Conclusión: próximos pasos que puedes hacer

El mito no es que lo personalizado pueda vencer a la referencia. El mito es que lo personalizado vence automáticamente a la referencia, y que la victoria es puramente técnica. En producción, el rendimiento es política entre la carga de trabajo, el hardware, el kernel, la red y las personas de guardia.

Si estás decidiendo si personalizar, haz tres cosas esta semana:

  1. Escribe tu línea base de referencia (kernel, firmware, sysctls, opciones de montaje, ajustes de almacenamiento) y guárdala como un artefacto que tu equipo pueda diffear.
  2. Ejecuta los pasos de diagnóstico rápido en un día normal y captura números “normales”: latencia iostat, pérdidas, salud de multipath, uso de swap, p99 de fio en una caja canaria.
  3. Elige una desviación que estés usando y obliga a que se defienda: qué métrica mejora, qué modo de fallo empeora y cómo la revertirías a las 3 a.m.

Si la desviación no puede defenderse, bórrala. Los sistemas más fiables no son los que tienen más afinaciones. Son los que tienen menos sorpresas.

← Anterior
APT en Ubuntu 24.04 lento: trucos de caché/proxy para acelerar actualizaciones en oficinas
Siguiente →
Detección de desajuste de ashift en ZFS: Cómo comprobar pools existentes

Deja un comentario