Scenariusz
Załóżmy, że mam SQL Server z 4 gniazdami z każdym 1 węzłem NUMA. Każde gniazdo ma 4 rdzenie fizyczne. Łącznie jest 512 GB pamięci, więc każdy węzeł NUMA ma 128 GB pamięci RAM.
Tabela kluczy jest ładowana do pierwszego węzła NUMA.
Pytanie
Załóżmy, że mamy duży odczyt ruchu z tej tabeli. Jeśli wszystkie fizyczne rdzenie gniazda, które jest właścicielem węzła NUMA, w 100% wykorzystują procesor, czy to negatywnie wpływa na koszt nielokalnego dostępu NUMA pochodzącego z innych gniazd? Albo z drugiej strony, czy koszt nielokalnego dostępu do NUMA jest niezależny od tego, jak zajęte jest to gniazdo?
Mam nadzieję, że moje pytanie ma sens. Daj mi znać, jeśli nie, postaram się wyjaśnić.
tło
W ubiegłym tygodniu mieliśmy problem z bazą danych na naszym serwerze produkcyjnym, a niektóre z przetwarzanych przez nas firm wyglądały na bardziej dotknięte niż inne. Mieliśmy zapytania z kilkoma logicznymi odczytami, które trwały dłużej niż 1 minutę. Przyjrzeliśmy się całkowitemu wykorzystaniu procesora, które wyniosło około 60 procent. Nie przyjrzeliśmy się charakterystyce procesora specyficznej dla gniazd. Dane we / wy były średnie.
źródło
Odpowiedzi:
Ogromne pytanie :-) Przedstawię niektóre z czynników. W dowolnym kontekście czynniki te i inne mogą się różnić i dać interesujący wynik.
Przepraszam, że nie byłem w stanie uczynić tego o wiele krótszym ...
Accumuated CPU ms vs logical IO
Bardzo często używam wykresów logicznego We / Wy (lub w terminologii perfmon „wyszukiwania stron puli buforów”) w stosunku do wykorzystania procesora, aby zmierzyć wydajność procesorów obciążeń i poszukać przypadków podatnych na spinlock.
Ale SQL Server kumuluje czas procesora przy dużej aktywności innej niż wyszukiwanie stron i blokady:
Wiele innych działań pochłonie znaczny czas procesora bez odzwierciedlenia w wyszukiwaniu strony.
W obserwowanych przeze mnie obciążeniach głównym spośród tych „nielogicznych operacji intensywnie korzystających z IO, ale pochłaniających CPU” jest sortowanie / mieszanie.
Ma rację: rozważ wymyślony przykład dwóch zapytań przeciwko tablicy hashującej bez indeksów nieklastrowanych. Dwa zapytania mają identyczne zestawy wyników, ale jeden z zestawów wyników jest całkowicie nieuporządkowany, a drugi zestaw wyników jest uporządkowany według więcej niż jednej wybranej kolumny. Oczekuje się, że drugie zapytanie zużyje więcej czasu procesora, nawet jeśli odwołuje się do tej samej liczby stron w puli buforów.
Więcej informacji o pamięci obszaru roboczego i ilości wykorzystanego przyznanego obszaru roboczego w tych postach:
http://sql-sasquatch.blogspot.com/2015/08/sql-server-grantedreservedstolen_4.html
http://sql-sasquatch.blogspot.com/2015/08/sql-server-workspace-memory-with-twist.html
http://sql-sasquatch.blogspot.com/2015/03/resource-governor-to-restrict-max-query.html
Wyrównanie węzłów logicznej pamięci SQL Server z fizycznymi węzłami NUMA
SQL Server (od momentu włączenia strategii obsługujących NUMA) domyślnie tworzy węzeł pamięci SQLOS dla każdego węzła NUMA na serwerze. W miarę wzrostu przydziałów pamięci każdy przydział jest kontrolowany przez jeden z węzłów pamięci SQLOS.
Idealnie, węzły pamięci SQLOS są całkowicie wyrównane z fizycznymi węzłami NUMA. Oznacza to, że każdy węzeł pamięci SQLOS zawiera pamięć z pojedynczego węzła NUMA, przy czym żaden inny węzeł pamięci SQLOS nie zawiera również pamięci z tego samego węzła NUMA.
Jednak nie zawsze jest tak idealna sytuacja.
Poniższy post na blogu CSS SQL Server Engineers (również uwzględniony w odpowiedzi Kin) szczegółowo opisuje zachowanie, które może prowadzić do utrzymywania się alokacji pamięci między węzłami NUMA dla węzłów pamięci SQLOS. Gdy tak się dzieje, wpływ na wydajność może być katastrofalny.
Wprowadzono kilka poprawek dla szczególnie bolesnego przypadku uporczywego odwołania do węzła krzyżowego NUMA. Prawdopodobnie oprócz tych dwóch również:
POPRAWKA: Problemy z wydajnością występują w środowiskach NUMA podczas przetwarzania obcych stron w SQL Server 2012 lub SQL Server 2014
Poprawka: problemy z wydajnością programu SQL Server w środowiskach NUMA
Rywalizacja o blokadę podczas przydzielania pamięci obszaru roboczego
Tutaj zaczyna się dobrze bawić. Opisałem już, że praca sortowania i mieszania w pamięci obszaru roboczego zużywa procesor, ale nie znajduje odzwierciedlenia w liczbach wyszukiwania bpool.
Spór o blokadę to kolejna warstwa tej szczególnej zabawy. Gdy pamięć zostanie skradziona z puli buforów i przydzielona do użycia z przyznaniem pamięci zapytania, dostęp do pamięci jest szeregowany za pomocą blokady. Domyślnie dzieje się tak z zasobem podzielonym na partycje na poziomie węzła NUMA. Tak więc każde zapytanie w tym samym węźle NUMA korzystającym z pamięci obszaru roboczego może potencjalnie doświadczyć rywalizacji o blokadę podczas kradzieży pamięci przeciwko grantom. Bardzo ważne, aby pamiętać: nie jest to ryzyko rywalizacji „jeden raz na zapytanie”, tak jak byłoby, gdyby punkt rywalizacji był w momencie faktycznego przyznania. Raczej jest, gdy pamięć zostaje skradziona w stosunku do grantu - więc zapytanie z bardzo dużym przydziałem pamięci będzie miało wiele możliwości rywalizacji o spinlock, jeśli wykorzysta większość grantu.
Flaga śledzenia 8048 ma świetną robotę w łagodzeniu tego sporu poprzez dalsze dzielenie zasobu na poziomie podstawowym.
Microsoft mówi „rozważ flagę śledzenia 8048, jeśli 8 lub więcej rdzeni na gniazdo”. Ale ... tak naprawdę nie chodzi o liczbę rdzeni na gniazdo (o ile jest ich wiele), ale raczej o liczbę okazji do rywalizacji w pracy wykonywanej na jednym węźle NUMA.
Na przyklejonych procesorach AMD (12 rdzeni na gniazdo, 2 węzły NUMA na gniazdo) było 6 rdzeni na węzeł NUMA. Widziałem system z 4 tymi procesorami (czyli osiem węzłów NUMA, każdy po 6 rdzeni), który został zablokowany w konwoju spinlocka do momentu włączenia flagi śledzenia 8048.
Widziałem tę rywalizację o spinlock zmniejszającą wydajność na maszynach wirtualnych tak małych jak 4 vCPU. Flaga śledzenia 8048 działała tak, jak powinna, gdy była włączona w tych systemach.
Biorąc pod uwagę, że istnieją jeszcze jakieś 4 procesory o zoptymalizowanej częstotliwości rdzeniowej, przy odpowiednim obciążeniu, skorzystaliby również z flagi śledzenia 8048.
CMEMTHREAD czeka wraz z typem sporu o blokadę, który łagodzi flagę śledzenia 8048. Ale słowo ostrzeżenia: CMEMTHREAD czeka, co potwierdza, a nie jest podstawową przyczyną tego konkretnego problemu. Widziałem systemy z dużymi „początkami oczekiwania” CMEMTHREAD, w których flaga śledzenia 8048 i / lub 9024 były opóźnione we wdrożeniu, ponieważ skumulowany czas oczekiwania CMEMTHREAD był dość krótki. W przypadku spinlocków skumulowany czas oczekiwania jest zwykle niewłaściwy. Zamiast tego chcesz spojrzeć na zmarnowany czas procesora - reprezentowany głównie przez same spiny, a następnie przez powiązane oczekiwania, które reprezentują potencjalnie niepotrzebne przełączniki kontekstu.
Przypisanie zadań do harmonogramów
W systemach NUMA połączenia są dystrybuowane do węzłów NUMA (cóż - właściwie do powiązanych z nimi grup harmonogramu SQLOS), przy założeniu, że nie ma punktów końcowych połączeń powiązanych z poszczególnymi węzłami NUMA. Jeśli sesja wykonuje zapytanie równoległe, istnieje silna preferencja do używania pracowników z jednego węzła NUMA. Hmmm ... rozważ serwer 4 węzłów NUMA ze złożonym zapytaniem podzielonym na 4 ścieżki i domyślnie 0 MAXDOP. Nawet jeśli zapytanie użyje tylko wątków roboczych MAXDOP, dla każdego logicznego procesora w węźle NUMA będą 4 wątki robocze. Ale w złożonym planie są 4 ścieżki - więc każdy logiczny procesor w węźle NUMA może mieć 16 pracowników - wszystko na jedno zapytanie!
Dlatego czasami widzisz jeden węzeł NUMA, który ciężko pracuje, podczas gdy inne są próżnujące.
Istnieje kilka innych niuansów w przypisywaniu zadań. Ale główną zaletą jest to, że procesor zajęty niekoniecznie musi być równomiernie rozłożony na węzły NUMA. (Warto również zdawać sobie sprawę, że wstawki stron bpool (odczyty lub zapisy na pierwszej stronie) trafią do puli w węźle pamięci SQLOS skojarzonym z harmonogramem, na którym działa pracownik. A skradzione strony będą pochodzić z „lokalnej” pamięci SQLOS węzeł też.
Przekonałem się, że zwiększenie maxdop od 0 do nie więcej niż 8 jest pomocne. W zależności od profilu obciążenia (głównie imo na podstawie liczby oczekiwanych równoległych zapytań potencjalnie długo działających), przejście do MAXDOP = 2 może być uzasadnione.
Pomocne może być również dostosowanie progu kosztów dla równoległości. Systemy, na których pracuję, są zwykle obciążone wysokimi kosztami i rzadko spotykam się z planem poniżej 50 lub 100, więc miałem większą przyczepność, dostosowując maxdop (często na poziomie grupy obciążenia) niż dostosowując próg kosztów.
SQL Server PLE z 8 węzłami NUMA
W tym poście omówiono kombinację sporu o blokadę wokół pamięci obszaru roboczego i nierównomiernego podziału zadań. Zobacz - te rzeczy naprawdę splatają się razem :-)
40 równoległych zapytań SQL Server + (2 gniazda * 10 rdzeni na gniazdo) = konwój spinlock
Odpowiednie umieszczanie danych w puli
Jest to warunek, który moim zdaniem jest najbardziej intuicyjny w przypadku serwerów NUMA. Zazwyczaj nie jest to szczególnie istotne dla wydajności obciążenia.
Co się stanie, jeśli tabela zostanie wczytana do puli w węźle NUMA 3, a później zapytanie w węźle NUMA 4 skanuje tabelę, wykonując wszystkie wyszukiwania puli w węzłach NUMA?
Linchi Shea ma świetny post na temat tego wpływu na wydajność:
Dostęp do pamięci w węzłach NUMA wiąże się z niewielkim dodatkowym opóźnieniem pamięci. Jestem pewien, że istnieją pewne obciążenia, które muszą wyeliminować to dodatkowe opóźnienie pamięci podstawowej w celu uzyskania optymalnej wydajności - nie było to problemem w systemach, z którymi pracuję.
Ale - dostęp między węzłami zapewnia również inny punkt transferu, który może potencjalnie zostać nasycony. Jeśli aktywność jest tak duża, że przepustowość pamięci między węzłami NUMA jest nasycona, opóźnienie pamięci między węzłami wzrośnie. Ta sama praca będzie wymagała dodatkowych cykli procesora.
Znowu - jestem pewien, że istnieją takie obciążenia, że przepustowość pamięci ma kluczowe znaczenie. Jednak w przypadku moich systemów inne rozważania, które wymieniam, były bardziej znaczące.
Umieszczenie pamięci fizycznej
Ten jest rzadki, ale kiedy ma znaczenie, naprawdę ma znaczenie. Na większości serwerów instalacja pamięci prawie naturalnie równoważy wszystkie węzły NUMA. Ale w niektórych przypadkach należy zachować szczególną ostrożność w celu zrównoważenia pamięci w węzłach. Wydajność w niektórych systemach może zostać całkowicie zmarnowana, jeśli pamięć została tak rozmieszczona, że nie jest zrównoważona. Jest to jednak ustawione i zapomnij. Dość rzadkie jest wykrycie takiego problemu po miesiącach pracy w produkcji, a nie po pierwszym naprawdę pracowitym dniu :-)
WIELKIE WYKOŃCZENIE!
Ktoś inny zauważył, że zły wybór planu, być może z powodu nieaktualnych statystyk, może powodować objawy, które widziałeś. Z mojego doświadczenia tak nie było. Złe plany mogą sprawić, że zapytanie zajmie więcej czasu niż oczekiwano - ale zwykle dlatego, że wykonywane są bardziej logiczne operacje wejścia / wyjścia niż to konieczne. Lub z powodu wycieku do tempdb. Ogromny wyciek do tempdb powinien być widoczny podczas obserwowania serwera - i zamiast wysokiego procesora można oczekiwać mierzalnego czasu oczekiwania na zapis dysku związany z wyciekami.
Zamiast tego, jeśli obserwowana przez ciebie sytuacja jest związana z NUMA, spodziewam się, że będzie to kombinacja czynników wymienionych powyżej, głównie:
wykorzystanie pamięci obszaru roboczego (która nie pojawi się w logicznych liczbach operacji we / wy)
który może być węzłem krzyżowym NUMA z powodu trwałego stanu pamięci obcej (w takim przypadku poszukaj odpowiednich poprawek)
i które mogą pociągać za sobą spór o blokadę w węźle NUMA za każdym razem, gdy dokonywany jest przydział dla dotacji (poprawka w T8048)
i mogą być wykonywane przez pracowników na logicznych procesorach przeciążonych przez innych równoległych pracowników zapytania (w razie potrzeby dostosuj maxdop i / lub próg kosztu równoległości)
źródło
( zaktualizuj swoje pytanie o
coreinfo -v
dane wyjściowe (narzędzie sysinternal), aby uzyskać lepszy kontekst procesora / gniazd i dystrybucji NUMA )Wydaje mi się, że szczekasz na niewłaściwe drzewo. SQL Server jest
NUMA
świadomy. Jest znacznie mniejszy spadek wydajności za dostęp do pamięci krzyżowej NUMA . Możesz również użyć tego zapytania, aby zobaczyć, ileNUMA
masz węzłów i do których procesorów i rdzeni są przypisaneNUMA
:Lub po prostu ile
NUMA
:Zwykle dzieje się tak, gdy generowane są złe plany zapytań z powodu nieaktualnych statystyk. Upewnij się, że masz zaktualizowane statystyki, a indeksy są poprawnie defragmentowane .
Musisz także ustawić MAXDOP na bardziej rozsądną wartość, aby uniknąć głodu wątków roboczych .
Ustaw
cost threshold of parallelism
domyślną wartość 5 na dobrą wartość początkową, taką jak 45, a następnie monitoruj tę wartość i dostosuj ją do swojego środowiska.Jeśli wykonujesz wiele zapytań adhoc, włącz (ustaw na 1),
optimize for ad hoc workloads
aby zapobiec rozdęciu pamięci podręcznej planu.Używaj ostrożnie: możesz używać T8048, jeśli korzystasz z SQL Server 2008/2008 R2 na nowszych komputerach z prezentacją więcej niż 8 procesorów na węzeł NUMA, a jeśli korzystasz z SQL Server 2012 lub 2014, istnieje poprawka .
Zdecydowanie zalecamy rozpoczęcie zbierania informacji o statystykach Wait dotyczących instancji serwera bazy danych.
Patrz: Jak to działa: SQL Server (bloki pamięci lokalnej, zagranicznej i wyjazdowej NUMA)
źródło
Z punktu widzenia sprzętowego zarządzanie pamięcią główną od architektury Nehalem jest zarządzane przez zintegrowany kontroler pamięci, jest to część „nie-rdzeniowa” matrycy procesora, która jest oddzielona od części, na której żyją rzeczywiste rdzenie, ponieważ pamięć jest skutecznie „Przewodowa” dla każdego procesora, dostęp do pamięci zagranicznej AFAIK odbywa się za pośrednictwem szybkiego połączenia (ponownie od Nehalem i dalej), dlatego powiedziałbym, że nasycenie rdzenia procesora w lokalnym węźle NUMA nie powinno wpływać na zdalny dostęp do tej pamięci.
Ten link może być przydatny:
http://cs.nyu.edu/~lerner/spring10/projects/NUMA.pdf
Chris
źródło