Beeinflusst die CPU-Auslastung die Kosten für den ausländischen NUMA-Zugriff?

21

Szenario

Angenommen, ich habe einen SQL Server mit 4 Sockets mit jeweils 1 NUMA-Knoten. Jeder Sockel verfügt über 4 physische Kerne. Insgesamt sind 512 GB Arbeitsspeicher vorhanden, sodass jeder NUMA-Knoten über 128 GB RAM verfügt.

Eine Schlüsseltabelle wird in den ersten NUMA-Knoten geladen.

Frage

Nehmen wir an, wir haben viel Verkehr, der von dieser Tabelle gelesen wird. Wenn alle physischen Kerne des Sockets, dem der NUMA-Knoten gehört, eine 100-prozentige CPU-Auslastung aufweisen, hat dies einen negativen Einfluss auf die Kosten für den nicht lokalen NUMA-Zugriff von anderen Sockets aus? Oder sind die Kosten für den nicht-lokalen NUMA-Zugriff unabhängig von der Auslastung dieses Sockets?

Ich hoffe meine Frage macht Sinn. Bitte lassen Sie mich wissen, wenn dies nicht der Fall ist. Ich werde versuchen, dies zu klären.

Hintergrund

Wir hatten letzte Woche ein Datenbankproblem auf unserem Produktionsserver und einige unserer verarbeiteten Geschäfte schienen stärker betroffen zu sein als andere. Wir hatten Abfragen mit wenigen logischen Lesevorgängen, die länger als 1 Minute dauerten. Wir haben uns die CPU-Auslastung angesehen, die bei rund 60 Prozent lag. Wir haben uns keine sockelspezifischen CPU-Metriken angesehen. Die E / A-Metriken waren durchschnittlich.

xav
quelle
Wenn Sie so etwas produzieren können, wie Kin es erwähnt hat, ist es hilfreich. Auf was hast du MAXDOP eingestellt?
user41207

Antworten:

18

Eine heftige Frage :-) Ich werde einige der beteiligten Faktoren skizzieren. In jedem gegebenen Kontext können diese und andere Faktoren variieren und ein interessantes Ergebnis liefern.

Entschuldigung, ich konnte das nicht viel kürzer machen ...

  1. Akkumulierte CPU-ms im Vergleich zu logischem E / A
  2. Ausrichtung des logischen SQL Server-Speicherknotens mit physischen NUMA-Knoten
  3. Spinlock-Konflikt bei der Speicherzuweisung für den Abfrage-Arbeitsbereich
  4. Aufgabenzuweisung an Scheduler
  5. Relevante Datenplatzierung im Pufferpool
  6. Platzierung des physischen Speichers

  1. Akkumulierte CPU-ms im Vergleich zu logischem E / A

    Ich verwende sehr oft logische E / A-Diagramme (oder in der Perfmon-Terminologie "Buffer Pool Page Lookups") gegen die CPU-Auslastung, um die CPU-Effizienz von Workloads zu messen und nach Spinlock-anfälligen Fällen zu suchen.

    In SQL Server wird jedoch CPU-Zeit mit vielen anderen Aktivitäten als Seitensuchen und Spinlocks angesammelt:

    • Pläne werden kompiliert und neu kompiliert.
    • CLR-Code wird ausgeführt.
    • Funktionen ausgeführt werden.

    Bei vielen anderen Aktivitäten wird eine erhebliche CPU-Zeit verbraucht, ohne dass dies in den Seitensuchen berücksichtigt wird.

    Bei den Workloads, die ich beobachte, ist die Sortier- / Hashing-Aktivität der Hauptbestandteil dieser "nicht logischen IO-intensiven, aber CPU-verschlingenden" Aktivitäten.

    Es liegt auf der Hand: Betrachten Sie ein konstruiertes Beispiel für zwei Abfragen gegen eine Hash-Tabelle ohne nicht gruppierte Indizes. Die beiden Abfragen haben identische Ergebnismengen, aber eine der Ergebnismengen ist völlig ungeordnet und die zweite Ergebnismenge ist nach mehr als einer der ausgewählten Spalten geordnet. Es wird erwartet, dass die zweite Abfrage mehr CPU-Zeit beansprucht, obwohl sie auf die gleiche Anzahl von Seiten im Pufferpool verweist.

    Weitere Informationen zum Arbeitsspeicher und zur Verwendung des zugewiesenen Arbeitsspeichers finden Sie in den folgenden Beiträgen:


  1. Ausrichtung des logischen SQL Server-Speicherknotens mit physischen NUMA-Knoten

    SQL Server erstellt (seit der Integration seiner NUMA-fähigen Strategien) standardmäßig einen SQLOS-Speicherknoten für jeden NUMA-Knoten auf dem Server. Wenn die Speicherzuweisungen zunehmen, wird jede Zuordnung von einem der SQLOS-Speicherknoten gesteuert.

    Im Idealfall sind die SQLOS-Speicherknoten vollständig auf die physischen NUMA-Knoten ausgerichtet. Das heißt, jeder SQLOS-Speicherknoten enthält Speicher von einem einzelnen NUMA-Knoten, wobei kein anderer SQLOS-Speicherknoten ebenfalls Speicher von demselben NUMA-Knoten enthält.

    Diese ideale Situation ist jedoch nicht immer der Fall.

    Der folgende Blogeintrag von CSS SQL Server Engineers (ebenfalls in Kins Antwort enthalten) beschreibt das Verhalten, das dazu führen kann, dass die Speicherzuordnungen für die SQLOS-Speicherknoten NUMA-übergreifend beibehalten werden. In diesem Fall können die Auswirkungen auf die Leistung verheerend sein.

    Es wurden einige Korrekturen für den besonders schmerzhaften Fall einer dauerhaften NUMA-übergreifenden Knotenreferenz vorgenommen. Wahrscheinlich auch andere zusätzlich zu diesen beiden:


  1. Spinlock-Konflikt während der Zuweisung von Arbeitsspeicher

    Hier fängt es an, Spaß zu haben. Ich habe bereits beschrieben, dass die Sortier- und Hash-Arbeit im Arbeitsspeicher die CPU beansprucht, sich jedoch nicht in den bpool-Lookup-Nummern widerspiegelt.

    Spinlock-Streit ist eine weitere Ebene für diesen besonderen Spaß. Wenn Speicher aus dem Pufferpool gestohlen und für die Verwendung mit einer Speicherzuweisung für Abfragen zugewiesen wird, wird der Speicherzugriff mit einem Spinlock serialisiert. Dies erfolgt standardmäßig mit einer Ressource, die auf NUMA-Knotenebene partitioniert ist. Daher kann es bei jeder Abfrage auf demselben NUMA-Knoten, der Arbeitsspeicher verwendet, zu Spinlock-Konflikten kommen, wenn Speicher gegen Berechtigungen gestohlen wird. Sehr wichtig zu beachten: Dies ist kein Konfliktrisiko "einmal pro Abfrage", da dies der Fall wäre, wenn der Streitpunkt zum Zeitpunkt der tatsächlichen Gewährung wäre. Eher ist es, wenn Speicher gegen die Bewilligung gestohlen wird - so hat eine Abfrage mit einer sehr großen Speicherbewilligung viele Möglichkeiten für Spinlock-Konflikte, wenn sie den größten Teil ihrer Bewilligung verwendet.

    Das Ablaufverfolgungsflag 8048 leistet einen hervorragenden Beitrag zur Beseitigung dieses Konflikts, indem die Ressource auf der Kernebene weiter partitioniert wird.

    Microsoft sagt "Trace-Flag 8048 berücksichtigen, wenn 8 oder mehr Kerne pro Socket". Aber ... es ist nicht wirklich die Anzahl der Kerne pro Socket (solange es mehrere gibt), sondern vielmehr die Anzahl der Konfliktmöglichkeiten bei der Arbeit an einem einzelnen NUMA-Knoten.

    Auf den geklebten AMD-Prozessoren (12 Kerne pro Sockel, 2 NUMA-Knoten pro Sockel) befanden sich 6 Kerne pro NUMA-Knoten. Ich sah ein System mit 4 dieser CPUs (also acht NUMA-Knoten, jeweils 6 Kerne), das im Spinlock-Konvoi blockiert war, bis das Ablaufverfolgungsflag 8048 aktiviert wurde.

    Ich habe gesehen, dass dieser Spinlock-Konflikt die Leistung auf VMs mit nur 4 vCPUs beeinträchtigt. Das Trace-Flag 8048 hat genau das getan, was es sollte, wenn es auf diesen Systemen aktiviert wurde.

    In Anbetracht der Tatsache, dass es immer noch 4 frequenzoptimierte CPUs mit der richtigen Auslastung gibt, würden sie auch vom Trace-Flag 8048 profitieren.

    CMEMTHREAD-Wartezeiten begleiten die Art der Spinlock-Konflikte, die das Ablaufverfolgungsflag 8048 lindert. Aber Vorsicht: CMEMTHREAD-Wartezeiten sind ein bestätigendes Symptom und keine Grundursache für dieses spezielle Problem. Ich habe Systeme mit hohen CMEMTHREAD-Wartezeiten gesehen, bei denen das Ablaufverfolgungsflag 8048 und / oder 9024 bei der Bereitstellung verzögert wurden, weil die akkumulierte CMEMTHREAD-Wartezeit ziemlich niedrig war. Bei Spinlocks ist die angesammelte Wartezeit in der Regel das Falsche. Sie möchten sich eher die verschwendete CPU-Zeit ansehen - dargestellt in erster Linie durch die Spins selbst, in zweiter Linie durch die damit verbundenen Wartezeiten, die potenziell unnötige Kontextwechsel darstellen.


  1. Aufgabenzuweisung an Scheduler

    Auf NUMA-Systemen werden Verbindungen auf NUMA-Knoten verteilt (und zwar auf die ihnen zugeordneten SQLOS-Scheduler-Gruppen), vorausgesetzt, es gibt keine Verbindungsendpunkte, die bestimmten NUMA-Knoten zugeordnet sind. Wenn eine Sitzung eine parallele Abfrage ausführt, werden nachdrücklich Worker von einem einzelnen NUMA-Knoten verwendet. Hmmm ... Betrachten Sie einen 4-NUMA-Knotenserver mit einer komplexen Abfrage, die in 4 Pfade unterteilt ist, und dem Standardwert 0 MAXDOP. Selbst wenn die Abfrage nur MAXDOP-Arbeitsthreads verwendet, gibt es 4 Arbeitsthreads für jede logische CPU auf dem NUMA-Knoten. Der komplexe Plan enthält jedoch vier Pfade, sodass auf jeder logischen CPU des NUMA-Knotens 16 Worker installiert sein können - alles für eine einzelne Abfrage!

    Aus diesem Grund werden Sie manchmal einen NUMA-Knoten sehen, der hart arbeitet, während andere herumlungern.

    Es gibt ein paar andere Nuancen bei der Aufgabenzuweisung. Das Wichtigste ist jedoch, dass die ausgelastete CPU nicht unbedingt gleichmäßig auf die NUMA-Knoten verteilt wird. (Gut zu wissen, dass Bpool-Seiteneinfügungen (Lesen oder Schreiben der ersten Seite) in den Bpool des SQLOS-Speicherknotens gelangen, der dem Scheduler zugeordnet ist, auf dem sich der Worker befindet. Die gestohlenen Seiten stammen vorzugsweise aus dem "lokalen" SQLOS-Speicher Knoten auch.

    Ich habe festgestellt, dass es hilfreich ist, maxdop von 0 auf nicht mehr als 8 zu bringen. Abhängig vom Workload-Profil (in erster Linie abhängig von der Anzahl der gleichzeitig zu erwartenden potenziell lang andauernden Abfragen) kann es gerechtfertigt sein, MAXDOP = 2 zu erreichen.

    Das Anpassen der Kostenschwelle für Parallelität kann ebenfalls hilfreich sein. Systeme, an denen ich arbeite, sind in der Regel mit hohen Kosten verbunden und stoßen selten auf einen Plan unter 50 oder 100. Ich habe also mehr Traktion durch Anpassen von maxdop (oten auf Workload-Gruppenebene) als durch Anpassen des Kostenschwellenwerts.


  1. Relevante Datenplatzierung im bpool

    Dies ist die Bedingung, die meiner Meinung nach am intuitivsten ist, wenn es um NUMA-Server geht. Es ist auch in der Regel nicht sehr wichtig für die Leistung der Workload.

    Was passiert, wenn die Tabelle auf NUMA-Knoten 3 in den Pool eingelesen wird und später eine Abfrage auf NUMA-Knoten 4 die Tabelle durchsucht und alle Pool-Lookups auf NUMA-Knoten durchführt?

    Linchi Shea hat einen großartigen Beitrag zu diesen Auswirkungen auf die Leistung:

    Der Zugriff auf Speicher über NUMA-Knoten hinweg verursacht eine geringe zusätzliche Speicherlatenz. Ich bin mir sicher, dass es einige Workloads gibt, die diese zusätzliche Basisspeicherlatenz für eine optimale Leistung beseitigen müssen - auf den Systemen, mit denen ich arbeite, war dies kein Problem.

    Der knotenübergreifende Zugriff bringt jedoch auch einen anderen Übertragungspunkt mit sich, der möglicherweise überlastet sein kann. Wenn so viel Aktivität vorhanden ist, dass die Speicherbandbreite zwischen NUMA-Knoten voll ist, erhöht sich die Speicherlatenz zwischen den Knoten. Dieselbe Arbeit erfordert zusätzliche CPU-Zyklen.

    Ich bin mir sicher, dass es Workloads gibt, bei denen die Speicherbandbreite eine wichtige Rolle spielt. Für meine Systeme waren die anderen Überlegungen, die ich aufführe, wichtiger.


  1. Platzierung des physischen Speichers

    Dieser ist selten, aber wenn es darauf ankommt, ist es wirklich wichtig. Auf den meisten Servern wird die Speicherinstallation normalerweise auf die NUMA-Knoten verteilt. In einigen Fällen ist jedoch besondere Aufmerksamkeit erforderlich, um den Speicher über die Knoten zu verteilen. Die Leistung in einigen Systemen kann absolut beeinträchtigt werden, wenn der Speicher so gesteckt wurde, dass er nicht ausgeglichen ist. Dies ist jedoch das Festlegen und Vergessen. Es ist ziemlich selten, ein Problem wie dieses nach Monaten des Produktionsdienstes zu entdecken, im Gegensatz zu dem nach dem ersten wirklich anstrengenden Tag :-)


DAS GROSSE FINISH!

Jemand anderes hat darauf hingewiesen, dass eine schlechte Planauswahl, möglicherweise aufgrund veralteter Statistiken, zu den Symptomen führen kann, die Sie gesehen haben. Das war meiner Erfahrung nach nicht der Fall. Bei schlechten Plänen kann eine Abfrage leicht länger dauern als erwartet - in der Regel jedoch, weil mehr logische E / A-Vorgänge als erforderlich ausgeführt werden. Oder aufgrund von Überlauf zu tempdb. Bei der Beobachtung des Servers sollte eine massive Verschüttung von Tempdb offensichtlich sein - und statt einer hohen CPU würde man eine messbare Wartezeit auf die verschütteten Festplattenschreibvorgänge erwarten.

Wenn die beobachtete Situation NUMA-bezogen ist, würde ich eher erwarten, dass es sich um eine Kombination der oben aufgeführten Faktoren handelt, hauptsächlich:

  1. Verwendung des Arbeitsspeichers (der nicht in logischen E / A-Zählungen angezeigt wird)

  2. Dies kann ein NUMA-übergreifender Knoten sein, da der Zustand des Fremdspeichers weiterhin besteht (in diesem Fall suchen Sie nach relevanten Korrekturen).

  3. und die jedes Mal, wenn eine Zuweisung gegen eine Bewilligung vorgenommen wird, einen Spinlock-Konflikt innerhalb des NUMA-Knotens verursachen können (behoben mit T8048)

  4. und kann von Workern auf logischen CPUs ausgeführt werden, die von anderen parallelen Abfrage-Workern überlastet sind (passen Sie den Maxdop- und / oder Kostenschwellenwert der Parallelität nach Bedarf an).

sql_handle
quelle
7

( Bitte aktualisieren Sie Ihre Frage mit einer coreinfo -v(systeminternen) Ausgabe, um einen besseren Kontext Ihrer CPU / Sockel und NUMA-Verteilung zu erhalten. )

Wir haben uns die CPU-Auslastung angesehen, die bei rund 60 Prozent lag. Wir haben uns keine sockelspezifischen CPU-Metriken angesehen. Die E / A-Metriken waren durchschnittlich.

Scheint mir, dass Sie am falschen Baum bellen. SQL Server ist NUMAbekannt. Es gibt viel geringere Leistungseinbußen für den NUMA-übergreifenden Speicherzugriff . Mit dieser Abfrage können Sie auch sehen, wie viele NUMAKnoten Sie haben und welche CPU und Kerne welchen zugewiesen sind NUMA:

SELECT parent_node_id, scheduler_id, cpu_id
FROM sys.dm_os_schedulers WITH (NOLOCK) 
WHERE [status] = N'VISIBLE ONLINE';

Oder wie viele NUMA:

select COUNT(distinct Parent_node_id)
from sys.dm_os_schedulers
where [STATUS] = 'VISIBLE ONLINE'
    and Parent_node_ID < 64

Wir hatten Abfragen mit wenigen logischen Lesevorgängen, die länger als 1 Minute dauerten.

Dies ist normalerweise der Fall, wenn aufgrund veralteter Statistiken falsche Abfragepläne erstellt wurden. Stellen Sie sicher, dass Ihre Statistiken aktualisiert und Ihre Indizes ordnungsgemäß defragmentiert sind .

Außerdem müssen Sie MAXDOP auf einen vernünftigeren Wert setzen , um das Verhungern von Worker-Threads zu vermeiden .

Setzen Sie den cost threshold of parallelismStandardwert von 5 auf einen guten Startwert wie 45, überwachen Sie diesen Wert und passen Sie ihn entsprechend Ihrer Umgebung an.

Wenn Sie viele Ad-hoc-Abfragen ausführen, aktivieren Sie diese Option (auf 1 gesetzt) optimize for ad hoc workloads, um ein Aufblähen des Plan-Cache zu verhindern.

Vorsicht: Sie können T8048 verwenden, wenn Sie SQL Server 2008/2008 R2 auf neueren Computern mit mehr als 8 CPUs pro NUMA-Knoten ausführen. Wenn Sie SQL Server 2012 oder 2014 verwenden, gibt es einen Hotfix .

Es wird dringend empfohlen, mit dem Sammeln von Wartestatistikinformationen zu Ihrer Datenbankserverinstanz zu beginnen .

Siehe: Wie es funktioniert: SQL Server (NUMA Lokale, Außen- und Auswärts Speicherblocks)

Kin Shah
quelle
1

Die Verwaltung des Hauptspeichers von der Nehalem-Architektur an erfolgt rein hardwaremäßig über einen integrierten Speichercontroller. Dieser befindet sich auf dem "Un-Core" -Teil des CPU-Chips, der von dem Teil getrennt ist, auf dem die eigentlichen Kerne leben. Da der Speicher effektiv mit jeder CPU 'verdrahtet' ist, erfolgt der Zugriff auf den Fremdspeicher AFAIK über die Schnellverbindung (erneut ab Nehalem). Ich würde daher sagen, dass die CPU-Kernsättigung auf einem lokalen NUMA-Knoten den Fernzugriff auf diesen Speicher nicht beeinträchtigen sollte.

Möglicherweise finden Sie diesen Link nützlich:

http://cs.nyu.edu/~lerner/spring10/projects/NUMA.pdf

Chris

Chris Adkin
quelle