TL; DR: Ao conectar-se ao meu contêiner do SQL Server Docker por meio de um nome que resolve o loopback do IPv6 ( ::1
), as chamadas SMO são realmente lentas. Ao usar 127.0.0.1
, eles são rápidos.
Estou tentando aprender como usar a imagem do Docker microsoft / mssql-server-windows-developer . Segundo a documentação da Microsoft, esse contêiner expõe apenas a 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
Estou executando o contêiner no Windows 10 e tive êxito em iniciá-lo, autenticando com autenticação do SQL Server e executando consultas na instância usando sqlcmd e SSMS 17.4 no host do Windows (conectando-se ao host local ou ".") E SQL Operations Estúdio em um mac next door conectando por IP. Não vejo problemas visíveis de desempenho ao executar consultas dessa maneira.
No SSMS, também posso procurar o explorador de objetos, mas se tentar fazer algo no menu do botão direito do mouse em um objeto no explorador de objetos, como abrir a janela de parâmetros da instância ou anexar um banco de dados, o SSMS não mostrará uma resposta por cerca de 5 -10 minutos, momento em que exibe a janela solicitada ou exibe esta mensagem de erro:
Também estou tentando executar scripts do PowerShell nessa instância usando o objeto SMO Scripter e ver o mesmo tipo de comportamento. O script PS percorre os objetos no banco de dados e os rotula para arquivar e, embora ele trabalhe para reunir a lista de objetos de maneira relativamente rápida, cada objeto individual leva de 5 a 10 minutos para o script - lento demais para ser utilizável.
Eu tenho um palpite de que a única porta exposta não é suficiente e que o SMO e o SSMS estão tentando se conectar de uma maneira semelhante que os torna mais lentos. Também pode ser que, ao conectar-se ao host local, essas ferramentas considerem que existem outros canais de comunicação presentes que normalmente não seriam protegidos por firewall? Existem parâmetros de conexão adicionais que eu poderia estar usando? Alguém pode validar minha suposição de que o SSMS está usando SMO ou outra coisa para conversar com o SQL Server?
ATUALIZAÇÃO: Ainda estou investigando, mas é plausível que esse seja um problema do Docker relacionado a restrições de recursos. Isso é confuso, porque a maioria da documentação parece indicar que os Contêineres do Windows não têm restrições de recursos padrão (e elas não podem ser definidas na GUI do Docker for Windows - apenas para contêineres do Linux ), mas parece que, na realidade, o Windows os contêineres em execução no Windows 10 recebem uma alocação de RAM padrão de 1 GB. Ainda estou tentando descobrir como inspecionar um contêiner em execução para ver sua alocação de RAM e CPU, mas, em seguida, tenho que tentar aumentá-los, independentemente dos padrões, usando docker run
parâmetros.
ATUALIZAÇÃO ADICIONAL: Falha ao obter qualquer tipo de métrica confiável da janela de encaixe que me diga quais limites de CPU e memória ela possui para o contêiner. Pesquisas variadas indicam que os contêineres do docker não têm um limite de memória por padrão, ou que possuem e é de 1 GB, mas tudo o que posso verificar no momento é que docker stats
o contêiner SQL está usando apenas entre 750 e 850 meg e quando Eu tento adicionar um parâmetro de execução para definir a memória disponível para 4 gb, erros. Então, parei de seguir esse segmento de perguntas e fiz uma verificação intestinal diferente: entrar em uma sessão interativa do PowerShell no contêiner em execução e depois chamar meu script do PowerShell vinculado acima de dentro do contêiner.
Correndo dentro do contêiner, não havia problema. Ele percorreu 2780 objetos em apenas alguns minutos. Acho que isso confirma que o problema está no limite do contêiner / host, então vou ver se consigo abrir a porta UDP. ATUALIZAÇÃO: Abrir a porta 1434 UDP não ajudou.
MAIS ATUALIZAÇÕES - Solução alternativa alcançada, não é um problema de restrição de recursos: Parece haver problemas relacionados à configuração de grandes alocações de memória para contêineres do Windows - eu estava recebendo erros semelhantes para 3G e 2G, mas finalmente consegui iniciar o contêiner com 1,5g e Vi uma diferença no docker stats
contêiner que (acho) confirma que estava sendo executado com uma alocação padrão de 1 GB. Nas configurações padrão, a estatística PRIV WORKING SET (para a qual não encontro documentação, mas meu melhor palpite é que é RAM) está entre 700MiB e 850MiB. Comdocker run —memory="1.5g"
conjunto, é em torno de 1.0GiB. Por isso, expandiu-se, mas parece estar deixando mais da alocação livre do que antes. Eu interpreto isso (talvez incorretamente) para significar que este servidor (que está executando absolutamente SEM carga e NÃO possui bancos de dados de usuário) não está sob pressão de memória. Verifiquei a configuração de memória máxima do servidor para confirmar se está definida no máximo padrão de 2PiB.
Então as coisas ficaram estranhas. Ainda estou testando as coisas executando meu script do PowerShell de vários locais. Rápido dentro do contêiner, lento no host. Então eu fiz o RDP para outra máquina Windows na rede e executei o script dessa máquina, conectando-me ao meu host do Windows 10 por IP. E foi RÁPIDO! Isso parece apoiar a teoria de que, ao conectar-se a algo que deveria ser host local, o SMO está tentando se conectar ao SQL Server usando algo diferente da porta 1433 TCP, que aguarda um tempo limite muito longo antes de retornar à conexão TCP.
Decidi tentar validar essa teoria inserindo uma entrada de arquivo hosts para se referir ao localhost por um nome diferente de localhost:
127.0.0.1 dockersucks
Conectei o SSMS ao dockersucks em vez do localhost ou ".", E imediatamente as coisas ficaram mais rápidas. Navegar no explorador de objetos era como de costume, e abrir painéis como anexar banco de dados ou propriedades do servidor acontecia o mais rápido possível. E, quando executei meu script do PowerShell no host do Windows 10 usando esse alias como o nome do servidor, ele também foi rápido.
Eu adicionei esta atualização à pergunta em vez de uma resposta, pois ainda estou procurando uma explicação sobre o motivo disso estar ocorrendo e se existe uma maneira de corrigi-la para conexões com "localhost" com esse nome.