SMO, SSMS медленны для управления SQL Server в Docker при подключении к localhost

9

TL; DR: при подключении к контейнеру Docker SQL Server через имя, которое разрешается в loopback IPv6 ( ::1), вызовы 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 и выполняю запросы к экземпляру, используя sqlcmd и SSMS 17.4 на хосте Windows (подключение к localhost или «.»), И операции SQL Студия на Mac по соседству подключается по IP. Я не вижу заметных проблем с производительностью при выполнении запросов таким образом.

В SSMS я также могу просматривать обозреватель объектов, но если я пытаюсь что-то сделать из меню правой кнопки мыши на объекте в проводнике объектов, например открыть окно параметров экземпляра или присоединить базу данных, SSMS не показывает ответ около 5 -10 минут, после чего он либо отображает запрошенное мной окно, либо отображает это сообщение об ошибке:

Сообщение об ошибке SSMS

Я также пытаюсь выполнить некоторые сценарии PowerShell для этого экземпляра, используя объект SMO Scripter , и вижу такое же поведение. Сценарий PS просматривает объекты в базе данных и записывает их в файл, и, хотя он работает для сравнительного быстрого сбора списка объектов, для создания сценария каждого отдельного объекта требуется 5-10 минут - слишком медленно, чтобы его можно было использовать.

Я догадываюсь, что одного незащищенного порта недостаточно, и что SMO и SSMS пытаются соединиться аналогичным образом, что замедляет их. Может ли быть так, что при подключении к локальному узлу эти инструменты предполагают наличие других каналов связи, которые, как правило, не защищены брандмауэром? Есть ли дополнительные параметры подключения, которые я мог бы использовать? Может ли кто-нибудь подтвердить мое предположение, что SSMS использует SMO или что-то еще для общения с SQL Server?


ОБНОВЛЕНИЕ: Я все еще исследую, но вполне вероятно, что это проблема Docker, связанная с ограниченностью ресурсов. Это сбивает с толку , потому что большая часть документации , кажется, указывает , что Windows , контейнеры не имеют каких - либо ограничений ресурсов по умолчанию (и они могут не быть установлены в Docker для графического интерфейса пользователя Windows - только для контейнеров Linux ), но мне кажется , что на самом деле, Windows контейнеры, работающие в Windows 10, по умолчанию выделяют 1 ГБ памяти Я все еще пытаюсь выяснить, как проверить работающий контейнер, чтобы увидеть его ОЗУ и распределение ЦП, но затем я должен просто попытаться увеличить их из значений по умолчанию, используя docker runпараметры.


ДОПОЛНИТЕЛЬНОЕ ОБНОВЛЕНИЕ: мне не удалось получить какой-либо надежный показатель из докера, который говорит мне, какие ограничения ЦП и памяти он имеет для контейнера. Варьируя исследование указывает на то, что либо Докер контейнеры не имеют ограничение памяти по умолчанию, или что они делают , и это 1 Гб, но все , что я могу проверить , на данный момент , что docker statsговорит SQL контейнер только с использованием между 750 и 850 мег, а когда Я пытаюсь добавить параметр запуска, чтобы установить доступную память на 4 ГБ, это ошибки. Поэтому я перестал следить за этим потоком запросов и пошел к другой проверке интуиции: входил в интерактивный сеанс powershell в работающем контейнере, а затем вызывал мой скрипт powershell, связанный выше, изнутри контейнера.

Запуск внутри контейнера не было проблемой. Всего за пару минут он пронзил 2780 объектов. Я думаю, это подтверждает, что проблема связана с границей контейнера / хоста, поэтому я собираюсь посмотреть, смогу ли я открыть этот порт UDP. ОБНОВЛЕНИЕ: Открытие порта 1434 UDP не помогло.


БОЛЬШЕ ОБНОВЛЕНИЙ — Обходной путь достигнут, не проблема с ограничением ресурсов: Кажется, есть проблемы, связанные с установкой больших выделений памяти для контейнеров Windows - я получал аналогичные ошибки для 3g и 2g, но в итоге смог запустить контейнер с 1,5g, и Я ДЕЙСТВИТЕЛЬНО видел разницу в docker statsконтейнере, который (я думаю) подтверждает, что он работает с выделением по умолчанию 1 ГБ. При настройках по умолчанию показатель PRIV WORKING SET (для которого я не могу найти никакой документации, но, скорее всего, это ОЗУ), составляет от 700 МБ до 850 МБ. Сdocker run —memory="1.5g"установить, это около 1,0 ГБ. Таким образом, он расширился, но, похоже, оставил больше свободных ресурсов, чем раньше. Я интерпретирую это (возможно, неправильно), чтобы означать, что этот сервер (который работает абсолютно без нагрузки и не имеет пользовательских баз данных) не находится под давлением памяти. Я проверил настройку max server memory, чтобы убедиться, что она установлена ​​по умолчанию на максимум 2PiB.

Тогда все стало странно. Я все еще проверяю вещи, выполняя свой скрипт powershell из разных мест. Быстро внутри контейнера, медленно на хосте. Затем я перешел на другой компьютер с Windows в сети и запустил скрипт с ЭТОГО компьютера, подключившись к моему хосту Windows 10 по IP. И это было БЫСТРО! Похоже, что это подтверждает теорию, что при подключении к чему-то, что должно быть локальным, SMO пытается подключиться к SQL Server, используя что-то отличное от порта 1433 TCP, который ждет очень долгое время ожидания, прежде чем вернуться к TCP-соединению.

Я решил попробовать проверить эту теорию, введя запись в файле hosts для ссылки на localhost по имени, отличному от localhost:

        127.0.0.1       dockersucks

Я подключился в SSMS к dockersucks вместо localhost или ".", И сразу все стало быстрее. Навигация по объекту проводника была обычной, и открытие панелей, таких как присоединение базы данных или свойств сервера, происходило так же быстро, как обычно. И когда я запустил свой скрипт powershell с хоста Windows 10, используя этот псевдоним в качестве имени сервера, он также был быстрым.

Я добавил это обновление к вопросу вместо ответа, так как я все еще ищу объяснение, почему это происходит, и есть ли способ исправить это для соединений с "localhost" с таким именем.

NReilingh
источник
Может быть, ваш экземпляр докера находится под напряжением? Если бы это была проблема с портом, я сомневаюсь, что вы вообще увидите, как она работает, поэтому я бы не стал тратить много времени на эту дорогу.
LowlyDBA
Да, я думал об этом, но производительность запросов кажется хорошей, поэтому кажется, что она ограничена только определенными типами действий. Мне также нужно протестировать запуск SMO-содержимого из INSIDE контейнера и убедиться, что проблемы там нет.
NReilingh
1
Я не пропустил эту часть. SQL Server использует пул соединений. Я понимаю, что это расстраивает, но я также хочу убедить вас убедиться, что у контейнера (или «странной виртуальной машины Hyper-V lite» в этом случае) достаточно ОЗУ. Ваш PS скрипт RAN «быстро», но минуты пробежать ~ 3000 объектов является медленным в машине с достаточным количеством оперативной памяти (т.е. более 2 Гб).
Рэндольф Вест
1
Честно говоря, вам, вероятно, лучше развернуть виртуальную машину Ubuntu Hyper-V на своем компьютере и установить на нее SQL Server для Linux.
Рэндольф Вест
1
@bazzilic Я объясняю почему в своем ответе. Пожалуйста, прокомментируйте там, если вам нужно разъяснение.
NReilingh

Ответы:

3

Скорее всего, это проблема с нехваткой оперативной памяти.

Вещи, чтобы проверить:

  • Контейнеру выделено 4 ГБ ОЗУ? Проверьте этот ответ .
  • Вы сконфигурировали параметр Max Server Memory для SQL Server внутри контейнера? В зависимости от того, сколько оперативной памяти SQL Server видит в контейнере, может быть установлено значение от 1 до 3,25 ГБ.
  • Не израсходована ли оперативная память вашего хоста, и возможно ли, что Docker выполняет пейджинг на диск? Закройте любые посторонние приложения (веб-браузеры являются большими потребителями оперативной памяти). Для работы SSMS требуется около 1 ГБ оперативной памяти.
  • Это быстрее после перезагрузки?

Если бы я делал это сам, я бы установил Docker Community Edition для Windows из хранилища Docker , а затем установил образ Docker SQL Server таким образом.

Если ваше интернет-соединение достаточно быстрое, вы можете начать работу менее чем за 5 минут, и сможете распределять ресурсы намного проще.

РЕДАКТИРОВАТЬ: Ах, сеть.

Рэндольф Вест
источник
Не уверен, что вы неправильно это поняли, но я не использую SSMS внутри контейнера. Это невозможно, так как контейнеры Windows в настоящее время не поддерживают RDP-соединения или графические интерфейсы. Я уже знаю, что SQL Server не медленный - но мне нужно выяснить, не истощаю ли я этот док-контейнер для ресурсов. Хост Windows 10, на котором запущен контейнер и SSMS, имеет 10 ГБ ОЗУ и 2 ядра, но я не уверен, сколько выделяется для контейнера.
NReilingh
Мой ответ был переписан
Рэндольф Вест
Смотрите Q update для дополнительной информации. Обратите внимание, что это собственная сборка образа контейнера в Microsoft, поэтому я думаю, что мы вполне уверены, что настройки внутри контейнера не будут проблемой.
NReilingh
2
Пожалуйста, не делайте этого предположения!
Рэндольф Вест
@NReilingh Я добавил URL-адрес в мой ответ, чтобы вы могли исследовать этот -mвариант.
Рэндольф Вест
3

Ключевое отличие здесь заключается в том, пытается ли SSMS / SMO соединиться с IPv4 или IPv6. Если вы сделаете a 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 вызывает это сломать.

NReilingh
источник
Вы пытались подключиться к tcp: localhost? Может случиться так, что SSMS / SMO пытаются подключиться к общей памяти или именованным каналам, когда имя является localhost или (local) или даже "." и :: 1. Я не знаю, использует ли SSMS 17.4 SMO в Object Explorer, но я думаю, что это возможно.
Мистер Магу,
@MisterMagoo Ввод tcp:localhostв поле имени сервера, кажется, не работает вообще, но я попытался явно указать TCP / IP в свойствах соединения без улучшения. Я все еще думаю, что проблема заключается в медленном отступлении 127.0.0.1для локального хоста при ::1сбое. Я думаю, что мои окна запросов работали, потому что они поддерживали соединение, тогда как мой сценарий, использующий SMO, (возможно) создавал новые соединения снова и снова.
NReilingh
1
@NReilingh Я вижу ту же самую проблему - ваши устранение неполадок и объяснения были действительно полезны. Адресация моего контейнера сервера sql как 127.0.0.1 ( не localhost ) из моей среды хоста была единственным способом, которым я мог заставить соединения между хостом и контейнером работать нормально.
Роджерсиллито