
In diesem Artikel erklären wir Ihnen, wie man einen Scheduler Deadlock löst und die Threadpool Wartezeit verkürzen kann. Bevor wir jedoch zu den Lösungen kommen, wollen wir zuerst auf die Funktionsweise eines SOS Schedulers näher eingehen.
Begriffsdefinition
Wir beginnen mit dem SOS Scheduler (SQL on OS Scheduler). Dieser ist dafür verantwortlich, eingehende Tasks des Client anzunehmen und die Bearbeitung einzuleiten. Dabei agiert er als Master - was bedeutet, dass er nicht selbst Aufgaben ausführt, sondern diese an Worker Threads abgibt. Jeder Worker Thread erhält eine Teilaufgabe und soll diese anschließend ausführen. Jedoch kann immer nur genau ein Thread auf einmal auf die CPU zugreifen. Daher wird der Zugriff mit dem Prinzip First-In-First-Out geregelt.
Wenn wir von Worker Threads sprechen, denkt man vielleicht an “normale” Threads. Jedoch gibt es hier eine Unterscheidung. Die Worker Threads sind ein Konstrukt des Schedulers. Sie sind aufgebaut wie Threads, enthalten aber noch weitaus mehr Informationen zu dem System. Das hilft dabei, dass ein Kontextwechsel nicht notwendig ist. Jedoch lässt sich genau ein Worker auf genau einen Thread abbilden.
Exkurs: Kontextwechsel
Ein Kontextwechsel tritt ein, wenn ein Thread nicht fertig gestellt werden kann, da auf neue Dateien gewartet werden muss. In der Zwischenzeit würde jedoch Zeit verschwendet werden, in der die CPU nicht arbeitet. Aus diesem Grund wird einem anderen Thread Zugang gewährt. Um den Fortschritt des ursprünglichen Threads nicht zu verlieren, wird dieser gespeichert. Sobald dieser Thread wieder weiter arbeiten kann, wird der entsprechende Status geladen und an derselben Stelle wieder weiter ausgeführt. Dieses Speichern und Laden nennt man einen Kontextwechsel.
Eine Task ist eine Aufgabe auf der Ebene des Schedulers. Beispiele dafür sind Queries, Login oder Logout Events. Der Scheduler erhält diese Task und zerlegt sie in kleinere Aufgaben. Da jede Teilaufgabe einem Worker übergeben wird, besitzt jede Task unterschiedliche Kosten. Die Verteilung von Worker Threads schauen wir uns später an.
Leistungspakete der Mainzer Datenfabrik
Als professioneller SQL Server Support und zertifizierter Microsoft Partner unterstützen wir Sie in allen Fragen und individuellen Problemen rund um Ihre Serverumgebung, egal ob vor Ort oder remote. Überzeugen Sie sich selbst von unserem vielfältigen Angebot und den individuellen Leistungspaketen.
Beispielhafter Ablauf
Wie sieht nun ein Ablauf mit einem SOS Scheduler auf der Serverebene aus?
Zunächst muss eine physische Verbindung zwischen Client und Server hergestellt werden. Hierfür stellt der Client eine Login Request, die an den Scheduler geht. Dieser verarbeitet die Anfrage und schickt eine Confirmation, wenn der Login korrekt ist. Mit dem erfolgreichen Login startet der Server eine neue Session mit dem Client. In diesem Schritt wird eine SessionID zugewiesen. Diese hilft dabei, gestellte Tasks wieder dem Client zuzuordnen und somit einen Überblick über die Tasks zu bewahren. In dem Fall, dass von zwei Clients dieselbe Task gestellt wird, können beide Vorgänge anhand der SessionID identifiziert werden.
Besteht nun eine aktive Session zwischen Client und Server, kann der Client Tasks stellen. Diese werden an den Scheduler geschickt. Er verarbeitet die Anfrage und macht eine Kostenberechnung. Es wird danach geschaut, welche Teilaufgaben mit der gestellten Task anfallen und wie viele Worker Threads dafür benötigt werden. Hat der Scheduler nicht genügend Threads, befindet sich aber noch unter seinem maximalen Limit an erlaubten Workern, erstellt er sich die benötigte Menge. Kann er nicht genügend Worker erstellen, kommt es zu einem Threadpool Wait. Darauf gehen wir später genauer ein.
Innerhalb des Scheduler sieht es demnach folgendermaßen aus: Es gibt eine Liste mit Threads, die erledigt werden können, auch Runnable Queue genannt. In dieser Liste befinden sich alle Threads die den Status RUNNABLE
haben. Wenn die CPU frei ist, wechselt der erste Thread in der Liste zu RUNNING
und führt seine Task aus. Wenn er während der Bearbeitung feststellt, dass ihm noch Daten fehlen, oder er nicht weitermachen kann, wechselt er in einen SUSPENDED
Status und wird in eine Waiting Liste geschoben. Hier befinden sich alle Threads, die momentan nicht alle Ressourcen besitzen, um mit ihrer Bearbeitung weitermachen zu können. Steht jetzt die fehlende Datei zur Verfügung, wechselt der Thread erneut den Status zu RUNNABLE
und wird an das Ende der Runnable Queue gesetzt. Dort muss er warten, bis er an der Reihe ist, um auf die CPU zuzugreifen. Schließt er seine Aufgabe ab, wird der Worker wieder abgebaut, also gelöscht.
Scheduler
Bisher wurde immer vom SOS Scheduler gesprochen, aber wie unterscheidet dieser sich vom Scheduler des Betriebssystems und warum nutzen wir diesen nicht?
Jedes Betriebssystem hat einen Scheduler, der wie oben schon erwähnt, die anfallenden Tasks managed. Diese Scheduler arbeiten preemptive. Das heißt, dass der Scheduler in den Ablauf der arbeitenden Threads eingreifen kann. Das Grundprinzip bleibt beim First-In-First-Out, jedoch kann der Scheduler Tasks mit höherer Wichtigkeit in den Vordergrund schieben. Dafür wird der aktuelle Thread pausiert und von dem Priorisierten abgelöst. Außerdem erhält jeder Thread eine Zeit, in der die Aufgabe zu erledigen ist. Wird diese Zeit überschritten, macht der Thread Platz und muss warten, bis er wieder an der Reihe ist.
Es kann daher vorkommen, dass manche Threads kurz vor der Fertigstellung ihrer Aufgabe sind, aber trotzdem ihren Platz an der CPU aufgeben müssen. Im Gegensatz kann es dazu kommen, dass der Thread zu Beginn nicht alle Ressourcen besitzt und somit seine Zeit “absitzt”, ohne dass irgendeine Arbeit ausgeführt wird. Darum ist das System der CPU Nutzung nicht optimal für SQL Server. Stattdessen wird ein non-preemptive Prinzip benutzt: Der Scheduler ist davon abhängig, dass jeder Thread freiwillig seinen Platz wieder hergibt. So kann die CPU besser genutzt werden. Denn wenn ein Thread noch nicht arbeiten kann, gibt er seinen Zugriff ab und ein anderer kann in der Zwischenzeit seine Aufgabe erledigen.