AMD Opteron: Cómo los servidores abrieron la puerta VIP para AMD

¿Te fue útil?

Si alguna vez te has quedado mirando un panel donde la CPU parece “bien”, los discos parecen “bien” y aun así la aplicación va como si arrastrara un refrigerador cuesta arriba,
ya entiendes por qué Opteron importó. No fue simplemente “otro CPU”. Fue AMD entrando a la sala de servidores—donde los presupuestos son reales y
las excusas no—y entregando a los administradores un conjunto de perillas que realmente movían la aguja.

Opteron no ganó por ser simpático. Ganó porque hizo que el sistema se comportara: la latencia de memoria cayó, el escalado multi-socket dejó de ser
un proyecto de laboratorio y el 64 bits llegó sin obligar a la industria a quemar su pila de software.

La puerta VIP: por qué los servidores eran la única sala que importaba

Los consumidores compran CPUs por sensaciones y benchmarks. Las empresas las compran por resultados: latencia predecible, escalado estable y la capacidad
de actualizar sin reescribir una década de software. Por eso el mercado de servidores es la puerta VIP. Una vez que te ganan la confianza en producción, tu logo migra
de “interesante” a “proveedor aprobado”. Y “proveedor aprobado” es donde está el dinero.

A principios de los 2000, Intel dominaba la narrativa en servidores. “Xeon” significaba seguro. “Itanium” se posicionaba como el futuro. AMD era la alternativa
contestataria—a menudo excelente, a veces ignorada, rara vez invitada a la mesa grande. Opteron cambió la geometría social.

La clave es que Opteron no solo intentó vencer a Intel en potencia bruta de CPU. Atacó el rendimiento del sistema donde las cargas reales sufren:
ancho de banda de memoria, latencia de memoria, coherencia multi-socket y compatibilidad de actualización. El resultado no fue simplemente “más rápido”.
El resultado fueron menos sorpresas feas a las 2 a.m.

Hechos históricos que explican el cambio (sin mitología)

  • Opteron se lanzó en 2003, y trajo x86-64 (AMD64) a los servidores manteniendo el software de 32 bits funcionando.
  • Intel apostó inicialmente por Itanium (EPIC/IA-64) para la computación empresarial de 64 bits, esperando que x86 desapareciera en servidores de alta gama.
  • El controlador de memoria integrado de AMD sacó el acceso a memoria del northbridge, reduciendo latencia y aumentando ancho de banda en cargas reales.
  • HyperTransport reemplazó al antiguo front-side bus para los enlaces CPU-CPU y CPU-chipset, ayudando al escalado multi-socket.
  • Las distribuciones Linux adoptaron AMD64 temprano, y eso importó: los equipos de ops pudieron probar y desplegar sin esperar ecosistemas propietarios.
  • Grandes OEMs enviaron servidores Opteron—la señal de adquisición de que “esto no es un proyecto de feria de ciencias”.
  • La virtualización obtuvo una pista práctica: incluso antes de que maduraran las extensiones de virtualización por hardware, AMD64 facilitó el espacio de direcciones y la consolidación.
  • NUMA dejó de ser teórico: los servidores x86 multi-socket se convirtieron claramente en NUMA, y el software tuvo que admitirlo.
  • Intel adoptó más tarde esencialmente el mismo modelo de 64 bits (Intel 64/EM64T), validando la estrategia de AMD: evolucionar x86, no reemplazarlo.

Qué cambió Opteron técnicamente—y por qué a los operadores les importó

1) El controlador de memoria integrado: menos capas entre tú y la RAM

En el viejo mundo del front-side bus (FSB) compartido, las CPUs eran como compañeros de piso que comparten un pasillo estrecho hacia la cocina. Todos podían cocinar.
Simplemente no al mismo tiempo. Opteron puso la cocina dentro de cada paquete de CPU al integrar el controlador de memoria. Cada socket tenía su propio
camino directo a la RAM.

Para los operadores, esto se manifestó como algo que se puede notar:

  • Menor latencia de memoria bajo carga—menos rarezas de latencia cola en bases de datos y cargas JVM.
  • Escalado más predecible al añadir sockets, porque el ancho de banda de memoria escalaba de forma más lineal (con matices, por NUMA).
  • Mejor rendimiento “real” en cargas que parecen modestas en utilización de CPU pero que en secreto están limitadas por memoria.

El controlador de memoria integrado también forzó un cambio cultural: ya no puedes fingir que la memoria es “uniforme”. Si un hilo en el socket 0
está machacando memoria adjunta al socket 1, eso no es “solo RAM”. Es una penalización por acceso remoto, y se muestra como latencia.

2) HyperTransport: escalado que no requería rezos

HyperTransport le dio a Opteron un interconector punto a punto de alta velocidad. En lugar de que todas las CPUs pelearan por un bus compartido, los sockets podían
comunicarse más directamente, y el tráfico de coherencia tenía a dónde ir además de “gritar más fuerte en el FSB”.

Esto importó para dos problemas clásicos de la empresa:

  • Escalado multi-socket sin chocar inmediatamente con un muro de bus compartido.
  • Rutas de E/S que no colapsaban bajo cargas mixtas (red + almacenamiento + presión de memoria) tan rápido como los diseños anteriores.

3) x86-64 como estrategia de compatibilidad, no como prueba de pureza

AMD64 funcionó porque no pidió al mundo tirar su software. Esa es la genialidad silenciosa. El 64 bits no se vendió como “una nueva religión”.
Se vendió como “tu cosa existente todavía funciona, y ahora puedes direccionar más memoria sin perder el fin de semana”.

Eso no es relleno de marketing. Es aritmética operacional. Las empresas no actualizan con un interruptor. Actualizan mediante pilotos, validación,
migraciones y planes de reversión. AMD64 encajó en esa realidad.

4) NUMA se convierte en el impuesto que debes declarar

NUMA no es opcional en servidores multi-socket de la era Opteron. O lo entiendes, o pagas intereses después. El acceso local a memoria es más rápido.
El acceso remoto a memoria es más lento. El ancho de banda no es infinito. La coherencia de caché no es gratuita. Y tu base de datos no le importa la diapositiva del proveedor.

Si aprendiste un hábito gracias a Opteron, debería ser este: siempre pregunta, “¿Dónde está la memoria respecto a la CPU que realiza el trabajo?”

AMD64 vs Itanium: la bifurcación en el camino

Itanium fue la senda de la “nueva arquitectura”: una ruptura limpia, una gran promesa y un gran requisito—portar tu software. AMD64 fue la senda de “seguir avanzando”:
extender x86, mantener compatibilidad, llegar a 64 bits sin detonar tu ecosistema.

Si manejas sistemas en producción, sabes cómo termina esta película. La plataforma que pide menos reescrituras gana, asumiendo que el rendimiento es suficientemente bueno
y las herramientas no son un desastre. AMD64 alcanzó ese punto dulce.

Hay un ángulo de fiabilidad también. Las nuevas arquitecturas introducen nuevos comportamientos de compiladores, nuevos casos límite en librerías, nuevos precipicios de rendimiento
y nuevos bugs de “esto funcionaba en la plataforma antigua”. Parte de eso es inevitable. Pero multiplicarlo por toda una flota es cómo creas una carrera en respuesta a incidentes.

Un chiste, porque nos lo hemos ganado: Itanium era el tipo de “futuro” que siempre llegaba justo después de la próxima ventana de mantenimiento.

NUMA: la característica que pagó la renta y causó peleas

NUMA es un amigo de dos caras. Cuando alineas cómputo con memoria local, el rendimiento es hermoso. Cuando no lo haces, obtienes jitter que parece
bugs de aplicación, pero en realidad es el hardware recordándote que existe.

Opteron hizo que NUMA fuera corriente principal en las salas de servidores x86. Forzó a desarrolladores y operadores a tomarse en serio la afinidad: pinning de CPU,
política de memoria, colocación de IRQ y distribución de interrupciones.

El truco no es “tunear todo”. El truco es tunear la una o dos cosas que realmente te están limitando: localidad de memoria, interrupciones de E/S y
comportamiento del scheduler bajo contención.

Una idea de fiabilidad parafraseada, porque sigue siendo cierta: Idea parafraseada — John Ousterhout: mide primero; la mayoría de las mejoras de rendimiento y fiabilidad provienen de arreglar el verdadero cuello de botella, no de adivinar.

Tres micro-historias corporativas desde las trincheras

Micro-historia #1: El incidente causado por una suposición equivocada

Una empresa mediana ejecutaba un sistema de facturación sensible a la latencia en servidores dual-socket. El equipo migró desde una plataforma Xeon antigua a
máquinas basadas en Opteron porque la relación precio/rendimiento era fantástica y el proveedor prometía “drop-in fácil”.

La migración fue suave hasta el cierre de fin de mes. De repente, la latencia de la API se duplicó y la base de datos empezó a registrar paradas intermitentes.
La utilización de CPU se mantuvo en torno al 40–50%. Los gráficos de almacenamiento parecían tranquilos. Todos culparon a la aplicación.

La suposición equivocada: “Memoria es memoria; si hay suficiente, no importa dónde viva”. En Opteron, importaba absolutamente.
El proceso de BD tenía hilos rebotando entre sockets mientras sus páginas de memoria más calientes se asignaban mayormente en un nodo. El tráfico de memoria remota
subió, la latencia siguió y la carga cayó en un mal bucle de retroalimentación: consultas más lentas mantenían bloqueos por más tiempo, aumentando la contención,
aumentando el ping-pong de líneas de caché.

La solución no fue exótica. Fijaron los hilos trabajadores de la BD a núcleos, hicieron cumplir la asignación de memoria consciente de NUMA (o al menos la intercalaron para esa carga),
y movieron las IRQ del NIC fuera del nodo ocupado. La latencia volvió a la normalidad y la “regresión de la aplicación” desapareció como si nunca hubiera existido.

La lección: En NUMA, “RAM suficiente” no es lo mismo que “RAM rápida”. Trata la localidad como una métrica de primera clase.

Micro-historia #2: La optimización que salió mal

Otra compañía ejecutaba un clúster de virtualización con una mezcla de cargas web y batch. Descubrieron que desactivar ciertas funciones de gestión de energía hacía que los números de benchmark se vieran mejor.
El equipo aplicó el cambio en toda la flota: modo rendimiento en todas partes, todo el tiempo.

Inicialmente, los gráficos se veían genial. Menor latencia. Mayor throughput. Hubo celebraciones. Luego llegó el verano, junto con una serie de eventos de estrangulamiento térmico y fallos de ventiladores.
El presupuesto de refrigeración del centro de datos no era infinito y los racks ya eran densos.

Bajo calor sostenido, algunos nodos empezaron a reducir frecuencia de forma impredecible. Esa impredecibilidad importó más que la ganancia media de rendimiento.
El scheduler de virtualización persiguió la carga, las VMs migraron en momentos inoportunos y el clúster desarrolló una nueva personalidad: ocasionalmente rápido, frecuentemente gruñón.

Revirtieron a una política equilibrada, usaron ajustes de rendimiento por host solo para niveles de latencia específicos y añadieron alertas de monitorización térmica
vinculadas a señales reales de estrangulamiento en lugar de “la temperatura ambiente parece alta”.

La lección: una optimización que ignora potencia y térmica es solo deuda técnica con una curva de ventilador.

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

Un equipo de servicios financieros ejecutó servidores Opteron durante años. Nada glamoroso. Principalmente bases de datos y colas de mensajes. Su arma secreta no fue un parche de kernel exótico ni una sesión de tuning heroica.
Fue el establecimiento disciplinado de baselines.

Cada trimestre, capturaban una instantánea “conocida como buena” de telemetría de hardware y SO: disposición NUMA, distribución de IRQ, ancho de banda de memoria bajo una prueba estándar,
latencia de almacenamiento bajo una carga controlada y un perfil de rendimiento de los servicios principales. Lo almacenaban con la misma seriedad que las copias de seguridad.

Un día, una actualización de firmware cambió silenciosamente el comportamiento de intercalado de memoria. El sistema todavía arrancaba. No hubo alarmas. Pero su comparación con la baseline
detectó un aumento significativo en accesos remotos a memoria y una caída medible en el ancho de banda de memoria. Antes de que los usuarios lo notaran, pausaron el despliegue,
abrieron un caso con el proveedor y fijaron la versión de firmware para esa generación de hardware.

La solución fue sencilla: ajustar las opciones de firmware para coincidir con el comportamiento anterior y validar con las mismas pruebas de baseline. Sin incidente.
Sin sala de guerra. Solo un ticket aburrido y un registro de cambios limpio.

La lección: las prácticas aburridas vencen a las heroicidades excitantes. Las baselines convierten “regresiones misteriosas” en “deltas conocidos”.

Guía de diagnóstico rápido: encuentra el cuello de botella rápidamente

Este es el orden que uso cuando un servidor “se siente lento” y la culpa se pasa como una papa caliente. Está afinado para realidades de la era Opteron (NUMA, controladores de memoria por socket, escalado multi-socket),
pero aún aplica a sistemas modernos.

Primero: confirma qué tipo de lentitud tienes

  • ¿Pico de latencia? Busca retrasos de planificación, memoria remota, contención de locks, tormentas de IRQ.
  • ¿Caída de throughput? Busca saturación de ancho de banda de memoria, profundidad de colas de E/S, estrangulamiento térmico o un core caliente único.
  • ¿Solo bajo concurrencia? Sospecha colocación NUMA, rebote de líneas de caché o contención de recursos compartidos.

Segundo: CPU vs memoria vs E/S en 10 minutos

  1. Presión de planificación de CPU: ejecuta vmstat 1 y revisa la cola de ejecución, switches de contexto y steal time.
  2. Localidad de memoria: revisa estadísticos NUMA con numastat y disposición CPU/nodo con lscpu.
  3. Espera y latencia de E/S: ejecuta iostat -x 1 y observa await, svctm (si está presente) y la utilización.
  4. Red: revisa drops y overruns con ip -s link y la distribución de interrupciones.

Tercero: valida el gráfico “obvio” con una herramienta de verdad

  • Contadores de perf: perf stat y perf top para CPI, fallos de caché y funciones calientes.
  • Vista del kernel: pidstat, sar, dmesg para estrangulamientos y quejas de drivers.
  • Colocación: taskset, numactl, /proc/interrupts para ver si accidentalmente creaste un impuesto cross-socket.

Tareas prácticas: comandos, significado de la salida y la decisión que tomas

Estas son las comprobaciones que realmente ejecuto. Cada tarea incluye: un comando ejecutable, una salida de ejemplo, qué significa y qué decisión sigue.
Asume Linux en metal o una VM con suficiente visibilidad.

Tarea 1: Identificar modelo de CPU y topología de cores

cr0x@server:~$ lscpu
Architecture:        x86_64
CPU(s):              16
Thread(s) per core:  1
Core(s) per socket:  8
Socket(s):           2
NUMA node(s):        2
Vendor ID:           AuthenticAMD
Model name:          AMD Opteron(tm) Processor 285
NUMA node0 CPU(s):   0-7
NUMA node1 CPU(s):   8-15

Significado: Dos sockets, dos nodos NUMA. Cualquier planificación “aleatoria” puede crear acceso remoto a memoria.

Decisión: Para servicios sensibles a la latencia, planifica pinning de CPU o despliegue consciente de NUMA (una instancia por socket, si es factible).

Tarea 2: Confirmar distancias NUMA (qué tan caro es realmente “remoto”)

cr0x@server:~$ numactl --hardware
available: 2 nodes (0-1)
node 0 cpus: 0 1 2 3 4 5 6 7
node 0 size: 16384 MB
node 0 free: 12210 MB
node 1 cpus: 8 9 10 11 12 13 14 15
node 1 size: 16384 MB
node 1 free: 12044 MB
node distances:
node   0   1
  0   10  20
  1   20  10

Significado: El acceso a nodo remoto cuesta ~2x en distancia relativa. Eso no es sutil.

Decisión: Si ves alto tráfico remoto más tarde, trátalo como causa principal de incidente, no como “ruido”.

Tarea 3: Comprobar si el kernel usa NUMA balancing (y si deberías preocuparte)

cr0x@server:~$ sysctl kernel.numa_balancing
kernel.numa_balancing = 1

Significado: El balanceo NUMA automático está habilitado. Puede ayudar, o puede crear churn de migración de páginas.

Decisión: Para cargas de base de datos en steady-state, prueba con ello activado/desactivado en staging. Si ves migraciones y jitter, considera deshabilitar y fijar.

Tarea 4: Detectar presión en la cola de ejecución y actividad de swap rápidamente

cr0x@server:~$ vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 2  0      0 122100  81200 945000    0    0     1     5  310  540 18  4 76  2  0
 8  0      0 121880  81200 945120    0    0     0     0  900 1800 55 10 33  2  0
 9  0      0 121700  81200 945200    0    0     0    16  920 1900 58 12 28  2  0
 3  1      0 121500  81200 945210    0    0   120     0  600 1200 20  6 68  6  0
 2  0      0 121480  81200 945240    0    0     0     0  330  560 16  4 78  2  0

Significado: La columna r picos (8–9) indica tareas ejecutables excediendo la capacidad de CPU. wa es baja, swap es cero.

Decisión: Esto es presión de planificación de CPU, no disco. Investiga hilos calientes, afinidad o contención de locks.

Tarea 5: Identificar si estás limitado por CPU o por memoria (rápido y sucio)

cr0x@server:~$ perf stat -a -- sleep 5
 Performance counter stats for 'system wide':

       18,245.12 msec task-clock                #    3.649 CPUs utilized
   12,345,678,901      cycles                    #    0.677 GHz
    9,876,543,210      instructions              #    0.80  insn per cycle
    1,234,567,890      cache-references
      456,789,012      cache-misses              #   36.99% of all cache refs

       5.001234567 seconds time elapsed

Significado: IPC alrededor de 0.8 y alta tasa de fallos de caché sugiere stalls—a menudo latencia/ancho de banda de memoria, no puro cómputo.

Decisión: Revisa localidad NUMA y presión de ancho de banda de memoria antes de comprar “más CPU”.

Tarea 6: Comprobar asignaciones remotas vs locales de memoria por proceso (verificación NUMA)

cr0x@server:~$ numastat -p 1234
Per-node process memory usage (in MBs) for PID 1234 (postgres)
         Node 0  Node 1   Total
Private    8200     900    9100
Heap        600    4200    4800
Stack        20      18      38
Huge         0       0       0
Total     8820    5118   13938

Significado: La memoria está distribuida de forma desigual; si los hilos de CPU están principalmente en el nodo 0 pero el heap es pesado en el nodo 1,
espera penalizaciones por acceso remoto.

Decisión: Fija el proceso o usa políticas de numactl; considera ejecutar una instancia por socket para localidad predecible.

Tarea 7: Inspeccionar afinidad de CPU de un proceso (¿dejas que el scheduler haga de freeload?)

cr0x@server:~$ taskset -pc 1234
pid 1234's current affinity list: 0-15

Significado: El proceso puede ejecutarse en cualquier núcleo, aumentando la probabilidad de rebotes entre nodos.

Decisión: Para servicios de cola de latencia, restringe a un nodo NUMA (p. ej., CPUs 0–7) y mantiene la memoria local.

Tarea 8: Revisar latencia de dispositivo de almacenamiento y comportamiento de colas

cr0x@server:~$ iostat -x 1 3
Device            r/s     w/s   rkB/s   wkB/s  await  svctm  %util
sda              45.0    12.0   820.0   140.0   4.20   0.90  52.0
md0               0.0     0.0     0.0     0.0   0.00   0.00   0.0
nvme0n1         500.0   300.0 64000.0 32000.0   0.45   0.10  78.0

Significado: await es la latencia vista por las solicitudes. Alto %util con await en aumento apunta a saturación.

Decisión: Si await sube bajo carga, reduce I/O aleatorio, aumenta caché o mueve datos calientes—no culpes a la CPU.

Tarea 9: Verificar síntomas de latencia a nivel de sistema de ficheros (¿estás bloqueado en escrituras?)

cr0x@server:~$ pidstat -d 1 3 -p 1234
Linux 5.15.0 (server)  01/09/2026  _x86_64_  (16 CPU)

12:00:01 PM   UID       PID   kB_rd/s   kB_wr/s kB_ccwr/s iodelay  Command
12:00:02 PM  1001      1234      0.00   4200.00      0.00      18  postgres
12:00:03 PM  1001      1234      0.00   3900.00      0.00      22  postgres
12:00:04 PM  1001      1234      0.00   4100.00      0.00      20  postgres

Significado: iodelay en aumento indica tiempo bloqueado en E/S (contabilidad del kernel). Es una evidencia clara cuando la CPU parece inactiva.

Decisión: Investiga amplificación de escrituras, frecuencia de fsync, caché de RAID o saturación del backend de almacenamiento.

Tarea 10: Comprobar drops y errores de red (porque “la CPU está bien” aún puede ser red)

cr0x@server:~$ ip -s link show dev eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
    link/ether 00:11:22:33:44:55 brd ff:ff:ff:ff:ff:ff
    RX:  bytes packets errors dropped  missed   mcast
      987654321  1234567      0     842       0       0
    TX:  bytes packets errors dropped carrier collsns
      876543210  1122334      0       9       0       0

Significado: Drops en RX (842) no son “cosméticos”. Pueden provocar retransmisiones y picos de latencia.

Decisión: Revisa buffers de anillo, afinidad de IRQ y congestión; considera habilitar tuning RSS apropiado para la NIC.

Tarea 11: Inspeccionar distribución de interrupciones (modo clásico de fallo multi-socket)

cr0x@server:~$ cat /proc/interrupts | head -n 12
           CPU0       CPU1       CPU2       CPU3       CPU4       CPU5       CPU6       CPU7
  24:   9876543          0          0          0          0          0          0          0  IO-APIC   24-fasteoi   eth0
  25:      1200       1100       1150       1080       1120       1090       1110       1070  IO-APIC   25-fasteoi   nvme0q0
NMI:        120        118        121        119        117        120        122        118  Non-maskable interrupts

Significado: Las interrupciones de eth0 están fijadas solo a CPU0. Eso puede crear un cuello de botella de red y robar ciclos del lugar equivocado.

Decisión: Rebalancea IRQs (irqbalance o smp_affinity manual) y mantén las interrupciones NIC en el mismo nodo NUMA que la carga.

Tarea 12: Detectar estrangulamiento de frecuencia de CPU / problemas térmicos

cr0x@server:~$ dmesg -T | egrep -i "thrott|thermal|clock"
[Thu Jan  9 11:58:12 2026] CPU0: Core temperature above threshold, cpu clock throttled
[Thu Jan  9 11:58:15 2026] CPU0: Core temperature/speed normal

Significado: La CPU se está protegiendo. Tus “picos aleatorios de latencia” podrían ser física, no software.

Decisión: Arregla flujo de aire, curvas de ventiladores, disipadores o política de energía; no tunées la app para compensar una caja caliente.

Tarea 13: Confirmar uso de huge pages (buen siervo, mal maestro)

cr0x@server:~$ grep -i huge /proc/meminfo
AnonHugePages:    1048576 kB
HugePages_Total:     2048
HugePages_Free:       512
HugePages_Rsvd:       128
Hugepagesize:       2048 kB

Significado: Huge pages están en uso. Eso puede mejorar el comportamiento de TLB pero complicar la asignación de memoria y la colocación NUMA.

Decisión: Si aparecen fallos de asignación o uso desigual por nodo, ajusta la reserva de huge pages por nodo NUMA o reviértelo para esa carga.

Tarea 14: Comprobar presión de ancho de banda de memoria (proxy práctico)

cr0x@server:~$ sar -B 1 3
Linux 5.15.0 (server)  01/09/2026  _x86_64_  (16 CPU)

12:01:01 PM  pgpgin/s pgpgout/s   fault/s  majflt/s  pgfree/s pgscank/s pgscand/s pgsteal/s    %vmeff
12:01:02 PM      0.00    850.00  22000.00      0.00  48000.00      0.00      0.00      0.00      0.00
12:01:03 PM      0.00    920.00  24000.00      0.00  49000.00      0.00      0.00      0.00      0.00
12:01:04 PM      0.00    870.00  23000.00      0.00  47500.00      0.00      0.00      0.00      0.00

Significado: Muchas faltas de página (menores) sin faltas mayores sugiere churn de memoria pero no necesariamente paginación a disco. Puede correlacionar con estrés de ancho de banda de memoria.

Decisión: Si la latencia se correlaciona con picos aquí, perfila asignaciones, reduce churn y valida localidad NUMA—especialmente para JVMs y caches de BD.

Segundo chiste, porque todos necesitamos uno: NUMA es como la ubicación de los asientos en la oficina—pon al equipo cerca del pizarrón, o disfruta largas reuniones sobre “latencia de comunicación”.

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

1) Síntoma: La CPU “no está alta”, pero la latencia es horrible

Causa raíz: Stalls de memoria (acceso NUMA remoto, fallos de caché) o contención de locks; la utilización de CPU engaña por omisión.

Solución: Usa perf stat para IPC/fallos, numastat para localidad, luego fija hilos y aplica políticas de memoria NUMA.

2) Síntoma: Añadir un segundo socket no mejoró el throughput

Causa raíz: La carga es single-threaded, está serializada en un lock o está limitada por el ancho de banda de memoria de un nodo NUMA.

Solución: Perfila hotspots; divide en múltiples procesos independientes fijados por socket; asegura que las asignaciones de memoria sean locales por instancia.

3) Síntoma: El throughput de red se queda por debajo del enlace y aparecen drops

Causa raíz: IRQs fijadas a un núcleo, configuración RSS pobre o valores por defecto de driver inadecuados para cargas altas de PPS.

Solución: Distribuye IRQs entre núcleos en el nodo NUMA correcto; valida con /proc/interrupts y contadores de drops.

4) Síntoma: Picos de latencia en almacenamiento durante trabajos “intensos en CPU”

Causa raíz: Interrupciones de finalización de I/O y contención en ksoftirqd; la ruta de almacenamiento compite con cómputo en los mismos núcleos.

Solución: Separa núcleos para IRQs; aísla CPUs para niveles de latencia; confirma con pidstat -d y iostat -x.

5) Síntoma: Lentos aleatorios después de cambios de firmware/BIOS

Causa raíz: Cambió intercalado de memoria, C-states o política de energía; el comportamiento NUMA cambió sutilmente.

Solución: Compara baselines (distancias NUMA, pruebas de ancho de banda de memoria, contadores perf). Restaura o estandariza configuraciones en toda la flota.

6) Síntoma: Host de virtualización es inestable, las VMs migran “demasiado”

Causa raíz: Overcommit + colocación sin conciencia NUMA; las VMs abarcan nodos e incurren en penalizaciones de memoria remota.

Solución: Mantén vCPUs y memoria de VM dentro de un nodo cuando sea posible; usa pools por nodo NUMA; valida con métricas de host e invitado.

Listas de verificación / plan paso a paso

Checklist A: Al comprar o heredar servidores de la era Opteron (o cualquier caja NUMA)

  1. Confirma sockets/nodos NUMA con lscpu y numactl --hardware.
  2. Estandariza ajustes de BIOS: política de intercalado de memoria, política de energía, opciones de virtualización y cualquier opción del interconector de nodos.
  3. Establece una baseline: perf stat en idle y bajo una carga controlada, más iostat -x y ip -s link.
  4. Documenta la distribución de IRQ en un host conocido como bueno (snapshot de /proc/interrupts).
  5. Elige una estrategia NUMA por carga: “pin por socket”, “intercalar memoria” o “dejar que el balanceo lo haga” (solo después de probar).

Checklist B: Cuando un servicio se vuelve lento tras migrar a nuevo hardware

  1. Confirma relojes/estrangulamiento con dmesg y herramientas de frecuencia de CPU (si están disponibles).
  2. Revisa cola de ejecución y espera de E/S: vmstat 1, luego iostat -x 1.
  3. Valida localidad NUMA: numastat -p para el proceso y afinidad de CPU con taskset -pc.
  4. Revisa hotspots de IRQ: cat /proc/interrupts, luego correlaciona con drops de red/almacenamiento.
  5. Sólo entonces tunear la aplicación—porque el mal posicionamiento de hardware puede imitar regresiones de software perfectamente.

Checklist C: Un plan de tuning sensato (no te tunées hacia un rincón)

  1. Mide: captura 10 minutos de vmstat, iostat y perf stat alrededor del problema.
  2. Haz un cambio a la vez (pinning, afinidad de IRQ, política de memoria) y vuelve a medir.
  3. Prefiere cambios reversibles (overrides de systemd, wrappers de servicio) sobre “sopa misteriosa de sysctl”.
  4. Escribe la racionalidad. El tú del futuro es otra persona con menos paciencia.

Preguntas frecuentes

1) ¿La principal ventaja de Opteron fue solo “64 bits”?

No. El 64 bits importó, pero el diseño a nivel de sistema de Opteron—controlador de memoria integrado e interconexión multi-socket mejor—entregó rendimiento tangible y
predictibilidad para cargas reales.

2) ¿Por qué los controladores de memoria integrados cambiaron tanto el rendimiento de servidores?

Reducen la latencia de memoria y eliminan un cuello de botella compartido (northbridge/FSB). Para bases de datos, middleware y hosts de virtualización,
el comportamiento de la memoria a menudo domina la percepción de rendimiento.

3) ¿Cuál es el modo de fallo más común de ops en la era Opteron?

Ignorar NUMA: cargas corriendo en un socket mientras la memoria se asigna en otro, produciendo penalizaciones de acceso remoto y jitter que parecen
“lentitud aleatoria”.

4) ¿Debería fijar siempre procesos a un nodo NUMA?

No siempre. El pinning puede ayudar a cargas sensibles a la latencia y estables. Puede perjudicar cargas bursti o muy mixtas si las restricciones las constriñen.
Prueba con carga similar a producción y vigila la latencia en cola, no solo los promedios.

5) ¿Cómo sé si estoy limitado por memoria sin herramientas sofisticadas?

Busca IPC bajo en perf stat, altas tasas de fallos de caché y síntomas donde la utilización de CPU no esté alta pero el throughput no aumente.
Luego valida localidad NUMA con numastat.

6) ¿Por qué AMD64 venció a Itanium en el mercado?

Compatibilidad. AMD64 permitió a las empresas moverse a 64 bits sin reescribir todo. Itanium requería ports e introducía fricción en el ecosistema.
En la empresa, la fricción es un centro de costo.

7) ¿Todo esto importa en CPUs modernas?

Sí. Las plataformas modernas siguen teniendo NUMA, múltiples canales de memoria, interconexiones complejas y problemas de localidad de IRQ/CPU. Las etiquetas cambiaron.
La física no.

8) ¿Cuál es la comprobación más rápida “¿es CPU o E/S?”?

vmstat 1 más iostat -x 1. Si wa y await suben, sospecha almacenamiento. Si la cola de ejecución sube y wa es baja,
sospecha planificación de CPU, locks o stalls de memoria.

9) ¿Puede la virtualización ocultar problemas NUMA?

Puede ocultar la causa mientras amplifica los síntomas. Si una VM abarca nodos, el acceso remoto a memoria se vuelve “jitter misterioso”. Prefiere dimensionado y colocación
de VM alineados con NUMA.

Conclusión: próximos pasos que realmente puedes hacer

Opteron abrió la puerta VIP para AMD al resolver los problemas que a los operadores ya les pagaban por resolver: escalado, comportamiento de memoria, compatibilidad y rendimiento predecible bajo carga.
La lección no es nostalgia. La lección es alfabetización arquitectónica: si no entiendes dónde vive el cuello de botella, optimizarás con confianza lo equivocado.

Pasos siguientes:

  1. En un host con carga parecida a producción, captura una baseline: lscpu, numactl --hardware, vmstat, iostat -x, ip -s link, /proc/interrupts.
  2. Elige un servicio crítico y valida localidad NUMA con numastat -p más afinidad de CPU con taskset.
  3. Arregla la desalineación más grande primero (normalmente distribución de IRQ o localidad de memoria), luego vuelve a medir. Si los gráficos no se mueven, no resolviste el cuello de botella.
  4. Escribe cómo se ve “bien” para esa generación de hardware. El día que lo necesites será el día en que no tengas tiempo para recrearlo.
← Anterior
MariaDB vs RDS MariaDB: ¿Cuál provoca menos sorpresas extrañas de compatibilidad?
Siguiente →
Debian 13: la red no se activa tras reinicio — lista de verificación sin florituras para systemd-networkd

Deja un comentario