Toen ESX 5 en Hyper-V in Windows Server 2012 de beperkingen die eerder bestonden voor VM-grootten uitbrachten en veranderden, wist ik vrijwel onmiddellijk dat we zouden zien dat meer grootschalige SQL Server-workloads gevirtualiseerd zouden worden. Ik heb het afgelopen jaar met een aantal klanten gewerkt die om verschillende redenen 16-32 core SQL-servers virtualiseerden, van vereenvoudigde rampherstelstrategieën die overeenkwamen met de rest van het bedrijf, tot consolidatie en lagere totale eigendomskosten op nieuwere hardware platformen. Een van de redenen voor de schaalbaarheidsverandering met ESX 5+ was de introductie van virtuele NUMA (vNUMA) voor brede gasten die de grootte van een individuele hardware-NUMA-node overschreed. Met vNUMA wordt de gast-VM geoptimaliseerd om overeen te komen met de hardware-NUMA-topologie, waardoor het gastbesturingssysteem en alle NUMA-bewuste toepassingen, zoals SQL Server, die op de VM worden uitgevoerd, kunnen profiteren van de NUMA-prestatie-optimalisaties, net alsof ze draait op een fysieke server.
Binnen VMware is een vNUMA-topologie beschikbaar op hardwareversie 8 of hoger en wordt deze standaard geconfigureerd als het aantal vCPU's groter is dan acht voor de gast. Het is ook mogelijk om de vNUMA-topologie voor een VM handmatig te configureren met behulp van geavanceerde configuratieopties, wat handig kan zijn voor VM's waaraan meer geheugen is toegewezen dan een fysiek NUMA-knooppunt kan bieden, maar die nog steeds acht of minder vCPU's gebruiken. Voor het grootste deel werken de standaardconfiguratie-instellingen voor de meeste VM's die ik de afgelopen jaren heb bekeken, maar er zijn bepaalde scenario's waarin de standaard vNUMA-topologie niet ideaal is en handmatige configuratie enkele voordelen kan bieden. Onlangs werkte ik met een client met een aantal 32 vCPU SQL Server-VM's met toegewezen 512 GB RAM om de prestaties af te stemmen, waarbij de vNUMA-topologie niet in de buurt kwam van wat werd verwacht.
De VM-hostservers in deze omgeving waren vier socket E5-4650 acht-coreprocessors en 1 TB RAM, elk toegewezen aan een enkele SQL Server-VM onder typische bewerkingen, maar met beschikbare capaciteit om twee VM's te ondersteunen in een storingsscenario. Met deze hardwarelay-out zijn er vier NUMA-knooppunten, één per socket, en de verwachte VM-configuratie zou ook 4 vNUMA-knooppunten bevatten voor een 32 vCPU-configuratie. Wat ik echter ontdekte toen ik naar de DMV's in SQL Server keek, was dat dit niet het geval was:
Figuur 1 – Onjuiste vNUMA-configuratie
Zoals je waarschijnlijk op de afbeelding kunt zien, is er echt iets mis met de NUMA-configuratie op deze server. Er zijn vier geheugenknooppunten binnen SQLOS en slechts één CPU-knooppunt, waarin alle vCPU's zijn toegewezen. Om heel eerlijk te zijn, verbaasde dit me toen ik het zag, omdat het indruiste tegen alles wat ik wist over hoe SQLOS de interne structuren configureerde bij het opstarten van de instantie. Na wat rond te snuffelen in de ErrorLog-bestanden, Prestatiemeter en Windows Taakbeheer, heb ik een kopie van CoreInfo gedownload van SysInternals en heb ik de NUMA-layout bekeken die aan Windows wordt gerapporteerd.
Logische processor naar socketkaart:********———————— Socket 0
——–********—————- Socket 1
—————-*******——– Aansluiting 2
———————******* Aansluiting 3
Logische processor naar NUMA-knooppuntkaart:
******************************** NUMA-knooppunt 0
De CoreInfo-uitvoer bevestigde dat de VM de 32 vCPU's presenteert als 4 verschillende sockets, maar vervolgens alle 32 vCPU's groepeerde in NUMA Node 0. Als ik naar de prestatiemeteritems van Windows Server 2012 op de VM keek, kon ik zien aan de NUMA Node Memory-tellergroep, dat 4 NUMA-geheugenknooppunten werden aan het besturingssysteem gepresenteerd, waarbij het geheugen gelijkmatig over de knooppunten was verdeeld. Dit kwam allemaal overeen met wat ik zag in SQLOS, en ik kon ook aan de opstart ERRORLOG-vermeldingen zien dat het cpu-masker voor het knooppunt alle beschikbare CPU's maskeerde in CPU-knooppunt 0, maar dat er vier Large Page Allocators werden gemaakt, één voor elk geheugenknooppunt.
22-09-2013 05:03:37,Server,Onbekend,Knooppuntconfiguratie:knooppunt 0:CPU-masker:0x00000000ffffffff:0 Actief CPU-masker:0x00000000ffffffff:0. Dit bericht geeft een beschrijving van de NUMA-configuratie voor deze computer. Dit is alleen een informatief bericht. Er is geen actie van de gebruiker vereist.22/09/2013 05:03:37,Server,Unknown,Dit exemplaar van SQL Server is voor het laatst gerapporteerd met een proces-ID van 1596 op 22-09-2013 5:00:25 AM (lokaal) 22-09-2013 10:00:25 AM (UTC). Dit is alleen een informatief bericht; er is geen actie van de gebruiker vereist.
22/09/2013 05:03:35,Server,Onbekend,Grote pagina Toegewezen:32MB
22/09/2013 05:03:35,Server,Onbekend,Large Toegewezen pagina:32 MB
22-09-2013 05:03:35,Server,Onbekend,Grote pagina Toegewezen:32MB
22-09-2013 05:03:35,Server,Onbekend,Grote pagina Toegewezen :32MB
22-09-2013 05:03:35,Server,Onbekend,Vergrendelde pagina's gebruiken in geheugenbeheer.
22-09-2013 05:03:35,Server,Onbekend,Gedetecteerd 524287 MB RAM-geheugen. Dit is een informatief bericht; er is geen actie van de gebruiker vereist.
22/09/2013 05:03:35,Server,Unknown,SQL Server begint op de normale prioriteitsbasis (=7). Dit is alleen een informatief bericht. Er is geen actie van de gebruiker vereist.
22/09/2013 05:03:35,Server,Unknown,SQL Server heeft 4 sockets gedetecteerd met 8 cores per socket en 8 logische processors per socket 32 in totaal logische processors; gebruikmakend van 32 logische processors op basis van SQL Server-licenties. Dit is een informatief bericht; er is geen gebruikersactie vereist.
Op dit punt was ik er zeker van dat het iets te maken had met de VM-configuratie, maar ik kon niet identificeren wat specifiek het probleem was, aangezien ik dit gedrag nog nooit had gezien op andere brede SQL Server-VM's die ik klanten had geholpen op VMware ESX 5+ in het verleden. Na een aantal configuratiewijzigingen te hebben aangebracht aan een test-VM-server die beschikbaar was, corrigeerde geen van deze de vNUMA-configuratie die in de VM werd gepresenteerd. Nadat we VMware-ondersteuning hadden ingeschakeld, werd ons gevraagd om de vCPU-hotplugfunctie voor de test-VM uit te schakelen en te kijken of dat het probleem oploste. Met hotplug uitgeschakeld op de VM, bevestigde de CoreInfo-uitvoer dat de vNUMA-toewijzing van de processors voor de VM nu correct was:
Logische processor naar socketkaart:********———————— Socket 0
——–********—————- Socket 1
—————-*******——– Aansluiting 2
———————******* Aansluiting 3
Logische processor naar NUMA Node Map:
********———————— NUMA Node 0
——–**********————— - NUMA-knooppunt 1
—————-********——– NUMA-knooppunt 2
————————******** NUMA-knooppunt 3
Dit gedrag is gedocumenteerd in het VMware KB-artikel (vNUMA is uitgeschakeld als VCPU-hotplug is ingeschakeld), van oktober 2013. Dit was toevallig de eerste brede VM voor SQL Server waarmee ik had gewerkt waarbij vCPU-hotplug was ingeschakeld, en het is geen typische configuratie die ik zou verwachten voor een 32 vCPU VM, maar maakte deel uit van de standaardsjabloon die door de client werd gebruikt en had toevallig invloed op hun SQL Server.
Effecten van het uitschakelen van vNUMA
Er zijn een aantal effecten die het uitschakelen van vNUMA kan hebben op een werkbelasting, maar er zijn twee specifieke problemen die specifiek van invloed kunnen zijn op SQL Server onder dit type configuratie. De eerste is dat de server problemen kan hebben met CMEMTHREAD-wachtaccumulaties, aangezien er 32 vCPU's zijn toegewezen aan één NUMA-knooppunt en de standaardpartitionering voor geheugenobjecten in SQLOS per NUMA-knooppunt is. Dit specifieke probleem is gedocumenteerd door Bob Dorr in de CSS-groep bij Microsoft in hun blogbericht SQL Server 2008/2008 R2 op nieuwere machines met meer dan 8 CPU's gepresenteerd per NUMA-knooppunt heeft mogelijk traceringsvlag 8048 nodig. Als onderdeel van het beoordelen van wachtstatistieken op de VM met de client merkte ik op dat CMEMTHREAD hun op één na hoogste wachttype was, wat abnormaal is vanuit mijn ervaring en ervoor zorgde dat ik keek naar de SQLOS NUMA-configuratie die wordt weergegeven in figuur 1 hierboven. In dit geval is de traceringsvlag niet de oplossing, het verwijderen van vCPU-hotplug uit de VM-configuratie lost het probleem op.
Het tweede probleem dat met name van invloed zou zijn op SQL Server als u een niet-gepatchte versie gebruikt, houdt verband met NUMA-geheugenbeheer in SQLOS en de manier waarop SQLOS Away-pagina's bijhoudt en beheert tijdens de initiële geheugenaanloopfase na het opstarten van de instantie. Dit gedrag is gedocumenteerd door Bob Dorr in de CSS-blogpost How It Works:SQL Server (NUMA Local, Foreign en Away Memory Blocks). In wezen, wanneer SQLOS probeert een lokale knooppuntgeheugentoewijzing uit te voeren tijdens de initiële opstart, als het geretourneerde geheugenadres van een ander geheugenknooppunt is, wordt de pagina toegevoegd aan de lijst Afwezig en vindt er nog een lokale geheugentoewijzingspoging plaats, en het proces herhaalt zich totdat een lokale geheugentoewijzing is gelukt of het doel van het servergeheugen is bereikt. Aangezien driekwart van ons instancegeheugen op NUMA-knooppunten zonder planners bestaat, zorgt dit voor een verslechterde prestatieconditie tijdens de initiële aanloop van het geheugen voor de instance. Recente updates hebben het gedrag van geheugentoewijzing tijdens de eerste opstart veranderd om de lokale geheugentoewijzing slechts een vast aantal keren te proberen (het specifieke aantal is niet gedocumenteerd) voordat het externe geheugen wordt gebruikt om door te gaan met verwerken. Die updates zijn gedocumenteerd in KB #2819662, FIX:Prestatieproblemen met SQL Server in NUMA-omgevingen.
Samenvatting
Voor brede VM's, gedefinieerd als met meer dan 8 vCPU's, is het wenselijk om vNUMA door de hypervisor aan de VM te laten doorgeven, zodat Windows en SQL Server gebruik kunnen maken van de NUMA-optimalisaties binnen hun codebasis. Als gevolg hiervan zouden deze bredere VM's de vCPU-hotplugconfiguratie niet moeten hebben ingeschakeld, omdat dit incompatibel is met vNUMA en kan leiden tot verminderde prestaties voor SQL Server wanneer ze worden gevirtualiseerd.