SMO, SSMS są powolne w zarządzaniu SQL Server w Docker podczas łączenia z localhost

9

TL; DR: Podczas łączenia się z moim kontenerem dokującym SQL Server za pomocą nazwy, która rozwiązuje się w funkcji loopback ( ::1) IPv6 , wywołania SMO są naprawdę wolne. Podczas używania 127.0.0.1są szybkie.


Próbuję nauczyć się korzystać z obrazu Docker microsoft / mssql-server-windows-developer . Zgodnie z dokumentacją Microsoftu ten kontener ujawnia tylko port 1433 TCP.

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

Korzystam z kontenera w systemie Windows 10 i udało mi się go uruchomić, uwierzytelnić za pomocą uwierzytelniania programu SQL Server i uruchomić zapytania względem instancji za pomocą narzędzia sqlcmd i SSMS 17.4 na hoście systemu Windows (połączenie z hostem lokalnym lub „.”) Oraz operacji SQL Studio na komputerze Mac obok obok połączenia przez IP. Nie widzę zauważalnych problemów z wydajnością podczas uruchamiania zapytań w ten sposób.

W SSMS mogę również przeglądać eksplorator obiektów, ale jeśli spróbuję zrobić coś z menu prawego przycisku myszy na obiekcie w eksploratorze obiektów, np. Otworzyć okno parametrów instancji lub dołączyć bazę danych, SSMS nie wyświetli odpowiedzi przez około 5 -10 minut, w którym to momencie wyświetla okno, o które prosiłem, lub wyświetla ten komunikat o błędzie:

Komunikat o błędzie SSMS

Próbuję również wykonać pewne skrypty PowerShell przeciwko tej instancji za pomocą obiektu SMO Scripter i zobaczę ten sam rodzaj zachowania. Skrypt PS zapętla obiekty w bazie danych i wykonuje skrypty do pliku, a chociaż stosunkowo szybko zbiera listę obiektów, każdy pojedynczy obiekt zajmuje 5–10 minut na skrypt - zbyt wolno, aby można go było użyć.

Mam przeczucie, że pojedynczy odsłonięty port nie jest wystarczający i że SMO i SSMS próbują połączyć się w podobny sposób, co je spowalnia. Czy to możliwe, że przy łączeniu się z hostem lokalnym narzędzia te zakładają istnienie innych kanałów komunikacji, które zwykle nie byłyby zaporą ogniową? Czy są jakieś dodatkowe parametry połączenia, których mógłbym użyć? Czy ktoś może potwierdzić moje założenie, że SSMS używa SMO lub czegoś innego do rozmowy z SQL Server?


AKTUALIZACJA: Nadal badam, ale prawdopodobne jest, że jest to problem Dockera związany z ograniczeniami zasobów. Jest to mylące, ponieważ większość dokumentacji wydaje się wskazywać, że Kontenery Windows nie mają żadnych domyślnych ograniczeń zasobów (i nie można ich ustawić w interfejsie GUI Dockera dla Windows - tylko dla kontenerów Linux ), ale wydaje się, że w rzeczywistości Windows kontenery działające w systemie Windows 10 otrzymują domyślny przydział pamięci RAM wynoszący 1 GB. Wciąż próbuję wymyślić, jak sprawdzić działający kontener, aby zobaczyć jego przydzielenie pamięci RAM i procesora, ale teraz muszę po prostu spróbować zwiększyć te wartości bez względu na ustawienia domyślne, używając docker runparametrów.


DALSZA AKTUALIZACJA: Nie udało mi się uzyskać z dokera żadnego wiarygodnego wskaźnika, który powiedziałby mi, jakie ograniczenia procesora i pamięci ma dla kontenera. Różne badania wskazują, że albo kontenery dokerów domyślnie nie mają limitu pamięci, albo tak, i mają 1 GB, ale w tej chwili mogę tylko zweryfikować, docker statsże kontener SQL używa tylko między 750 a 850 megabajtów, a kiedy Próbuję dodać parametr uruchomienia, aby ustawić dostępną pamięć na 4 GB, błąd się kończy. Więc zatrzymał się w następstwie tego wątku śledztwa i poszedł do innego czeku gut: wprowadzając interaktywną sesję powershell na bieżącą pojemniku, a następnie powołując mój skrypt PowerShell powiązany z wyżej wewnątrz pojemnika.

Podczas pracy w kontenerze nie było problemu. Przebił się przez 2780 obiektów w ciągu zaledwie kilku minut. Myślę, że to potwierdza, że ​​problem dotyczy granicy kontenera / hosta, więc zobaczę, czy mogę otworzyć ten port UDP. AKTUALIZACJA: Otwarcie portu 1434 UDP nie pomogło.


WIĘCEJ AKTUALIZACJI - Osiągnięto obejście problemu, nie jest to problem związany z ograniczeniami zasobów: Wydaje się, że występują problemy związane z ustawianiem dużej alokacji pamięci dla kontenerów Windows - otrzymywałem podobne błędy dla 3g i 2g, ale ostatecznie mogłem uruchomić pojemnik z 1,5g, i WIDZIAŁEM różnicę w docker statskontenerze, która (jak sądzę) potwierdza, że ​​działała z domyślnym przydziałem 1 GB. Przy ustawieniach domyślnych statystyka PRIV WORKING SET (dla której nie mogę znaleźć żadnej dokumentacji, ale przypuszczam, że to RAM) wynosi pomiędzy 700MiB a 850MiB. Zdocker run —memory="1.5g"set, to około 1.0GiB. Tak więc rozszerzyło się, ale wydaje się, że pozostawia większą część przydziału wolną niż wcześniej. Interpretuję to (być może niepoprawnie) w ten sposób, że ten serwer (który działa absolutnie BEZ obciążenia i NIE ma baz danych użytkowników) nie jest pod presją pamięci. Sprawdziłem maksymalne ustawienie pamięci serwera, aby potwierdzić, że jest ustawione na domyślne maksimum 2PiB.

Potem wszystko stało się dziwne. Nadal testuję różne rzeczy, uruchamiając skrypt PowerShell z różnych lokalizacji. Szybko w pojemniku, powoli na hoście. Następnie przełączyłem RDP na inny komputer z systemem Windows w sieci i uruchomiłem skrypt z TEGO komputera, łącząc się z moim hostem Windows 10 przez IP. I było SZYBKO! Wydaje się to potwierdzać teorię, że podczas łączenia się z czymś, co ma być hostem lokalnym, SMO próbuje połączyć się z SQL Server przy użyciu czegoś innego niż port 1433 TCP, który czeka bardzo długi czas oczekiwania przed powrotem do połączenia TCP.

Postanowiłem spróbować zweryfikować tę teorię, wprowadzając wpis pliku hosta w celu odniesienia do localhost nazwą inną niż localhost:

        127.0.0.1       dockersucks

Połączyłem w SSMS z dockersucks zamiast localhost lub „.” I od razu wszystko poszło szybciej. Nawigacja w eksploratorze obiektów przebiegała jak zwykle, a otwieranie paneli, takich jak dołączanie bazy danych lub właściwości serwera, odbywało się tak szybko, jak zwykle. Kiedy uruchomiłem skrypt PowerShell z hosta systemu Windows 10, używając tego aliasu jako nazwy serwera, również był szybki.

Dodałem tę aktualizację do pytania zamiast odpowiedzi, ponieważ wciąż szukam wyjaśnienia, dlaczego tak się dzieje i czy istnieje sposób, aby to naprawić w przypadku połączeń z „hostem lokalnym” o tej nazwie.

NReilingh
źródło
Może Twoja instancja dokera jest po prostu za słaba? Gdyby to był problem z portem, wątpię, żebyś w ogóle widział, że działa, więc nie spędziłbym dużo czasu na tej drodze.
LowlyDBA,
Tak, myślałem o tym, ale wydajność zapytań wydaje się dobra, więc ogranicza się tylko do niektórych rodzajów działań. Muszę również przetestować uruchamianie SMO z INSIDE kontenera i sprawdzić, czy problem tam nie występuje.
NReilingh
1
Nie tęskniłem za tą częścią. SQL Server używa puli połączeń. Rozumiem, że jest to frustrujące, ale chcę również wywrzeć na tobie wrażenie, aby upewnić się, że kontener (lub „dziwna Hyper-V lite VM” w tym przypadku) ma wystarczającą ilość pamięci RAM. Twój skrypt PS działał „szybko”, ale minuty na przejrzenie ~ 3000 obiektów są powolne na maszynie z wystarczającą ilością pamięci RAM (tj. Ponad 2 GB).
Randolph West
1
Szczerze mówiąc, prawdopodobnie lepiej jest spakować maszynę wirtualną Ubuntu Hyper-V na swoim komputerze i zainstalować na niej SQL Server dla Linuxa.
Randolph West
1
@bazzilic wyjaśniam dlaczego w mojej odpowiedzi. Proszę o komentarz, jeśli potrzebujesz wyjaśnienia.
NReilingh

Odpowiedzi:

3

Najprawdopodobniej jest to problem głodu pamięci RAM.

Rzeczy do sprawdzenia:

  • Czy do kontenera przypisano 4 GB pamięci RAM? Sprawdź tę odpowiedź .
  • Czy skonfigurowałeś ustawienie Max Server Memory dla SQL Server wewnątrz kontenera? W zależności od tego, ile pamięci RAM SQL Server może zobaczyć w kontenerze, może to być dowolna wartość od 1 GB do 3,25 GB.
  • Czy pamięć RAM Twojego hosta jest zużyta i czy jest możliwe, że Docker stronicuje na dysk? Zamknij wszelkie zewnętrzne aplikacje (przeglądarki internetowe są dużymi odbiorcami pamięci RAM). SSMS potrzebuje około 1 GB działającej pamięci RAM, aby był użyteczny.
  • Czy to jest szybsze po ponownym uruchomieniu?

Gdybym to robił sam, zainstalowałbym Docker Community Edition dla systemu Windows ze sklepu Docker , a następnie zainstalowałem w ten sposób obraz SQL Server Docker .

Jeśli twoje połączenie internetowe jest wystarczająco szybkie, możesz być gotowy do pracy w mniej niż 5 minut i być w stanie przydzielić zasoby w znacznie łatwiejszy sposób.

EDYCJA: Ach, networking.

Randolph West
źródło
Nie jestem pewien, czy to źle rozumiesz, ale nie uruchamiam SSMS w kontenerze. Nie jest to możliwe, ponieważ kontenery Windows obecnie nie obsługują połączeń RDP ani GUI. Wiem już, że SQL Server nie jest wolny - ale muszę się dowiedzieć, czy głoduję ten kontener dokerów w poszukiwaniu zasobów. Host systemu Windows 10 z uruchomionym kontenerem i SSMS ma 10 GB pamięci RAM i 2 rdzenie, ale nie jestem pewien, ile jest przydzielane do kontenera.
NReilingh
Moja odpowiedź została przepisana
Randolph West,
Aby uzyskać dodatkowe informacje, zobacz Aktualizacja Q. Pamiętaj, że jest to własna kompilacja obrazu kontenera firmy Microsoft, więc myślę, że jesteśmy całkiem bezpieczni, zakładając, że ustawienia w kontenerze nie będą stanowić problemu.
NReilingh
2
Proszę nie przyjmować tego założenia!
Randolph West
@NReilingh Dodałem adres URL do mojej odpowiedzi w celu zbadania -mopcji.
Randolph West
3

Kluczową różnicą tutaj jest to, czy SSMS / SMO próbuje połączyć się z IPv4 czy IPv6. Jeśli wykonasz ping localhostaw wierszu polecenia, powinieneś zobaczyć, że rozwiązuje to ::1, co odpowiada IPv6 127.0.0.1. Połączenie z .robi to samo.

Twoje docker runpolecenie ujawnia tylko port 1433 127.0.0.1. Możesz to sprawdzić, uruchamiając się, netstat -aaby sprawdzić, które porty są dostępne.

Utworzony alias pliku hosts rozwiązuje się bezpośrednio 127.0.0.1, ale nie jest on potrzebny, ponieważ można połączyć się 127.0.0.1bezpośrednio w SSMS i w ten sposób rozwiązać problem. Wyłączenie całkowicie IPv6 w systemie hosta prawdopodobnie również działałoby, ale nie jestem pewien, jak wskazane jest to w systemie Windows 10.

Rozważę alternatywną odpowiedź, aby zaakceptować, jeśli ktoś może mi powiedzieć, dlaczego IPv6 powoduje to awarię.

NReilingh
źródło
Próbowałeś połączyć się z tcp: localhost? Możliwe, że SSMS / SMO próbuje połączyć pamięć współdzieloną lub nazwane potoki, gdy nazwa to localhost lub (local), a nawet „.” i 1. Nie wiem, czy SSMS 17.4 zdecydowanie używa SMO w Object Explorerze, ale myślę, że jest to możliwe.
Mister Magoo,
@MisterMagoo Wpisywanie tcp:localhostw polu nazwy serwera wcale nie działa, ale próbowałem jawnie określić TCP / IP we właściwościach połączenia bez poprawy. Nadal uważam, że problem polega na powolnym powrocie do 127.0.0.1hosta lokalnego, gdy ::1zawiedzie. Myślę, że moje okna zapytań działały, ponieważ utrzymywały połączenie, podczas gdy mój skrypt używający SMO (prawdopodobnie) tworzył nowe połączenia w kółko.
NReilingh
1
@NReilingh Widzę ten sam problem - Twoje rozwiązywanie problemów i wyjaśnienia były bardzo pomocne. Adresowanie mojego kontenera serwera SQL jako 127.0.0.1 ( nie localhost ) ze środowiska hosta było jedynym sposobem, aby uzyskać prawidłowe połączenia hosta z kontenerem .
rogersillito