Hace algún tiempo escribí sobre paralelismo en SQL Server y debatimos entre algunas cosas sobre la importancia del afinamiento de CPU a la hora de obtener el máximo rendimiento de tu Hardware (puedes leer aqui: Paralelismo en SQL Server (I) )
El caso es que no en pocas ocasiones se me pregunta cómo puedes particionar el HW correctamente cuando usas SQL Server y otros servicios en la misma máquina. Obviamente la afinidad de procesador nativa de SQL Server nos va a servir claramente cuando tenemos por ejemplo 2 nodos numa y 2 instancias de motor relacional corriendo independientes en esa misma máquina.
Es muy facil darse cuenta que la mejor opción si uno quiere aislar ambas instancias y maximizar el potencial HW de su máquina, lo mas sencillo es es que en la instancia 1, se le activen solo los procesadores del nodo Numa0 y en la instancia 2, solo se le activen los procesadores del nodo numa1. De esta forma, estamos consiguiendo que ambas instancias no compitan por CPU y que los bancos de memoria que usan cada una de ellas, quede lo mas cerca posible a la CPU que va a necesitar de su acceso.
Forzar afinidad en SSIS
Una vez visto la parte obvia de segmentar el uso HW para instancias SQL Server, ¿qué ocurre si queremos destinar solo un nodo NUMA para SQL Server y el otro para SSIS? ¿Y si queremos destinarlo para otra aplicación de terceros que tengamos nosotros corriendo en la máquina? En este tipo de situaciones podemos apoyarnos sobre una característica disponible en Windows Server 2008 (soportado hasta Windows Server 2012) llamada “Windows Server Resource Manager”.
Supongamos entonces que queremos aprovechar nuestra máquina y hemos llegado a la conclusión (tras su análisis previo, obviamente) que la mejor opción en calidad/precio consiste en dejar en la misma máquina la instancia SQL Server relacional y la instancia SSIS. Además, durante el análisis hemos visto que la instancia SSIS podría correr con soltura en 1 nodo numa y el SQL Server en los otros 3 (obviamente debes apoyarte en datos, no vale chuparse el dedo para estimar estas cosas :)). Lo que deberemos hacer es una combinación de dos cosas. Por un lado deberemos configurar afinidad de CPU para la instancia SQL Server, y por otro configurar el servicio “Windows Server Resource Manager”, del que seguro que si no has oído hablar, te interesará conocerlo en detalle a partir de ahora :).
Pongamonos en el supuesto entonces de tener un servidor con 4 nodos numa y 2 cores por nodo y que quieres asignar 3 nodos numa para SQL Server y 1 exclusivamente para ejecutar paquetes de SSIS
Para la parte del motor relacional de SQL Server está bastante facil, ya que lo que tienes que hacer es marcar el processor affinity para las CPU de los NumaNode 0 a 3, dejando sin marcar el nodo 4:
Queda entonces la instancia SQL Server vinculada a los nodos numa 0-3, no pudiendo crear hilos en el nodo 4, cosa que nos viene muy bien porque es donde pensamos forzar la ejecución de SSIS. Para hacerlo, debemos primero instalar la característica “Windows Server Resource Manager”.
Abrimos el server manager y vamos sobre “Features”:
Ahora instalamos la característica “Windows System Resource Manager”:
Una vez instalada (no suele pedir reinicio de instancia), procedemos a configurarla para nuestra necesidad:
Creamos un nuevo “Allocation Policy”:
Ahora le ponemos el nombre representativo que queramos:
Y le configuramos manualmente los límites de los recursos deseados (sobre <New…>):
A este nuevo matching criteria le damos de nuevo un nombre característico:
Y ahora seleccionamos el proceso, aplicación o servicio deseado. En nuestro caso vamos a ir directamente a configurar límites de recursos para el ejecutable DTExec.exe:
Vamos diréctamente a por el ejecutable:
Y ahora nos vamos a la pestaña “Advanced”, donde le indicaremos que queremos usar específicamente los procesadores 6-7 (que obviamente no colisionan con los configurados por SQL Server anteriormente) y se corresponden con los del nodo numa 3:
Y ya lo tendríamos configurado (no requiere reinicio):
Ahora para probarlo, haremos algo tan simple como crear un paquete SSIS, añadirle 3 contenedores de loop que vayan lanzando código C# de cálculo de CPU intensivo (en nuestro caso he puesto código de cálculo de numeros primos):
NOTA: El warning que aparece es intencionado y se refiere a que el contenedor es un bucle infinito, definido como sigue:
NOTA: Nunca hagas lo que ves en la imagen, es solo con fines didácticos
Si nos fijamos en la definición del paquete SSIS, he creado 3 contenedores puesto que hemos creado afinidad hacia el último nodo NUMA (2 CPUs). Esto es intencionado para que de esta forma se ve mas evidente que aunque le estamos pidiendo 3 hilos intensivos, no sale fuera a por mas CPU de las que realmente necesita . Una vez lanzas el paquete intensivo de CPU, tal como hemos indicado se utilzarán las CPU vinculadas mediante nuestra política, con lo que obviamente no entrarán en colisión tareas intensivas de CPU con nuestra instancia SQL Server y además la memoria (aunque no limitada) quedará mas cerca a su nodo afín.
Una puntualización final es que tengas cuidado, puesto que este tipo de configuraciones deben realizarse con precaución para no salir perdiendo. En SolidQ somos especialistas en analizar y configurar servidores críticos 24×7 y este tipo de acciones las hacemos siempre con el convencimiento de que van a obtenerse resultados favorables. Si realmente deseas aprovechar toda la potencia HW de tu infraestructura, no dudes en ponerte en contacto con nosotros.