连接到本地主机时,SMO,SSMS对于在Docker中管理SQL Server的速度很慢


9

TL; DR:当通过可解析为IPv6环回(::1)的名称连接到我的SQL Server Docker容器时,SMO调用确实很慢。使用时127.0.0.1,速度很快。


我正在尝试学习如何使用Docker镜像microsoft / mssql-server-windows-developer。根据Microsoft的文档,此容器仅公开端口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

我正在Windows 10上运行该容器,并且已成功启动该容器,使用SQL Server身份验证进行身份验证,并在Windows主机上使用sqlcmd和SSMS 17.4对实例运行查询(连接到localhost或“。”),以及SQL操作通过IP连接的隔壁Mac上的Studio。这样运行查询时,我看不到任何明显的性能问题。

在SSMS中,我也可以浏览对象资源管理器,但是如果尝试从对象资源管理器中的对象的右键菜单上执行某些操作,例如打开实例参数窗口或附加数据库,则SSMS不会显示约5的响应-10分钟,此时它要么显示我要的窗口,要么显示以下错误消息:

SSMS错误消息

我还尝试使用SMO Scripter对象针对此实例进行一些PowerShell脚本编写,并看到相同的行为。PS脚本循环遍历数据库中的对象并将其脚本化为文件,并且可以相对较快地收集对象列表,但是每个单独的对象需要5-10分钟的时间来编写脚本-太慢了,无法使用。

我有一个预感,即单个暴露的端口还不够,SMO和SSMS试图以类似的方式进行连接,这会使它们变慢。难道是当连接到本地主机时,这些工具是否假定存在其他通常不会进行防火墙保护的通信通道?我可以使用其他任何连接参数吗?谁能验证我关于SSMS正在使用SMO或其他与SQL Server通信的假设?


更新:我仍在调查,但这似乎是围绕资源限制的Docker问题。这很令人困惑,因为大多数文档似乎都表明Windows容器没有任何默认资源限制(并且不能在Docker for Windows GUI中设置这些默认资源限制- 仅对于Linux容器),但是实际上,Windows在Windows 10上运行的容器的默认RAM分配为1GB。我仍在尝试找出如何检查正在运行的容器以查看其RAM和CPU分配的方法,但是接下来我必须尝试使用docker run参数从默认值中增加这些值。


进一步更新:我一直无法从docker获得任何可靠的指标,该指标可以告诉我该容器对CPU和内存的限制。各种研究表明,docker容器默认没有内存限制,或者它们有1GB,但是我目前只能验证的是,docker stats该SQL容器仅使用 750到850兆之间,何时我尝试添加一个运行参数来将可用内存设置为4 GB,但出现错误。因此,我不再关注该查询线程,而是进行了另一项肠道检查:在正在运行的容器上进入交互式Powershell会话,然后从容器内部调用上面链接的Powershell脚本。

在容器内运行没有问题。它在短短几分钟内就烧穿了2780个物体。我认为这可以确认问题出在容器/主机边界上,因此我将看看是否可以打开该UDP端口。更新:打开端口1434 UDP没有帮助。


更多更新-已解决,而不是资源约束问题:似乎与为Windows容器设置大的内存分配有关的问题 -我在3g和2g上收到类似的错误,但最终能够从1.5g启动该容器,并且我发现docker stats容器的差异(我认为)证实了容器运行时的默认分配为1GB。在默认设置下,PRIV WORKING SET stat(我找不到任何文档,但我最大的猜测是它的RAM)在700MiB和850MiB之间。用docker run —memory="1.5g"设置,大约是1.0GiB。因此,它的确扩大了,但似乎腾出了比以前更多的分配空间。我将此解释(可能是错误地)是指该服务器(绝对没有负载运行并且没有用户数据库)没有内存压力。我检查了最大服务器内存设置,以确认它设置为默认的最大2PiB。

然后事情变得奇怪了。我仍在通过从各个位置运行我的Powershell脚本来测试事物。在容器内部快,在主机上慢。然后,我RDP到网络上的另一台Windows计算机,并从那台计算机运行脚本,并通过IP连接到我的Windows 10主机。太快了!这似乎支持以下理论:当连接到本应为localhost的主机时,SMO尝试使用端口1433 TCP以外的其他主机连接到SQL Server,该主机在等待很长的超时时间后才退回到TCP连接。

我决定尝试通过输入一个hosts文件条目来尝试验证这一理论,该条目使用非localhost的名称引用localhost:

        127.0.0.1       dockersucks

我在SSMS中将其连接到dockersucks而不是localhost或“。”,结果一切很快。导航对象资源管理器的过程与往常一样,打开面板(如附加数据库或服务器属性)的速度与以往一样快。而且,当我使用该别名作为服务器名称从Windows 10主机运行Powershell脚本时,它的运行速度也很快。

我将这个更新添加到问题中,而不是添加答案,因为我仍在寻找为什么会发生这种情况的解释,以及是否有一种方法可以解决此问题,以解决通过该名称连接到“ localhost”的问题。


也许您的Docker实例刚刚通电?如果这是港口问题,我怀疑您会看到它完全正常工作,因此我不会在那条路上花费很多时间。
LowlyDBA '18年

是的,我当时正在考虑,但是查询性能似乎不错,因此似乎只限于某些类型的操作。我还需要测试从容器内部运行SMO东西,并验证那里没有问题。
NReilingh

1
我没有错过那部分。SQL Server使用连接池。我知道这令人沮丧,但是我也想给您留下深刻的印象,以确保该容器(在这种情况下为“奇怪的Hyper-V lite VM”)具有足够的RAM。您的PS脚本“快速”运行,但是在一台具有足够RAM(即超过2 GB)的计算机中,运行〜3000个对象的时间很
Randolph West

1
老实说,最好在计算机上安装Ubuntu Hyper-V VM,然后在该计算机上安装SQL Server for Linux。
Randolph West

1
@bazzilic我在回答中解释了原因。如果需要澄清,请在此处发表评论。
NReilingh '18

Answers:


3

这很可能是RAM不足的问题。

检查事项:

  • 容器是否分配有4 GB的RAM?检查此答案
  • 您是否在容器内为SQL Server配置了“最大服务器内存”设置?根据SQL Server在容器中可以看到多少RAM,可以将其设置为1 GB到3.25 GB之间的任何值。
  • 您的主机的RAM是否已用尽,并且Docker是否可能正在分页到磁盘?关闭所有无关的应用程序(Web浏览器是RAM的主要使用者)。SSMS需要大约1 GB的工作RAM才能使用。
  • 重新启动后速度更快吗?

如果我自己进行此操作,则需要从Docker store安装适用于Windows的Docker社区版,然后以这种方式安装SQL Server Docker映像

如果您的Internet连接速度足够快,那么您可以在5分钟内启动并运行,并且能够以一种更轻松的方式分配资源。

编辑:啊,网络。


不知道您是否误解了这一点,但是我没有在容器运行SSMS 。这是不可能的,因为Windows容器当前不支持RDP连接或GUI。我已经知道SQL Server并不慢-但我确实需要弄清楚我是否正在使此Docker容器中的资源不足。运行容器的Windows 10主机和SSMS具有10GB的RAM和2个内核,但是我不确定要为容器分配多少。
NReilingh

我的回答已被重写
兰多夫西

有关其他信息,请参见Q更新。请注意,这是Microsoft自己的容器映像构建,因此我认为假设容器内的设置不会成为问题是非常安全的。
NReilingh

2
请不要做那个假设!
伦道夫·韦斯特

@NReilingh我已在答案中添加了一个URL,供您调查该-m选项。
Randolph West

3

此处的主要区别在于SSMS / SMO是否尝试与IPv4或IPv6连接。如果ping localhost在命令提示符下执行,则应该看到它解析为::1,相当于的IPv6 127.0.0.1。连接到.做同样的事情。

您的docker run命令仅在上公开端口1433 127.0.0.1。您可以通过运行netstat -a查看哪些端口可用来验证这一点。

您创建的hosts文件别名可以直接解析为127.0.0.1,但您不需要它,因为您可以127.0.0.1直接在SSMS中连接并以这种方式解决问题。在您的主机系统上完全关闭IPv6可能也可以,但是我不确定Windows 10上的建议是否可行。

如果有人可以告诉我为什么IPv6导致此问题中断,我将考虑接受另一种答案。


您是否尝试连接到tcp:localhost?名称为localhost或(本地)甚至“”时,SSMS / SMO可能正在尝试共享内存或命名管道连接。和:: 1。我不知道SSMS 17.4是否确实在对象资源管理器中使用SMO,但我认为这是可能的。
马古先生

@MisterMagoo tcp:localhost在服务器名称字段中输入似乎根本不起作用,但是我尝试在连接属性中显式指定TCP / IP,而没有改进。我仍然认为问题是失败127.0.0.1时回退到本地主机的速度很慢::1。我认为我的查询窗口之所以有效是因为它们正在维护连接,而我使用SMO的脚本是(也许)一次又一次地创建新的连接。
NReilingh

1
@NReilingh我看到了同样的问题-您的故障排除和说明确实很有帮助。从主机环境中将我的SQL Server容器寻址为127.0.0.1而不是localhost)是我可以使主机到容器连接正常工作的唯一方法。
rogersillito
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.