SMO, SSMS sono lenti per la gestione di SQL Server in Docker durante la connessione a localhost


9

TL; DR: quando mi connetto al mio contenitore Docker di SQL Server tramite un nome che si risolve nel loopback IPv6 ( ::1), le chiamate SMO sono molto lente. Quando si usano 127.0.0.1, sono veloci.


Sto cercando di imparare come utilizzare l'immagine Docker microsoft / mssql-server-windows-developer . Secondo la documentazione di Microsoft, questo contenitore espone solo la porta 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

Sto eseguendo il contenitore su Windows 10 e sono riuscito a avviarlo, eseguendo l'autenticazione con l'autenticazione di SQL Server e eseguendo query sull'istanza utilizzando sqlcmd e SSMS 17.4 sull'host di Windows (connessione a localhost o ".") E Operazioni SQL Studio su un Mac della porta accanto che si collega tramite IP. Non vedo problemi di prestazioni evidenti quando eseguo query in questo modo.

In SSMS, posso anche sfogliare Esplora oggetti, ma se provo a fare qualcosa dal menu di scelta rapida su un oggetto in Esplora oggetti, come aprire la finestra dei parametri dell'istanza o collegare un database, SSMS non mostra una risposta per circa 5 -10 minuti, a quel punto visualizza la finestra richiesta o visualizza questo messaggio di errore:

Messaggio di errore SSMS

Sto anche cercando di eseguire alcuni script di PowerShell su questa istanza utilizzando l'oggetto SMO Scripter e vedere lo stesso tipo di comportamento. Lo script PS scorre gli oggetti nel database e li script su file, e mentre funziona per raccogliere l'elenco degli oggetti in modo relativamente rapido, ogni singolo oggetto impiega 5-10 minuti per eseguire lo script, troppo lento per essere utilizzabile.

Ho la sensazione che la singola porta esposta non sia sufficiente e che SMO e SSMS stiano cercando di connettersi in un modo simile che li sta rallentando. Potrebbe anche essere che durante la connessione a localhost, questi strumenti presumano che esistano altri canali di comunicazione che normalmente non sarebbero protetti da firewall? Ci sono altri parametri di connessione che potrei usare? Qualcuno può confermare il mio presupposto che SSMS sta usando SMO o qualcos'altro per parlare con SQL Server?


AGGIORNAMENTO: Sto ancora indagando, ma è plausibile che si tratti di un problema Docker relativo ai vincoli delle risorse. Ciò è confuso perché la maggior parte della documentazione sembra indicare che i contenitori di Windows non hanno vincoli di risorse predefiniti (e questi non possono essere impostati nella GUI Docker per Windows - solo per contenitori Linux ), ma sembra che in realtà, Windows i contenitori in esecuzione su Windows 10 ottengono un'allocazione RAM predefinita di 1 GB. Sto ancora cercando di capire come ispezionare un container in esecuzione per vedere la sua allocazione di RAM e CPU, ma dopo devo solo provare ad aumentare quelli da qualsiasi impostazione predefinita, usando i docker runparametri.


ULTERIORI AGGIORNAMENTI: non riesco a ottenere alcun tipo di metrica affidabile dalla finestra mobile che mi dice quali limiti di CPU e memoria ha in atto per il contenitore. Diverse ricerche indicano che i contenitori docker non hanno un limite di memoria per impostazione predefinita o che lo fanno ed è 1 GB, ma tutto ciò che posso verificare al momento è che docker statsil contenitore SQL utilizza solo tra 750 e 850 mega e quando Provo ad aggiungere un parametro di esecuzione per impostare la memoria disponibile su 4 GB, si errori. Quindi ho smesso di seguire quel thread di inchiesta e ho optato per un diverso controllo dell'intestino: entrare in una sessione di PowerShell interattiva sul container in esecuzione e quindi invocare il mio script PowerShell collegato sopra dall'interno del container.

In esecuzione all'interno del contenitore non c'erano problemi. Ha attraversato 2780 oggetti in un paio di minuti. Penso che ciò confermi che il problema riguarda il limite contenitore / host, quindi vedrò se riesco ad aprire quella porta UDP. AGGIORNAMENTO: L' apertura della porta 1434 UDP non ha aiutato.


ULTERIORI AGGIORNAMENTI: soluzione alternativa raggiunta, non un problema di restrizione delle risorse: sembrano esserci problemi relativi all'impostazione di grandi allocazioni di memoria per i contenitori di Windows: ho ricevuto errori simili per 3g e 2g, ma alla fine sono stato in grado di avviare il contenitore con 1,5 ge Ho visto una differenza nel docker statsper il contenitore che (penso) conferma che era in esecuzione con un'allocazione predefinita di 1 GB. Con le impostazioni predefinite, la statistica PRIV WORKING SET (per la quale non riesco a trovare alcuna documentazione, ma la mia ipotesi migliore è la RAM) è compresa tra 700 MiB e 850 MiB. Condocker run —memory="1.5g"set, è intorno a 1.0GiB. Quindi si è espanso, ma sembra lasciare più spazio libero rispetto a prima. Interpreto questo (forse in modo errato) per indicare che questo server (che non esegue assolutamente NESSUN carico e NON ha database utente) non è sotto pressione della memoria. Ho controllato l'impostazione di memoria massima del server per confermare che è impostata al massimo predefinito di 2PiB.

Poi le cose sono diventate strane. Sto ancora testando le cose eseguendo il mio script PowerShell da varie posizioni. Veloce all'interno del contenitore, lento sull'host. Quindi ho eseguito il RDP su un altro computer Windows sulla rete ed ho eseguito lo script da QUELLO computer, collegandomi al mio host Windows 10 tramite IP. Ed è stato VELOCE! Questo sembra supportare la teoria secondo cui quando si connette a qualcosa che dovrebbe essere localhost, SMO sta cercando di connettersi a SQL Server utilizzando qualcosa di diverso dalla porta 1433 TCP, che attende un timeout molto lungo prima di ricadere sulla connessione TCP.

Ho deciso di provare a convalidare questa teoria inserendo una voce del file hosts per fare riferimento a localhost con un nome diverso da localhost:

        127.0.0.1       dockersucks

Mi sono collegato in SSMS a dockersucks invece di localhost o ".", E immediatamente le cose sono state più veloci. La navigazione in Esplora oggetti era come al solito e l'apertura di pannelli come il collegamento del database o delle proprietà del server avveniva con la stessa rapidità. E, quando ho eseguito il mio script PowerShell dall'host Windows 10 usando questo alias come nome del server, è stato veloce.

Ho aggiunto questo aggiornamento alla domanda invece di una risposta poiché sto ancora cercando una spiegazione del perché questo si sta verificando e se esiste un modo per risolverlo per le connessioni a "localhost" con quel nome.


Forse l'istanza della tua finestra mobile è appena sotto tensione? Se fosse un problema portuale dubito che lo vedresti funzionare, quindi non passerei molto tempo su quella strada.
LowlyDBA,

Sì, ci stavo pensando, ma le prestazioni della query sembrano soddisfacenti, quindi sembrano limitate solo a determinati tipi di azioni. Ho anche bisogno di testare l'esecuzione delle cose SMO da INSIDE il contenitore e verificare che il problema non sia presente lì.
NReilingh,

1
Non ho perso quella parte. SQL Server utilizza il pool di connessioni. Capisco che questo sia frustrante, ma voglio anche impressionare te per assicurarti che il container (o "strana VM Hyper-V lite" in questo caso) abbia abbastanza RAM. Lo script PS è stato eseguito "rapidamente", ma i minuti per eseguire ~ 3000 oggetti sono lenti in una macchina con RAM sufficiente (ovvero più di 2 GB).
Randolph West,

1
Ad essere sinceri, probabilmente farai meglio a girare una VM Ubuntu Hyper-V sul tuo computer e installare SQL Server per Linux su quello.
Randolph West,

1
@bazzilic Spiego perché nella mia risposta. Per favore, commenta lì se hai bisogno di chiarimenti.
NReilingh,

Risposte:


3

Questo è molto probabilmente un problema di fame di RAM.

Cose da controllare:

  • Il contenitore ha 4 GB di RAM assegnati? Controlla questa risposta .
  • Hai configurato l'impostazione Max Server Memory per SQL Server all'interno del contenitore? A seconda della quantità di RAM che SQL Server può vedere nel contenitore, questa opzione può essere impostata su un valore compreso tra 1 GB e 3,25 GB.
  • La RAM del tuo host è esaurita ed è possibile che Docker esegua il paging su disco? Chiudi eventuali applicazioni estranee (i browser Web sono grandi consumatori di RAM). SSMS necessita di circa 1 GB di RAM funzionante per essere utilizzabile.
  • È più veloce dopo un riavvio?

Se lo stessi facendo, installerei Docker Community Edition per Windows dall'archivio Docker , quindi installerei l' immagine Docker di SQL Server in quel modo.

Se la tua connessione a Internet è abbastanza veloce, puoi essere attivo e funzionante in meno di 5 minuti ed essere in grado di allocare le risorse in un modo molto più semplice.

EDIT: Ah, networking.


Non sono sicuro se lo fraintendi, ma non sto eseguendo SSMS all'interno del contenitore. Questo non è possibile, poiché attualmente i contenitori di Windows non supportano connessioni RDP o GUI. So già che SQL Server non è lento, ma devo capire se sto morendo di fame questo contenitore docker per le risorse. L'host di Windows 10 che esegue il contenitore e SSMS ha 10 GB di RAM e 2 core, ma non sono sicuro di quanto venga allocato nel contenitore.
NReilingh,

La mia risposta è stata riscritta
Randolph West

Vedi Q update per ulteriori informazioni. Si noti che questa è la creazione dell'immagine del contenitore di Microsoft, quindi penso che siamo abbastanza sicuri supponendo che le impostazioni all'interno del contenitore non saranno un problema.
NReilingh,

2
Per favore, non fare questo presupposto!
Randolph West,

@NReilingh Ho aggiunto un URL alla mia risposta per consentirti di esaminare l' -mopzione.
Randolph West,

3

La differenza chiave qui è se SSMS / SMO sta tentando di connettersi con IPv4 o IPv6. Se si esegue un ping localhostprompt dei comandi, si dovrebbe vedere risolto ::1, che è l'equivalente IPv6 di 127.0.0.1. La connessione a .fa la stessa cosa.

Il tuo docker runcomando espone solo la porta 1433 127.0.0.1. Puoi verificarlo eseguendo netstat -aper vedere quali porte sono disponibili.

L'alias del file hosts che hai creato si risolve direttamente 127.0.0.1, ma non ti serve, poiché puoi connetterti 127.0.0.1direttamente in SSMS e risolvere il tuo problema in questo modo. Disattivare completamente IPv6 sul tuo sistema host probabilmente funzionerebbe anche, ma non sono sicuro di quanto sia consigliabile su Windows 10.

Prenderò in considerazione una risposta alternativa per accettare se qualcuno può dirmi perché IPv6 sta causando l'interruzione.


Hai provato a connetterti a tcp: localhost? È possibile che SSMS / SMO stiano tentando una memoria condivisa o una connessione named pipe quando il nome è localhost o (local) o addirittura "." e :: 1. Non so se SSMS 17.4 utilizzi sicuramente SMO in Esplora oggetti, ma penso che sia possibile.
Mago Magoo,

@MisterMagoo L'inserimento tcp:localhostnel campo del nome del server non sembra funzionare affatto, ma ho provato a specificare esplicitamente TCP / IP nelle proprietà della connessione senza miglioramenti. Penso ancora che il problema sia un lento fallback 127.0.0.1per localhost quando ::1fallisce. Penso che la mia query windows funzionasse perché mantenevano una connessione, mentre il mio script usando SMO stava (forse) creando continuamente nuove connessioni.
NReilingh,

1
@NReilingh Sto riscontrando lo stesso problema: la risoluzione dei problemi e la spiegazione sono state davvero utili. Indirizzare il mio contenitore sql server come 127.0.0.1 ( non localhost ) dal mio ambiente host era l'unico modo in cui potevo far funzionare normalmente le connessioni host-container .
rogersillito,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.