Da ESX 5 og Hyper-V i Windows Server 2012 frigav og ændrede de begrænsninger, der tidligere eksisterede for VM-størrelser, vidste jeg næsten med det samme, at vi ville se, at flere store SQL Server-arbejdsbelastninger begyndte at blive virtualiseret. Jeg har arbejdet med en række kunder i det sidste år, der virtualiserede 16-32 kerne-SQL-servere af forskellige årsager, fra forenklede Disaster Recovery-strategier, der matchede resten af virksomheden, til konsolidering og lavere samlede ejeromkostninger på nyere hardware platforme. En af grundene til skalerbarhedsændringen med ESX 5+ var introduktionen af virtuel NUMA (vNUMA) for brede gæster, der oversteg størrelsen af en individuel hardware NUMA-knude. Med vNUMA er gæste-VM'en optimeret til at matche hardware-NUMA-topologien, hvilket gør det muligt for gæsteoperativsystemet og alle NUMA-bevidste applikationer, såsom SQL Server, der kører på VM'en, at drage fordel af NUMA-ydeevneoptimeringerne, lige som om de var kører på en fysisk server.
Inden for VMware er en vNUMA-topologi tilgængelig på hardwareversion 8 eller højere og konfigureres som standard, hvis antallet af vCPU'er er større end otte for gæsten. Det er også muligt manuelt at konfigurere vNUMA-topologien for en VM ved hjælp af avancerede konfigurationsmuligheder, hvilket kan være nyttigt for VM'er, der har mere hukommelse allokeret til dem, end en fysisk NUMA-node kan give, men stadig bruger otte eller færre vCPU'er. For det meste fungerer standardkonfigurationsindstillingerne for de fleste VM'er, som jeg har set på i løbet af de sidste par år, men der er visse scenarier, hvor standard vNUMA-topologien ikke er ideel, og manuel konfiguration kan give nogle fordele. For nylig arbejdede jeg med en klient med et antal 32 vCPU SQL Server VM'er med 512 GB RAM tildelt, hvor jeg lavede en ydelsesjustering, hvor vNUMA-topologien ikke var i nærheden af det forventede.
VM-værtsserverne i dette miljø var fire socket E5-4650 otte core-processorer og 1 TB RAM, hver dedikeret til en enkelt SQL Server VM under typiske operationer, men med tilgængelig kapacitet til at opretholde to VM'er i et fejlscenarie. Med dette hardwarelayout er der fire NUMA-noder, én pr. socket, og den forventede VM-konfiguration vil også have 4 vNUMA-noder præsenteret for en 32 vCPU-konfiguration. Men det, jeg fandt, mens jeg kiggede på DMV'erne i SQL Server, var, at dette ikke var tilfældet:
Figur 1 – Forkert vNUMA-konfiguration
Som du sikkert kan se på billedet, er der virkelig noget galt med NUMA-konfigurationen på denne server. Der er fire hukommelsesknuder i SQLOS og kun en enkelt CPU-knude, med alle vCPU'er tildelt i den. For at være helt ærlig, blæste det mig, da jeg så det, fordi det gik imod alt, hvad jeg vidste om, hvordan SQLOS konfigurerede de interne strukturer ved opstart af instanser. Efter at have gravet lidt rundt i ErrorLog-filerne, Performance Monitor og Windows Task Manager, downloadede jeg en kopi af CoreInfo fra SysInternals og tog et kig på NUMA-layoutet, der rapporteres til Windows.
Kort over logisk processor til socket:********————————— Socket 0
——–********—————- Socket 1
—————-********——– Sokkel 2
————————******** Sokkel 3
Logisk processor til NUMA Node Map:
********************************* NUMA Node 0
CoreInfo-outputtet bekræftede, at VM'en præsenterer de 32 vCPU'er som 4 forskellige sockets, men grupperede derefter alle 32 vCPU'er i NUMA Node 0. Ved at se på Windows Server 2012-ydelsestællerne på VM'en kunne jeg se fra NUMA Node Memory-tællergruppen, at 4 NUMA hukommelsesknuder blev præsenteret for OS med hukommelsen jævnt fordelt på tværs af knudepunkterne. Alt dette stemte overens med det, jeg så i SQLOS, og jeg kunne også se fra opstarts ERRORLOG-indtastningerne, at cpu-masken for noden maskerede alle tilgængelige CPU'er ind i CPU Node 0, men fire store sideallokatorer blev oprettet, en til hver hukommelsesknude.
09/22/2013 05:03:37,Server,Ukendt,Nodekonfiguration:node 0:CPU maske:0x00000000ffffffff:0 Aktiv CPU maske:0x00000000ffffffff:0. Denne meddelelse giver en beskrivelse af NUMA-konfigurationen for denne computer. Dette er kun en informationsmeddelelse. Ingen brugerhandling er påkrævet.09/22/2013 05:03:37,Server,Ukendt,Denne forekomst af SQL Server sidst rapporteret ved hjælp af et proces-id på 1596 den 22/9/2013 5:00:25 (lokal) 22/9/2013 10:00:25 AM (UTC). Dette er kun en informationsmeddelelse; ingen brugerhandling er påkrævet.
09/22/2013 05:03:35,Server,Ukendt,Stor side allokeret:32MB
09/22/2013 05:03:35,Server,Ukendt,Stor Side allokeret:32MB
09/22/2013 05:03:35,Server,Ukendt,Stor side tildelt:32MB
09/22/2013 05:03:35,Server,Ukendt,Stor side allokeret :32MB
09/22/2013 05:03:35,Server,Ukendt,Brug af låste sider i hukommelseshåndteringen.
09/22/2013 05:03:35,Server,Ukendt,Opdaget 524287 MB RAM. Dette er en informativ besked; ingen brugerhandling er påkrævet.
09/22/2013 05:03:35,Server,Ukendt,SQL-server starter med normal prioritetsbase (=7). Dette er kun en informationsmeddelelse. Ingen brugerhandling er påkrævet.
09/22/2013 05:03:35,Server,Ukendt,SQL Server registrerede 4 sockets med 8 kerner pr. socket og 8 logiske processorer pr. socket 32 i alt logiske processorer; bruger 32 logiske processorer baseret på SQL Server-licens. Dette er en informativ besked; ingen brugerhandling er påkrævet.
På dette tidspunkt var jeg sikker på, at det var noget relateret til VM-konfigurationen, men jeg kunne ikke identificere, hvad problemet specifikt var, da jeg aldrig havde set denne adfærd på andre brede SQL Server VM'er, som jeg havde assisteret klienter på VMware ESX 5+ i fortiden. Efter at have foretaget et par konfigurationsændringer på en test-VM-server, der var tilgængelig, var det kun ingen af dem, der rettede vNUMA-konfigurationen, der blev præsenteret inde i VM'en. Efter at have ringet til VMware-support, blev vi bedt om at deaktivere vCPU-hotplug-funktionen for test-VM'en og se, om det løste problemet. Med hotplug deaktiveret på VM'en bekræftede CoreInfo-outputtet, at vNUMA-tilknytningen af processorerne til VM'en nu var korrekt:
Kort over logisk processor til socket:********————————— Socket 0
——–********—————- Socket 1
—————-********——– Sokkel 2
————————******** Sokkel 3
Logisk processor til NUMA Node Map:
********————————— NUMA Node 0
——–********————— - NUMA Node 1
—————-********——– NUMA Node 2
—————————******** NUMA Node 3
Denne adfærd er faktisk dokumenteret i VMware KB-artiklen (vNUMA er deaktiveret, hvis VCPU hotplug er aktiveret), fra oktober 2013. Dette var tilfældigvis den første brede VM til SQL Server, som jeg havde arbejdet med, hvor vCPU hotplug var aktiveret, og det er ikke en typisk konfiguration, jeg ville forvente for en 32 vCPU VM, men var en del af standardskabelonen, der blev brugt på klienten, og tilfældigvis påvirkede deres SQL Server.
Effekter af, at vNUMA blev deaktiveret
Der er en række effekter, som vNUMA bliver deaktiveret på denne måde, kan have for en arbejdsbelastning, men der er to specifikke problemer, der kan påvirke SQL Server specifikt under denne type konfiguration. Den første er, at serveren kan have problemer med CMEMTHREAD venteakkumuleringer, da der er 32 vCPU'er allokeret til en enkelt NUMA node, og standardpartitioneringen for hukommelsesobjekter i SQLOS er pr. NUMA node. Dette specifikke problem blev dokumenteret af Bob Dorr i CSS-gruppen hos Microsoft på deres blogindlæg SQL Server 2008/2008 R2 på nyere maskiner med mere end 8 CPU'er præsenteret pr. NUMA Node kan have brug for sporingsflag 8048. Som en del af gennemgang af ventestatistik på VM'en med klienten bemærkede jeg, at CMEMTHREAD var deres næsthøjeste ventetype, hvilket er unormalt fra min erfaring og fik mig til at se på SQLOS NUMA-konfigurationen vist i figur 1 ovenfor. I dette tilfælde er sporingsflaget ikke løsningen, fjernelse af vCPU-hotplug fra VM-konfigurationen løser problemet.
Det andet problem, der vil påvirke SQL Server specifikt, hvis du er på en ikke-patchet version, er forbundet med NUMA-hukommelsesadministration i SQLOS, og den måde, SQLOS sporer og administrerer Away-sider under den indledende hukommelsesopbygningsfase efter opstart af instans. Denne adfærd blev dokumenteret af Bob Dorr på CSS blogindlægget, How It Works:SQL Server (NUMA Local, Foreign and Away Memory Blocks). I det væsentlige, når SQLOS forsøger en lokal nodehukommelsesallokering under den første ramp-up, hvis den returnerede hukommelsesadresse er fra en anden hukommelsesknude, føjes siden til Away-listen, og endnu et lokalt hukommelsestildelingsforsøg forekommer, og processen gentages indtil en lokal hukommelsesallokering lykkes, eller serverhukommelsesmålet er nået. Da tre fjerdedele af vores instanshukommelse eksisterer på NUMA noder uden nogen skemalæggere, skaber dette en forringet ydeevne under den indledende ramp-up af hukommelsen for instansen. Nylige opdateringer har ændret adfærden for hukommelsesallokering under den første ramp-up til kun at forsøge den lokale hukommelsestildeling et fast antal gange (det specifikke antal er ikke dokumenteret), før den fremmede hukommelse bruges til at fortsætte behandlingen. Disse opdateringer er dokumenteret i KB #2819662, RETNING:Problemer med SQL Server-ydelse i NUMA-miljøer.
Oversigt
For brede VM'er, defineret som havende mere end 8 vCPU'er, er det ønskeligt at få vNUMA sendt til VM'en af hypervisoren for at tillade Windows og SQL Server at udnytte NUMA-optimeringerne i deres kodebase. Som følge heraf bør disse bredere VM'er ikke have vCPU-hotplug-konfigurationen aktiveret, da dette er inkompatibelt med vNUMA og kan resultere i forringet ydeevne for SQL Server, når det virtualiseres.