SMO, SSMS son lentos para la administración de SQL Server en Docker cuando se conecta a localhost


9

TL; DR: cuando me conecto a mi contenedor Docker de SQL Server a través de un nombre que se resuelve en el bucle invertido IPv6 ( ::1), las llamadas SMO son realmente lentas. Cuando se usan 127.0.0.1, son rápidos.


Estoy tratando de aprender a usar la imagen de Docker microsoft / mssql-server-windows-developer . Según la documentación de Microsoft, este contenedor solo expone el puerto 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

Estoy ejecutando el contenedor en Windows 10, y he tenido éxito al iniciarlo, autenticándome con la autenticación de SQL Server y ejecutando consultas contra la instancia usando sqlcmd y SSMS 17.4 en el host de Windows (conectando a localhost o "."), Y Operaciones SQL Estudio en un mac al lado de conexión por IP. No veo problemas de rendimiento notables al ejecutar consultas de esta manera.

En SSMS, también puedo explorar el explorador de objetos, pero si intento hacer algo desde el menú del botón derecho en un objeto en el explorador de objetos, como abrir la ventana de parámetros de instancia o adjuntar una base de datos, SSMS no muestra una respuesta durante aproximadamente 5 -10 minutos, momento en el que muestra la ventana que solicité o muestra este mensaje de error:

Mensaje de error de SSMS

También estoy tratando de hacer algunos scripts de PowerShell contra esta instancia usando el objeto SMO Scripter , y veo el mismo tipo de comportamiento. La secuencia de comandos PS recorre los objetos en la base de datos y los ordena a un archivo, y si bien funciona para recopilar la lista de objetos con relativa rapidez, cada objeto individual tarda de 5 a 10 minutos en ejecutarse, demasiado lento para ser utilizable.

Tengo el presentimiento de que el único puerto expuesto no es suficiente y que SMO y SSMS están tratando de conectarse de una manera similar que los está ralentizando. ¿Podría ser también que cuando se conectan a localhost, estas herramientas suponen que hay otros canales de comunicación presentes que normalmente no serían cortafuegos? ¿Hay algún parámetro de conexión adicional que pueda estar usando? ¿Alguien puede validar mi suposición de que SSMS está utilizando SMO o algo más para hablar con SQL Server?


ACTUALIZACIÓN: Todavía estoy investigando, pero es plausible que este sea un problema de Docker en torno a las limitaciones de recursos. Esto es confuso porque la mayoría de la documentación parece indicar que los Contenedores de Windows no tienen restricciones de recursos predeterminadas (y estas no se pueden configurar en la GUI de Docker para Windows, solo para contenedores de Linux ), pero parece que en realidad, Windows Los contenedores que se ejecutan en Windows 10 obtienen una asignación de RAM predeterminada de 1 GB. Todavía estoy tratando de descubrir cómo inspeccionar un contenedor en ejecución para ver su asignación de RAM y CPU, pero luego tengo que intentar aumentarlos de los valores predeterminados, usando docker runparámetros.


ACTUALIZACIÓN ADICIONAL: no he podido obtener ningún tipo de métrica confiable de la ventana acoplable que me diga qué límites de CPU y memoria tiene para el contenedor. Varias investigaciones indican que los contenedores de Docker no tienen un límite de memoria por defecto, o que lo tienen y es de 1GB, pero todo lo que puedo verificar en este momento es que docker statsdice que el contenedor de SQL solo está usando entre 750 y 850 meg, y cuando Intento agregar un parámetro de ejecución para establecer la memoria disponible en 4 gb, se produce un error. Así que dejé de seguir ese hilo de investigación y fui a una verificación intestinal diferente: ingresé a una sesión interactiva de PowerShell en el contenedor en ejecución y luego invoqué mi script de PowerShell vinculado desde el interior del contenedor.

Ejecutando dentro del contenedor no hubo problema. Atravesó 2780 objetos en solo un par de minutos. Creo que esto confirma que el problema está en el límite del contenedor / host, así que voy a ver si puedo abrir ese puerto UDP. ACTUALIZACIÓN: Abrir el puerto 1434 UDP no ayudó.


MÁS ACTUALIZACIONES: solución alternativa lograda, no es un problema de restricción de recursos: parece haber problemas relacionados con la configuración de asignaciones de memoria grandes para contenedores de Windows: recibí errores similares para 3g y 2g, pero finalmente pude iniciar el contenedor con 1.5g, y Vi una diferencia en el docker statscontenedor que (creo) confirma que se estaba ejecutando con una asignación predeterminada de 1 GB. En la configuración predeterminada, la estadística PRIV WORKING SET (para la que no puedo encontrar documentación, pero creo que es RAM) está entre 700MiB y 850MiB. Condocker run —memory="1.5g"conjunto, es alrededor de 1.0GiB. Por lo tanto, se expandió, pero parece estar dejando más de la asignación libre que antes. Interpreto esto (tal vez incorrectamente) en el sentido de que este servidor (que está ejecutando absolutamente SIN carga y NO tiene bases de datos de usuario) no está bajo presión de memoria. Verifiqué la configuración de memoria máxima del servidor para confirmar que está establecida en el máximo predeterminado de 2PiB.

Entonces las cosas se pusieron raras. Todavía estoy probando cosas ejecutando mi script de PowerShell desde varias ubicaciones. Rápido dentro del contenedor, lento en el host. Luego hice un RDP a otra máquina de Windows en la red, y ejecuté el script desde ESA máquina, conectándome a mi host de Windows 10 por IP. ¡Y fue RÁPIDO! Esto parece apoyar la teoría de que cuando se conecta a algo que se supone que es localhost, SMO está tratando de conectarse a SQL Server utilizando algo que no sea el puerto 1433 TCP, que espera un tiempo de espera muy largo antes de volver a la conexión TCP.

Decidí intentar validar esta teoría ingresando una entrada de archivo de hosts para referirme a localhost por un nombre que no sea localhost:

        127.0.0.1       dockersucks

Me conecté en SSMS a dockersucks en lugar de localhost o ".", E inmediatamente las cosas fueron más rápidas. Navegar por el explorador de objetos fue como de costumbre, y abrir paneles como adjuntar bases de datos o propiedades del servidor sucedió tan rápido como de costumbre. Y, cuando ejecuté mi script de PowerShell desde el host de Windows 10 usando este alias como el nombre del servidor, también fue rápido.

Agregué esta actualización a la pregunta en lugar de una respuesta, ya que todavía estoy buscando una explicación de por qué ocurre esto y si hay una manera de solucionarlo para las conexiones a "localhost" con ese nombre.


¿Quizás su instancia de Docker está poco activada? Si se tratara de un problema portuario, dudo que lo veas funcionar, así que no pasaría mucho tiempo en ese camino.
LowlyDBA

Sí, estaba pensando en eso, pero el rendimiento de la consulta parece estar bien, por lo que parece estar limitado solo a ciertos tipos de acciones. También necesito probar la ejecución del material SMO DENTRO del contenedor y verificar que el problema no esté presente allí.
NReilingh

1
No me perdí esa parte. SQL Server utiliza la agrupación de conexiones. Entiendo que esto es frustrante, pero también quiero impresionarlo para asegurarme de que el contenedor (o "extraña VM Hyper-V lite" en este caso) tenga suficiente RAM. Su script PS se ejecutó "rápidamente", pero los minutos para ejecutar ~ 3000 objetos son lentos en una máquina con suficiente RAM (es decir, más de 2 GB).
Randolph West

1
Para ser sincero, probablemente sea mejor activar una máquina virtual Ubuntu Hyper-V en su máquina e instalar SQL Server para Linux en eso.
Randolph West

1
@bazzilic Explico por qué en mi respuesta. Comenta allí si necesitas una aclaración.
NReilingh

Respuestas:


3

Este es probablemente un problema de falta de memoria RAM.

Cosas para verificar:

  • ¿El contenedor tiene 4 GB de RAM asignados? Mira esta respuesta .
  • ¿Ha configurado la configuración de Memoria máxima del servidor para SQL Server dentro del contenedor? Dependiendo de la cantidad de RAM que SQL Server puede ver en el contenedor, esto puede establecerse en 1 GB a 3.25 GB.
  • ¿Se ha agotado la RAM de su host y es posible que Docker esté pagándose en el disco? Cierre todas las aplicaciones extrañas (los navegadores web son grandes consumidores de RAM). SSMS necesita alrededor de 1 GB de RAM de trabajo para ser utilizable.
  • ¿Es esto más rápido después de un reinicio?

Si lo hiciera yo mismo, instalaría Docker Community Edition para Windows desde la tienda Docker y luego instalaría la imagen Docker de SQL Server de esa manera.

Si su conexión a Internet es lo suficientemente rápida, puede estar en funcionamiento en menos de 5 minutos y poder asignar recursos de una manera mucho más fácil.

EDITAR: Ah, redes.


No estoy seguro de si está malinterpretando esto, pero no estoy ejecutando SSMS dentro del contenedor. Eso no es posible, ya que los contenedores de Windows actualmente no admiten conexiones RDP o GUI. Ya sé que SQL Server no es lento, pero necesito averiguar si estoy hambriento de recursos en este contenedor acoplable. El host de Windows 10 que ejecuta el contenedor y SSMS tiene 10 GB de RAM y 2 núcleos, pero no estoy seguro de cuánto se asigna al contenedor.
NReilingh

Mi respuesta ha sido reescrita
Randolph West

Consulte la actualización de Q para obtener información adicional. Tenga en cuenta que esta es la construcción de la imagen del contenedor de Microsoft, así que creo que estamos bastante seguros asumiendo que la configuración dentro del contenedor no será un problema.
NReilingh

2
¡Por favor no hagas esa suposición!
Randolph West

@NReilingh He agregado una URL a mi respuesta para que investigue la -mopción.
Randolph West

3

La diferencia clave aquí es si SSMS / SMO está intentando conectarse con IPv4 o IPv6. Si lo hace ping localhosten un símbolo del sistema, debería ver que se resuelve ::1, que es el equivalente de IPv6 127.0.0.1. Conectarse a .hace lo mismo.

Su docker runcomando solo expone el puerto 1433 en 127.0.0.1. Puede verificar esto ejecutando netstat -apara ver qué puertos están disponibles.

El alias de archivo de hosts que creó se resuelve directamente 127.0.0.1, pero no lo necesita, ya que puede conectarse 127.0.0.1directamente en SSMS y resolver su problema de esa manera. Apagar IPv6 por completo en su sistema host probablemente también funcionaría, pero no estoy seguro de qué tan aconsejable es esto en Windows 10.

Consideraré una respuesta alternativa para aceptar si alguien puede decirme por qué IPv6 está causando que esto se rompa.


¿Has intentado conectarte a tcp: localhost? Puede ser que SSMS / SMO intente una memoria compartida o conexiones de canalizaciones con nombre cuando el nombre es localhost o (local) o incluso "." y 1. No sé si SSMS 17.4 definitivamente usa SMO en Object Explorer, pero creo que es posible.
Señor Magoo

@MisterMagoo Entrar tcp:localhosten el campo del nombre del servidor no parece funcionar en absoluto, pero intenté especificar explícitamente TCP / IP en las propiedades de conexión sin mejorar. Sigo pensando que el problema es la recuperación lenta 127.0.0.1de localhost cuando ::1falla. Creo que mis ventanas de consulta funcionaban porque mantenían una conexión, mientras que mi script que usaba SMO (tal vez) estaba creando nuevas conexiones una y otra vez.
NReilingh

1
@NReilingh Estoy viendo este mismo problema: su solución de problemas y su explicación fueron realmente útiles. Dirigir mi contenedor de servidor sql como 127.0.0.1 ( no localhost ) desde mi entorno de host era la única forma en que podía hacer que las conexiones de host a contenedor funcionaran normalmente.
rogersillito
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.