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:
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 run
pará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 stats
dice 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 stats
contenedor 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.
fuente
Respuestas:
Este es probablemente un problema de falta de memoria RAM.Cosas para verificar:
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.
fuente
-m
opción.La diferencia clave aquí es si SSMS / SMO está intentando conectarse con IPv4 o IPv6. Si lo hace
ping localhost
en un símbolo del sistema, debería ver que se resuelve::1
, que es el equivalente de IPv6127.0.0.1
. Conectarse a.
hace lo mismo.Su
docker run
comando solo expone el puerto 1433 en127.0.0.1
. Puede verificar esto ejecutandonetstat -a
para 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 conectarse127.0.0.1
directamente 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.
fuente
tcp:localhost
en 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 lenta127.0.0.1
de localhost cuando::1
falla. 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.