SMO und SSMS sind für die Verwaltung von SQL Server in Docker beim Herstellen einer Verbindung zu localhost langsam

9

TL; DR: Wenn Sie über einen Namen, der in IPv6-Loopback ( ::1) aufgelöst wird, eine Verbindung zu meinem SQL Server Docker-Container herstellen , sind SMO-Aufrufe sehr langsam. Bei der Verwendung 127.0.0.1sind sie schnell.


Ich versuche zu lernen, wie man das Docker-Bild Microsoft / MSSQL-Server-Windows-Entwickler verwendet . Gemäß der Microsoft-Dokumentation macht dieser Container nur Port 1433 TCP verfügbar.

docker run -d -p 1433:1433 -e sa_password=Passw0rd! -e ACCEPT_EULA=Y -v C:\dockerdb:C:\dockerdb microsoft/mssql-server-windows-developer

Ich führe den Container unter Windows 10 aus und habe ihn erfolgreich gestartet, mich mit SQL Server-Authentifizierung authentifiziert und Abfragen für die Instanz mit sqlcmd und SSMS 17.4 auf dem Windows-Host (Verbindung zu localhost oder ".") Und SQL Operations ausgeführt Studio auf einem Mac nebenan per IP-Verbindung. Ich sehe keine erkennbaren Leistungsprobleme, wenn Abfragen auf diese Weise ausgeführt werden.

In SSMS kann ich auch den Objekt-Explorer durchsuchen. Wenn ich jedoch versuche, über das Kontextmenü eines Objekts im Objekt-Explorer etwas zu tun, z. B. das Fenster mit den Instanzparametern zu öffnen oder eine Datenbank anzuhängen, zeigt SSMS für etwa 5 keine Antwort an -10 Minuten. Zu diesem Zeitpunkt wird entweder das von mir angeforderte Fenster oder die folgende Fehlermeldung angezeigt:

SSMS-Fehlermeldung

Ich versuche auch, mithilfe des SMO Scripter-Objekts PowerShell-Skripte für diese Instanz auszuführen und sehe dasselbe Verhalten. Das PS-Skript durchläuft Objekte in der Datenbank und schreibt sie in eine Datei. Während es die Liste der Objekte relativ schnell erfasst, dauert das Skript für jedes einzelne Objekt 5 bis 10 Minuten - zu langsam, um verwendet werden zu können.

Ich habe die Vermutung, dass der einzelne exponierte Port nicht ausreicht und dass SMO und SSMS versuchen, eine Verbindung auf eine ähnliche Weise herzustellen, die sie verlangsamt. Könnte es auch sein, dass diese Tools bei der Verbindung mit localhost davon ausgehen, dass andere Kommunikationskanäle vorhanden sind, die normalerweise nicht durch eine Firewall geschützt sind? Gibt es zusätzliche Verbindungsparameter, die ich verwenden könnte? Kann jemand meine Annahme bestätigen, dass SSMS SMO oder etwas anderes verwendet, um mit SQL Server zu kommunizieren?


UPDATE: Ich untersuche noch, aber es ist plausibel, dass dies ein Docker-Problem im Zusammenhang mit Ressourcenbeschränkungen ist. Dies ist verwirrend, da die meisten Dokumentationen darauf hinweisen, dass Windows-Container keine Standardressourcenbeschränkungen haben (und diese können nicht in der Docker für Windows-GUI festgelegt werden - nur für Linux-Container ), aber es scheint, dass in Wirklichkeit Windows Container, die unter Windows 10 ausgeführt werden, erhalten eine Standard-RAM-Zuweisung von 1 GB. Ich versuche immer noch herauszufinden, wie ein laufender Container auf seine RAM- und CPU-Zuordnung überprüft werden kann, aber als nächstes muss ich nur versuchen, diese mithilfe von docker runParametern von den Standardeinstellungen zu erhöhen .


WEITERES UPDATE: Ich habe keine zuverlässige Metrik aus Docker erhalten, die mir sagt, welche CPU- und Speicherbeschränkungen für den Container gelten. Forschung Wechselnde zeigt an, dass entweder Docker - Container, kein Speicherlimit standardmäßig haben oder dass sie tun und es ist 1 GB, aber alles , was ich im Moment überprüfen kann , ist , dass docker statssagt der SQL Container nur mit zwischen 750 und 850 meg, und wenn Ich versuche, einen Run-Parameter hinzuzufügen, um den verfügbaren Speicher auf 4 GB zu setzen. Also hörte ich diesen Faden der Untersuchung folgenden und für eine andere gut Prüfung ging: eine interaktive Powershell - Sitzung auf den laufenden Behälter eintreten und dann mein Powershell - Skript oben aus verknüpften Aufrufen innerhalb des Behälters.

Beim Laufen im Container gab es kein Problem. Es blitzte in nur wenigen Minuten durch 2780 Objekte. Ich denke, dies bestätigt, dass das Problem bei der Container / Host-Grenze liegt, also werde ich sehen, ob ich diesen UDP-Port öffnen kann. UPDATE: Das Öffnen von Port 1434 UDP hat nicht geholfen.


MEHR UPDATES - Problemumgehung erreicht, kein Problem mit Ressourcenbeschränkungen: Es scheint Probleme im Zusammenhang mit dem Festlegen großer Speicherzuordnungen für Windows-Container zu geben. Ich habe ähnliche Fehler für 3g und 2g erhalten, konnte den Container jedoch schließlich mit 1,5g und starten Ich habe einen Unterschied in dem docker statsfür den Container festgestellt, der (glaube ich) bestätigt, dass er mit einer Standardzuweisung von 1 GB ausgeführt wurde. In den Standardeinstellungen liegt der PRIV WORKING SET-Status (für den ich keine Dokumentation finden kann, aber ich vermute, dass es sich um RAM handelt) zwischen 700 MB und 850 MB. Mitdocker run —memory="1.5g"eingestellt, ist es um 1.0GiB. Es hat sich also erweitert, scheint aber mehr von der Zuteilung frei zu lassen als zuvor. Ich interpretiere dies (möglicherweise falsch) so, dass dieser Server (der absolut KEINE Last ausführt und KEINE Benutzerdatenbanken hat) nicht unter Speicherdruck steht. Ich habe die maximale Serverspeichereinstellung überprüft, um zu bestätigen, dass sie auf das Standardmaximum von 2PiB eingestellt ist.

Dann wurde es komisch. Ich teste immer noch Dinge, indem ich mein Powershell-Skript an verschiedenen Orten ausführe. Schnell im Container, langsam auf dem Host. Dann habe ich RDP auf einen anderen Windows-Computer im Netzwerk übertragen und das Skript von DIESEM Computer ausgeführt und über IP eine Verbindung zu meinem Windows 10-Host hergestellt. Und es war SCHNELL! Dies scheint die Theorie zu stützen, dass SMO beim Herstellen einer Verbindung zu einem lokalen Host versucht, eine Verbindung zu SQL Server über etwas anderes als Port 1433 TCP herzustellen, das auf eine sehr lange Zeitüberschreitung wartet, bevor es auf die TCP-Verbindung zurückgreift.

Ich habe mich entschlossen, diese Theorie zu validieren, indem ich einen Hosts-Dateieintrag eingegeben habe, um auf localhost mit einem anderen Namen als localhost zu verweisen:

        127.0.0.1       dockersucks

Ich habe mich in SSMS mit Dockersucks anstelle von localhost oder "." Verbunden, und sofort ging es schneller. Das Navigieren im Objekt-Explorer verlief wie gewohnt, und das Öffnen von Bedienfeldern wie Anhängen von Datenbank- oder Servereigenschaften erfolgte so schnell wie normal. Und als ich mein Powershell-Skript vom Windows 10-Host aus mit diesem Alias ​​als Servernamen ausführte, war es auch schnell.

Ich habe dieses Update anstelle einer Antwort zur Frage hinzugefügt, da ich immer noch nach einer Erklärung suche, warum dies geschieht und ob es eine Möglichkeit gibt, es für Verbindungen zu "localhost" unter diesem Namen zu beheben.

NReilingh
quelle
Vielleicht ist Ihre Docker-Instanz gerade unter Strom? Wenn es sich um ein Hafenproblem handelte, bezweifle ich, dass es überhaupt funktionieren würde, sodass ich nicht viel Zeit auf diesem Weg verbringen würde.
LowlyDBA
Ja, ich habe darüber nachgedacht, aber die Abfrageleistung scheint in Ordnung zu sein, sodass sie nur auf bestimmte Arten von Aktionen beschränkt zu sein scheint. Ich muss auch testen, wie das SMO-Material von INNEN im Container ausgeführt wird, und sicherstellen, dass das Problem dort nicht vorhanden ist.
NReilingh
1
Ich habe diesen Teil nicht vermisst. SQL Server verwendet Verbindungspooling. Ich verstehe, dass dies frustrierend ist, aber ich möchte Sie auch beeindrucken, um sicherzustellen, dass der Container (oder in diesem Fall die "seltsame Hyper-V-Lite-VM") über genügend RAM verfügt. Ihr PS-Skript lief "schnell", aber Minuten zum Durchlaufen von ~ 3000 Objekten sind auf einem Computer mit genügend RAM (dh mehr als 2 GB) langsam .
Randolph West
1
Um ganz ehrlich zu sein, ist es wahrscheinlich besser, eine Ubuntu Hyper-V-VM auf Ihrem Computer hochzufahren und SQL Server für Linux darauf zu installieren.
Randolph West
1
@bazzilic Ich erkläre warum in meiner Antwort. Bitte kommentieren Sie dort, wenn Sie eine Klärung benötigen.
NReilingh

Antworten:

3

Dies ist höchstwahrscheinlich ein RAM-Mangelproblem.

Dinge zu überprüfen:

  • Hat der Container 4 GB RAM zugewiesen? Überprüfen Sie diese Antwort .
  • Haben Sie die Einstellung für den maximalen Serverspeicher für SQL Server im Container konfiguriert? Abhängig davon, wie viel RAM SQL Server im Container sehen kann, kann dieser Wert zwischen 1 GB und 3,25 GB liegen.
  • Ist der Arbeitsspeicher Ihres Hosts aufgebraucht und ist es möglich, dass Docker auf die Festplatte blättert? Schließen Sie alle fremden Anwendungen (Webbrowser verbrauchen viel RAM). SSMS benötigt ca. 1 GB Arbeitsspeicher, um verwendet werden zu können.
  • Ist das nach einem Neustart schneller?

Wenn ich dies selbst tun würde, würde ich die Docker Community Edition für Windows aus dem Docker Store installieren und dann das SQL Server Docker-Image auf diese Weise installieren .

Wenn Ihre Internetverbindung schnell genug ist, können Sie in weniger als 5 Minuten einsatzbereit sein und Ressourcen viel einfacher zuweisen.

EDIT: Ah, Vernetzung.

Randolph West
quelle
Ich bin mir nicht sicher, ob Sie dies falsch verstehen, aber ich führe kein SSMS im Container aus. Dies ist nicht möglich, da Windows-Container derzeit keine RDP-Verbindungen oder GUIs unterstützen. Ich weiß bereits, dass SQL Server nicht langsam ist - aber ich muss herausfinden, ob ich diesen Docker-Container nach Ressourcen hungere. Der Windows 10-Host, auf dem der Container und SSMS ausgeführt werden, verfügt über 10 GB RAM und 2 Kerne, aber ich bin nicht sicher, wie viel dem Container zugewiesen wird.
NReilingh
Meine Antwort wurde umgeschrieben
Randolph West
Weitere Informationen finden Sie unter Q-Update. Beachten Sie, dass dies Microsofts eigener Container-Image-Build ist. Ich denke, wir sind ziemlich sicher, wenn wir davon ausgehen, dass die Einstellungen im Container kein Problem darstellen.
NReilingh
2
Bitte machen Sie diese Annahme nicht!
Randolph West
@NReilingh Ich habe meiner Antwort eine URL hinzugefügt, damit Sie die -mOption untersuchen können.
Randolph West
3

Der Hauptunterschied besteht darin, ob SSMS / SMO versucht, eine Verbindung mit IPv4 oder IPv6 herzustellen. Wenn Sie eine ping localhostEingabeaufforderung ausführen, sollte die Auflösung in ::1IPv6 angezeigt werden 127.0.0.1. Das Verbinden mit .macht dasselbe.

Ihr docker runBefehl macht nur Port 1433 verfügbar 127.0.0.1. Sie können dies überprüfen, indem Sie ausführen, um festzustellen netstat -a, welche Ports verfügbar sind.

Der von Ihnen erstellte Hosts-Dateialias wird direkt in aufgelöst 127.0.0.1, aber Sie benötigen ihn nicht, da Sie 127.0.0.1direkt in SSMS eine Verbindung herstellen und Ihr Problem auf diese Weise lösen können. Das vollständige Ausschalten von IPv6 auf Ihrem Hostsystem würde wahrscheinlich auch funktionieren, aber ich bin mir nicht sicher, wie ratsam dies unter Windows 10 ist.

Ich werde eine alternative Antwort in Betracht ziehen, um zu akzeptieren, ob mir jemand sagen kann, warum IPv6 dazu führt, dass dies nicht funktioniert.

NReilingh
quelle
Haben Sie versucht, eine Verbindung zu tcp: localhost herzustellen? Es kann sein, dass SSMS / SMO versuchen, eine Verbindung zwischen gemeinsam genutztem Speicher oder Named Pipes herzustellen, wenn der Name localhost oder (local) oder sogar "" lautet. und 1. Ich weiß nicht, ob SSMS 17.4 SMO im Objekt-Explorer definitiv verwendet, aber ich denke, dass dies möglich ist.
Herr Magoo
@MisterMagoo Die Eingabe tcp:localhostin das Feld Servername scheint überhaupt nicht zu funktionieren, aber ich habe versucht, TCP / IP in den Verbindungseigenschaften ohne Verbesserung explizit anzugeben. Ich denke immer noch, dass das Problem ein langsamer Fallback 127.0.0.1für localhost ist, wenn dies ::1fehlschlägt. Ich denke, meine Abfragefenster funktionierten, weil sie eine Verbindung aufrechterhielten, während mein Skript mit SMO (vielleicht) immer wieder neue Verbindungen herstellte.
NReilingh
1
@NReilingh Ich sehe das gleiche Problem - Ihre Fehlerbehebung und Erklärung waren wirklich hilfreich. Die Adressierung meines SQL Server-Containers als 127.0.0.1 ( nicht localhost ) aus meiner Host-Umgebung war die einzige Möglichkeit, Host-zu-Container- Verbindungen normal funktionieren zu lassen.
Rogersillito