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のスタジオ。この方法でクエリを実行しても、目立ったパフォーマンスの問題はありません。
SSMSでは、オブジェクトエクスプローラーを参照することもできますが、インスタンスエクスプローラーウィンドウを開いたり、データベースを接続したりするなど、オブジェクトエクスプローラーのオブジェクトで右クリックメニューから何かを行おうとすると、SSMSは約5秒間応答を表示しません-10分。この時点で、要求したウィンドウが表示されるか、次のエラーメッセージが表示されます。
また、SMO Scripterオブジェクトを使用して、このインスタンスに対してPowerShellスクリプトを実行して、同じような動作を確認しようとしています。PSスクリプトは、データベース内のオブジェクトをループしてスクリプトでファイルに保存し、オブジェクトのリストを比較的迅速に収集するように機能しますが、個々のオブジェクトのスクリプト作成には5〜10分かかり、使用するには遅すぎます。
公開された単一のポートでは不十分であり、SMOとSSMSが同様の方法で接続を試みて速度が低下しているのではないかと思います。また、localhostに接続するときに、これらのツールは、通常はファイアウォールで保護されない他の通信チャネルが存在すると想定しているのでしょうか。使用できる追加の接続パラメーターはありますか?SSMSがSMOなどを使用してSQL Serverと通信しているという私の仮定を誰かが検証できますか?
更新:まだ調査中ですが、これはリソースの制約に関するDockerの問題であると考えられます。ほとんどのドキュメントでは、Windowsコンテナにデフォルトのリソース制約がないことを示しているようです(そして、これらはDocker for Windows GUIでは設定できません。Linuxコンテナの場合のみです)が、実際にはWindows Windows 10で実行されているコンテナーは、1 GBのデフォルトのRAM割り当てを取得します。実行中のコンテナーを検査してそのRAMとCPUの割り当てを確認する方法をまだ考えていますが、次にdocker run
パラメーターを使用して、デフォルトの値からそれらを増やしてみます。
更なる更新:Dockerから、コンテナに設定されているCPUとメモリの制限を教えてくれる信頼できるメトリックを取得できませんでした。さまざまな調査により、Dockerコンテナーにはデフォルトでメモリ制限がないか、1 GBであることが示されていますが、現時点で確認できるのdocker stats
は、SQLコンテナーが750〜850 MBのメモリしか使用していないということです。使用可能なメモリを4 GBに設定する実行パラメータを追加しようとすると、エラーになります。だから私はその問い合わせのスレッドに従うのをやめ、別の腸のチェックに行きました:実行中のコンテナーでインタラクティブなPowerShellセッションを入力してから、コンテナー内から上記のリンクされた私のPowerShellスクリプトを呼び出します。
コンテナー内で実行しても問題はありませんでした。ほんの数分で2780個のオブジェクトを突破しました。これは問題がコンテナー/ホスト境界にあることを確認していると思います。そのため、そのUDPポートを開くことができるかどうかを確認します。更新: UDPポート1434を開いても解決しませんでした。
その他のアップデート—回避策は達成されましたが、リソース制約の問題ではありません。Windowsコンテナに大きなメモリ割り当てを設定することに関連する問題があるようです— 3gと2gでも同様のエラーが発生しましたが、最終的に1.5gでコンテナを起動できました。docker stats
コンテナーのの違いを確認しましたが、コンテナーがデフォルトの割り当てである1GBで実行されていることを確認しました(そう思います)。デフォルトの設定では、PRIV WORKING SET stat(ドキュメントを見つけることはできませんが、私の推測ではRAMです)は700MiBから850MiBの間です。とdocker run —memory="1.5g"
セット、それは約1.0GiBです。したがって、拡張はされましたが、以前よりも多くの割り当てを解放しているようです。私はこれを(おそらく間違って)解釈します。これは、このサーバー(まったく負荷がなく、ユーザーデータベースがない)がメモリの負荷を受けていないことを意味します。max server memory設定をチェックして、デフォルトの最大値である2PiBに設定されていることを確認しました。
その後、物事は奇妙になりました。私はまださまざまな場所から私のpowershellスクリプトを実行して物事をテストしています。コンテナ内は高速、ホストは低速。次に、ネットワーク上の別のWindowsマシンにRDPを実行し、そのマシンからスクリプトを実行して、IPでWindows 10ホストに接続しました。そしてそれは速い!これは、localhostであるはずの何かに接続するときに、SMOがポート1433 TCP以外のものを使用してSQL Serverに接続しようとし、TCP接続にフォールバックする前に非常に長いタイムアウトを待つという理論をサポートしているようです。
私はこの理論を検証するために、localhost以外の名前でlocalhostを参照するhostsファイルエントリを入力してみることにしました。
127.0.0.1 dockersucks
SSMSでlocalhostまたは "。"の代わりにdockersucksに接続しましたが、すぐに高速になりました。オブジェクトエクスプローラーのナビゲートは通常どおりであり、データベースやサーバーのプロパティのアタッチなどのパネルを開くのは、通常と同じくらい迅速に行われました。また、このエイリアスをサーバー名として使用してWindows 10ホストからpowershellスクリプトを実行したところ、高速でした。
なぜこの問題が発生しているのか、その名前で「localhost」への接続を修正する方法があるかどうかの説明をまだ探しているので、回答の代わりにこの更新を質問に追加しました。