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.1
są 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:
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 run
parametró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 stats
kontenerze, 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.