CPU NUMA: Cuando el procesador también tiene barrios

Aprende qué son los nodos NUMA en SQL Server, cómo afectan al rendimiento y qué errores evitar al configurarlos en físico, virtual y Azure.

Hay palabras que, al oírlas, nos ponen en guardia. “NUMA” es una de ellas. No porque suene peligrosa, sino porque suele venir envuelta en conceptos vagos y soluciones mágicas a problemas que no entendemos del todo. Pero no nos engañemos: si administramos SQL Server sobre hardware serio (y no sobre portátiles reciclados con Docker “porque mola”), entender cómo se comporta la arquitectura NUMA no es opcional. Es imprescindible.

¿Qué es NUMA? Una ciudad con barrios.

NUMA (Non-Uniform Memory Access) es una arquitectura de memoria en la que cada CPU (o grupo de CPUs) tiene acceso preferente a un bloque de memoria. A este conjunto se le llama nodo NUMA. Sí, se puede acceder a la memoria de otros nodos, pero es más lento. Y en un mundo donde las latencias de microsegundos importan más que los deadlines de los Project Managers, eso no es un detalle menor.

Puede parecer lioso pero vamos a verlo en una imagen para que no haya dudas. Realmente todo esto no es algo abstracto, viene directamente definido a nivel hardware. Las placas base de los servidores tienen varios socket de procesadores y, cada uno de ellos, tiene unos slots de RAM más cercanos a los que accede con menor latencia.

Aquí, por ejemplo, vemos dos sockets físicos, cada uno con 8 núcleos y 128 GB de RAM. Cada socket está conectado a su propia porción de memoria. Esto es lo que llamamos una arquitectura NUMA: cada CPU accede más rápido a su “propia” memoria que a la del otro socket. Y sí, como os decía, un procesador puede acceder a la memoria del otro, pero con más latencia. Cómo cruzar la ciudad para ir al mercadona de otro barrio teniendo uno en el tuyo, se puede, pero no es lo ideal.

SQL Server es plenamente NUMA-aware desde hace muchas versiones. Y no es solo marketing. El motor entiende esta arquitectura y la usa para optimizar la asignación de memoria, la ejecución de tareas en paralelo y la gestión de schedulers. Todo esto siempre y cuando no le pongamos la zancadilla con configuraciones absurdas.

Planificación y schedulers: cómo SQL Server reparte el trabajo

Cada nodo NUMA tiene un conjunto de schedulers, que no son otra cosa que planificadores de hilos (threads). Para ser lo más eficiente posible, SQL Server intenta ejecutar los hilos en el mismo nodo donde se asignaron, y acceder a la memoria local del mismo. Si la información está bien distribuida, esto reduce el tráfico entre nodos y mejora la latencia general. Pero si metemos la pata, por ejemplo fijando la afinidad de forma manual y sin criterio, podemos forzar al motor a comportarse como un repartidor de pizzas desorientado: yendo de un barrio a otro sin sentido y perdiendo tiempo en cada esquina.

Además, cada instancia de SQL Server crea un grupo de trabajo por cada nodo NUMA visible. Y si usamos el modo de memoria comprimida, las decisiones de qué nodo usa qué buffer pool se vuelven aún más relevantes. Ignorar esto es como jugar al ajedrez sin mirar el tablero. Puede parecer divertido, pero termina mal.

El efecto de un mal diseño NUMA

Cuando un servidor tiene múltiples sockets físicos, es muy probable que cada socket represente un nodo NUMA. Pero algunos sistemas operativos y BIOS permiten desactivar o modificar esta topología. Resultado: servidores con 256 núcleos que se ven como un único nodo NUMA. ¿Y eso qué implica? Pues, para empezar, que SQL Server no puede distribuir sus schedulers de forma eficiente. El escalado se resiente, la contención de recursos aumenta y las consultas paralelas empiezan a hacer cosas raras.

¿Has visto alguna vez una consulta que parece ir más lenta cuanto más CPUs tiene disponibles? Bienvenido al infierno del mal NUMA. Y sí, hay admins que creen que poner más CPUs siempre mejora el rendimiento. También hay quien piensa que una tabla de log no necesita índices. Vivir para ver.

Las virtualizaciones y sus trampas con NUMA

Ah, la virtualización. Ese mundo donde puedes tener 64 vCPU repartidas en 2 nodos NUMA virtuales y no saber por qué tu SQL Server tiene el rendimiento de un 486 con resaca. Los hipervisores serios (como VMware, Hyper-V o, incluso, Proxmox) permiten configurar el número de nodos NUMA expuestos a la máquina virtual. Pero si dejas esto en manos de un “especialista” que nunca ha leído una página del “whitepaper de arquitectura NUMA en SQL Server” (sí, no solo existe, cada fabricante tiene uno propio), lo normal es que termines con un entorno virtualizado más caótico que una tabla sin clave primaria.

Por eso, cuando trabajamos con entornos virtualizados, conviene revisar cuidadosamente cómo están asignados los núcleos físicos, cuántos nodos NUMA ve la VM y cómo se está presentando la memoria. SQL Server lo detectará, pero no puede arreglar por sí solo una chapuza.

¿Y qué hay del NUMA en SQL Server en Azure?

Pues aquí el tema se vuelve más oscuro. Microsoft no publica (con detalle) la topología NUMA exacta de sus VMs, pero en general puedes asumir que, en las series más potentes, hay más de un nodo. Las VMs con más de 16 vCPU casi siempre están divididas en al menos dos nodos NUMA virtuales. ¿Cómo lo comprobamos? Ejecutando SELECT * FROM sys.dm_os_nodes y observando el campo memory_node_id. Si ves más de un nodo con memory_node_id distinto de 64 (el de DAC), estás en terreno NUMA.

Por tanto, cuando afinamos instancias en Azure, conviene monitorizar la distribución de la carga entre nodos. A veces, ciertas consultas intensivas pueden estar trabajando siempre sobre el mismo nodo, provocando un cuello de botella local mientras el resto del servidor está de paseo.

Configuraciones de NUMA recomendadas

Si el servidor tiene una topología NUMA bien definida, lo mejor que podemos hacer es dejar que SQL Server gestione sus schedulers y memoria. No toques la afinidad de CPU salvo que tengas un motivo muy claro. Y por favor, no uses MAXDOP sin entender cómo afecta a los nodos. Un mal MAXDOP puede anular por completo los beneficios de NUMA, provocando saltos de memoria y escalado ineficiente.

También hay que considerar Resource Governor, que puede fijar workloads a ciertos nodos, o las nuevas opciones de Soft-NUMA (a partir de SQL Server 2016), útiles cuando el hardware ofrece más núcleos por nodo de los que SQL Server gestiona de forma eficiente por defecto.

Y si alguien propone usar lock pages in memory sin revisar la topología NUMA antes, haceos un favor: quitadle los permisos.

Conclusión

NUMA no es un problema. Es una característica muy potente. Pero como toda característica avanzada, si no la entendemos puede convertirse en un dolor de cabeza. En entornos de producción con alta carga, especialmente con muchos núcleos y grandes volúmenes de memoria, ignorar NUMA es como hacer tuning con los ojos vendados.

La solución no es complicarse la vida configurando todo a mano sin necesidad, sino entender cómo se comporta SQL Server en nuestro entorno y dejar que optimice… siempre que el terreno no esté lleno de minas.

No lo digo yo, lo dice la ciencia.

Espero que este artículo te haya resultado útil e interesante. Si tienes alguna duda o comentario, no dudes en contactarnos en Twitter o por mail o dejarnos un mensaje en los comentarios de aquí abajo. Y recuerda que también tenemos un grupo de LinkedIn al que te puedes unir.

Publicado por Roberto Carrancio

Mi nombre es Roberto Carrancio y soy un DBA de SQL server con más de 10 años de experiencia en el sector. Soy el creador del blog soydba.es donde intento publicar varios artículos a la semana (de lunes a viernes que los fines de semana me gusta estar con mi gente y disfrutar de mi moto) Espero que disfrutes leyendo este blog tanto como yo disfruto escribiendo y que te sea de utilidad. Si tienes alguna sugerencia, pregunta o comentario, puedes dejarlo al final de cada entrada o enviarme un correo electrónico. Estaré encantado de leerte y responderte. ¡Gracias por tu visita! Mi principal interés es compartir mi conocimiento sobre bases de datos con todo el que quiera aprenderlo. Me parece un mundo tan apasionante como desconocido. Fuera de lo profesional me encanta la cocina, la moto y disfrutar de tomar una cervecita con amigos.

Deja una respuesta