Když ESX 5 a Hyper-V ve Windows Server 2012 vydaly a změnily omezení, která dříve existovala pro velikosti virtuálních počítačů, téměř okamžitě jsem věděl, že začnou být virtualizovány další velké škálovatelné úlohy SQL Server. V minulém roce jsem pracoval s řadou zákazníků, kteří virtualizovali 16-32 jádrové SQL Servery z různých důvodů, od zjednodušených strategií obnovy po havárii, které odpovídaly zbytku podniku, po konsolidaci a nižší celkové náklady na vlastnictví na novějším hardwaru. platformy. Jedním z důvodů změny škálovatelnosti s ESX 5+ bylo zavedení virtuálního NUMA (vNUMA) pro široké hosty, které přesahovalo velikost jednotlivého hardwarového NUMA uzlu. S vNUMA je hostující virtuální počítač optimalizován tak, aby odpovídal hardwarové topologii NUMA, což umožňuje hostujícímu operačnímu systému a všem aplikacím s podporou NUMA, jako je SQL Server, které běží na virtuálním počítači, využívat optimalizace výkonu NUMA, jako by byly běžící na fyzickém serveru.
V rámci VMware je topologie vNUMA dostupná na hardwaru verze 8 nebo vyšší a ve výchozím nastavení se nakonfiguruje, pokud je počet vCPU pro hosta větší než osm. Je také možné ručně nakonfigurovat topologii vNUMA pro virtuální počítač pomocí pokročilých možností konfigurace, což může být užitečné pro virtuální počítače, které mají přiděleno více paměti, než může poskytnout fyzický uzel NUMA, ale stále používají osm nebo méně vCPU. Z velké části výchozí nastavení konfigurace funguje pro většinu virtuálních počítačů, na které jsem se za posledních několik let díval, ale existují určité scénáře, kdy výchozí topologie vNUMA není ideální a ruční konfigurace může poskytnout určité výhody. Nedávno jsem pracoval s klientem s řadou 32 virtuálních počítačů vCPU SQL Server s alokovanou 512 GB RAM a prováděl jsem nějaké ladění výkonu, kde topologie vNUMA nebyla ani zdaleka očekávaná.
Hostitelské servery virtuálních počítačů v tomto prostředí byly čtyřjádrové procesory E5-4650 se čtyřmi sokety a 1 TB paměti RAM, každý vyhrazený pro jeden virtuální počítač SQL Server při typických operacích, ale s dostupnou kapacitou pro udržení dvou virtuálních počítačů v případě selhání. S tímto hardwarovým rozložením jsou k dispozici čtyři uzly NUMA, jeden na každý soket, a očekávaná konfigurace virtuálního počítače by měla mít také 4 uzly vNUMA pro konfiguraci 32 vCPU. Při pohledu na DMV v SQL Server jsem však zjistil, že tomu tak nebylo:
Obrázek 1 – Nesprávná konfigurace vNUMA
Jak pravděpodobně vidíte na obrázku, něco je opravdu špatně s konfigurací NUMA na tomto serveru. V rámci SQLOS jsou čtyři paměťové uzly a pouze jeden uzel CPU se všemi vCPU alokovanými v něm. Abych byl naprosto upřímný, vybuchlo mi to z hlavy, když jsem to viděl, protože to bylo v rozporu se vším, co jsem věděl o tom, jak SQLOS konfiguroval vnitřní struktury při spuštění instance. Poté, co jsem se trochu prohrabal v souborech ErrorLog, Performance Monitor a Windows Task Manager, stáhl jsem si kopii CoreInfo od SysInternals a podíval jsem se na rozložení NUMA, které je hlášeno Windows.
Mapa logického procesoru do zásuvky:********———————— Soket 0
——–********—————- Socket 1
—————-********——– Zásuvka 2
————————******** Zásuvka 3
Logický procesor na mapu uzlů NUMA:
********************************* NUMA uzel 0
Výstup CoreInfo potvrdil, že VM prezentuje 32 vCPU jako 4 různé sokety, ale pak seskupil všech 32 vCPU do NUMA Node 0. Při pohledu na čítače výkonu Windows Server 2012 na VM jsem viděl ze skupiny čítačů paměti NUMA Node Memory, že Operačnímu systému byly předloženy 4 paměťové uzly NUMA s pamětí rovnoměrně rozloženou mezi uzly. To vše bylo v souladu s tím, co jsem viděl v SQLOS, a také jsem mohl ze spouštěcích záznamů ERRORLOG zjistit, že maska CPU pro uzel maskovala všechny dostupné CPU do CPU Node 0, ale byly vytvořeny čtyři Large Page Allocators, jeden pro každý paměťový uzel.
22.09.2013 05:03:37,Server,Neznámý,Konfigurace uzlu:uzel 0:Maska CPU:0x00000000ffffffff:0 Aktivní maska CPU:0x00000000ffffffff:0. Tato zpráva obsahuje popis konfigurace NUMA pro tento počítač. Toto je pouze informativní zpráva. Není vyžadována žádná akce uživatele.09/22/2013 05:03:37,Server,Neznámý,Tato instance SQL Server byla naposledy hlášena pomocí ID procesu 1596 dne 22.9.2013 5:00:25 (místní) 22. 9. 2013 10:00:25 (UTC). Toto je pouze informativní zpráva; není vyžadována žádná akce uživatele.
09/22/2013 05:03:35,Server,Neznámý,Velká přidělená stránka:32 MB
09/22/2013 05:03:35,Server,Neznámý,Velký Přidělená stránka:32 MB
09/22/2013 05:03:35,Server,Neznámý,Velká přidělená stránka:32 MB
09/22/2013 05:03:35,Server,Neznámý,Velká stránka přidělena :32 MB
09/22/2013 05:03:35,Server,Neznámý,Používání zamčených stránek ve správci paměti.
09/22/2013 05:03:35,Server,Neznámý,Zjištěno 524287 MB paměti RAM. Toto je informační zpráva; není vyžadována žádná akce uživatele.
09/22/2013 05:03:35,Server,Neznámý,SQL Server se spouští s normální prioritou (=7). Toto je pouze informativní zpráva. Není vyžadována žádná akce uživatele.
09/22/2013 05:03:35,Server,Neznámo,SQL Server detekoval 4 sokety s 8 jádry na soket a 8 logickými procesory na soket 32 logických procesorů celkem; pomocí 32 logických procesorů založených na licencování SQL Server. Toto je informační zpráva; není vyžadována žádná akce uživatele.
V tuto chvíli jsem si byl jistý, že se jedná o něco souvisejícího s konfigurací virtuálního počítače, ale nedokázal jsem identifikovat, v čem konkrétně byl problém, protože jsem toto chování nikdy neviděl na jiných rozsáhlých virtuálních počítačích SQL Server, kterým jsem pomáhal klientům na VMware ESX 5+. v minulosti. Po provedení několika změn konfigurace na testovacím serveru virtuálního počítače, který byl k dispozici, pouze žádná z nich neopravila konfiguraci vNUMA prezentovanou uvnitř virtuálního počítače. Po zavolání podpory VMware jsme byli požádáni, abychom deaktivovali funkci vCPU hotplug pro testovací VM a zjistili, zda se tím problém vyřešil. Když byl hotplug na virtuálním počítači vypnutý, výstup CoreInfo potvrdil, že mapování vNUMA procesorů pro virtuální počítač bylo nyní správné:
Mapa logického procesoru do zásuvky:********———————— Soket 0
——–********—————- Socket 1
—————-********——– Zásuvka 2
————————******** Zásuvka 3
Logický procesor na mapu uzlů NUMA:
********———————— NUMA uzel 0
——–********————— - Uzel NUMA 1
—————-********——– Uzel NUMA 2
————————******** Uzel NUMA 3
Toto chování je ve skutečnosti zdokumentováno v článku VMware KB (vNUMA je zakázáno, pokud je povolen VCPU hotplug), z října 2013. Toto byl náhodou první široký virtuální počítač pro SQL Server, se kterým jsem pracoval, kde byl povolen vCPU hotplug, a je to není typická konfigurace, kterou bych očekával pro 32 vCPU VM, ale byla součástí standardní šablony používané u klienta a náhodou ovlivnila jejich SQL Server.
Efekty deaktivace vNUMA
Existuje řada účinků, které by takovéto deaktivování vNUMA mohlo mít na pracovní zátěž, ale existují dva konkrétní problémy, které by mohly konkrétně ovlivnit SQL Server v tomto typu konfigurace. První je, že server může mít problémy s akumulací čekání CMEMTHREAD, protože jednomu uzlu NUMA je přiděleno 32 vCPU a výchozí rozdělení paměťových objektů v SQLOS je na uzel NUMA. Tento konkrétní problém zdokumentoval Bob Dorr ve skupině CSS v Microsoftu ve svém příspěvku na blogu SQL Server 2008/2008 R2 na novějších počítačích s více než 8 CPU prezentovanými na NUMA uzel může potřebovat příznak trasování 8048. Jako součást kontroly čekacích statistik na virtuálním počítači s klientem jsem si všiml, že CMEMTHREAD byl jejich druhý nejvyšší typ čekání, což je z mé zkušenosti abnormální a způsobilo to, že jsem se podíval na konfiguraci SQLOS NUMA zobrazenou na obrázku 1 výše. V tomto případě příznak trasování není řešením, problém vyřeší odstranění hotplug vCPU z konfigurace virtuálního počítače.
Druhý problém, který by konkrétně ovlivnil SQL Server, pokud používáte neopravenou verzi, je spojen se správou paměti NUMA v SQLOS a se způsobem, jakým SQLOS sleduje a spravuje stránky Away během počáteční fáze náběhu paměti po spuštění instance. Toto chování zdokumentoval Bob Dorr v příspěvku na blogu CSS How It Works:SQL Server (NUMA Local, Foreign and Away Memory Blocks). V podstatě, když se SQLOS pokusí o alokaci paměti místního uzlu během počátečního náběhu, pokud vrácená adresa paměti pochází z jiného paměťového uzlu, stránka se přidá do seznamu Pryč a dojde k dalšímu pokusu o přidělení místní paměti a proces se opakuje, dokud alokace místní paměti je úspěšná nebo je dosaženo cíle paměti serveru. Vzhledem k tomu, že tři čtvrtiny paměti našich instancí existují na uzlech NUMA bez jakýchkoli plánovačů, vytváří to podmínku sníženého výkonu během počátečního nárůstu paměti pro instanci. Nedávné aktualizace změnily chování přidělování paměti během počátečního náběhu tak, že se pokusí o přidělení místní paměti pouze pevně stanovený počet opakování (konkrétní počet není zdokumentován), než použije cizí paměť k pokračování ve zpracování. Tyto aktualizace jsou zdokumentovány v KB #2819662, OPRAVA:Problémy s výkonem serveru SQL v prostředích NUMA.
Shrnutí
U širokých virtuálních počítačů, které jsou definovány jako mající více než 8 vCPU, je žádoucí, aby vNUMA předal do virtuálního počítače hypervizor, aby Windows a SQL Server mohly využít optimalizace NUMA v rámci své kódové základny. V důsledku toho by tyto širší virtuální počítače neměly mít povolenou konfiguraci vCPU hotplug, protože ta není kompatibilní s vNUMA a může mít za následek snížení výkonu SQL Serveru při virtualizaci.