localhost에 연결할 때 Docker에서 SQL Server 관리 속도가 느린 SMO, SSMS


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 호스트 (localhost 또는 "."에 연결)에서 sqlcmd 및 SSMS 17.4를 사용하여 인스턴스에 대해 쿼리를 실행하고 SQL 작업을 성공적으로 수행했습니다. IP로 연결되는 옆집 맥의 스튜디오. 이 방법으로 쿼리를 실행할 때 눈에 띄는 성능 문제가 없습니다.

SSMS에서 객체 탐색기를 탐색 할 수도 있지만 인스턴스 탐색기 창을 열거 나 데이터베이스를 연결하는 등 객체 탐색기의 객체에서 마우스 오른쪽 버튼 메뉴에서 무언가를 시도하면 SSMS가 약 5에 대한 응답을 표시하지 않습니다. -10 분이되면 요청한 창을 표시하거나이 오류 메시지를 표시합니다.

SSMS 오류 메시지

또한 SMO Scripter object를 사용 하여이 인스턴스에 대해 PowerShell 스크립팅을 시도 하고 동일한 종류의 동작을 확인 하려고합니다 . PS 스크립트는 데이터베이스의 객체를 반복하여 파일로 스크립팅하고, 객체 목록을 비교적 빠르게 수집하는 동안 각 개별 객체는 스크립트를 작성하는 데 5-10 분이 걸리므로 사용하기에는 너무 느립니다.

노출 된 단일 포트로는 충분하지 않으며 SMO와 SSMS는 속도를 늦추는 비슷한 방식으로 연결하려고합니다. 로컬 호스트에 연결할 때 이러한 도구가 일반적으로 방화벽이되지 않는 다른 통신 채널이 있다고 가정 할 수 있습니까? 사용할 수있는 추가 연결 매개 변수가 있습니까? 누구든지 SSMS가 SMO 또는 다른 것을 사용하여 SQL Server와 통신하고 있다는 가정을 확인할 수 있습니까?


업데이트 : 여전히 조사 중이지만 이것이 리소스 제약과 관련된 Docker 문제라는 것이 그럴듯합니다. 대부분의 문서가 Windows Containers에 기본 리소스 제약 조건이 없음을 나타 내기 때문에 혼란 스럽지만 (Windows 컨테이너 의 Docker 에서는 Linux 컨테이너에만 설정할 수 없음 ) 실제로는 Windows 인 것처럼 보입니다. Windows 10에서 실행되는 컨테이너는 1GB의 기본 RAM 할당을 갖습니다. 여전히 실행중인 컨테이너를 검사하여 RAM 및 CPU 할당을 확인하는 방법을 알아 내려고 노력하고 있지만 다음에는 매개 변수를 사용하여 기본값에 관계없이 컨테이너를 늘리려 고합니다 .docker run


추가 업데이트 : 컨테이너에 대해 어떤 CPU 및 메모리 제한이 있는지 알려주는 신뢰할 수있는 메트릭을 도커에서 가져 오는 데 실패했습니다. 다양한 연구에 따르면 도커 컨테이너에는 기본적으로 메모리 제한이 없거나 1GB라는 것이 있지만 현재 확인할 수 docker stats있는 것은 SQL 컨테이너가 750에서 850 메가 사이 에서만 사용 된다는 것입니다. 사용 가능한 메모리를 4GB로 설정하기 위해 실행 매개 변수를 추가하려고하면 오류가 발생합니다. 그래서 그 스레드를 따라가는 것을 멈추고 다른 용기 검사를 진행했습니다. 실행중인 컨테이너에 대화 형 powershell 세션을 입력 한 다음 컨테이너 내부 에서 위에서 링크 된 powershell 스크립트를 호출 합니다.

컨테이너 내부에서 실행하면 문제가 없었습니다. 불과 2 분만에 2780 개의 물체를 뚫었습니다. 컨테이너 / 호스트 경계에 문제가 있음을 확인하므로 해당 UDP 포트를 열 수 있는지 확인하겠습니다. 업데이트 : 포트 1434 UDP를 여는 것이 도움이되지 않았습니다.


추가 업데이트 — 해결 방법 달성, 리소스 제약 문제가 아님 : Windows 컨테이너에 대해 큰 메모리 할당 설정과 관련된 문제 가있는 것 같습니다. 3g 및 2g에 대해 유사한 오류가 발생했지만 결국 1.5g로 컨테이너를 시작할 수있었습니다. docker stats컨테이너가 기본 할당 1GB로 실행되고 있음을 확인한 컨테이너 의 차이점을 보았습니다 . 기본 설정에서 PRIV WORKING SET 통계 (문서를 찾을 수는 없지만 RAM은 RAM입니다)는 700MiB와 850MiB 사이입니다. 와docker run —memory="1.5g"설정하면 약 1.0GiB입니다. 따라서 확장되었지만 이전보다 더 많은 할당을 사용하지 않는 것으로 보입니다. 나는 (아마도 부정확하게)이 서버 (절대적으로 NO로드를 실행하고 사용자 데이터베이스가 없음)가 메모리 압력을 받고 있지 않다는 것을 의미한다고 해석합니다. max server memory 설정을 확인하여 기본 최대 값 인 2PiB로 설정되어 있는지 확인했습니다.

그런 다음 상황이 이상해졌습니다. 다양한 위치에서 powershell 스크립트를 실행하여 여전히 테스트 중입니다. 컨테이너 내부가 빠르며 호스트 속도가 느립니다. 그런 다음 네트워크의 다른 Windows 시스템에 RDP를 연결하고 IP로 Windows 10 호스트에 연결하여 THAT 시스템에서 스크립트를 실행했습니다. 그리고 그것은 빠르다! 이것은 로컬 호스트로 연결되는 것으로 연결될 때 SMO가 포트 1433 TCP 이외의 다른 것을 사용하여 SQL Server에 연결하려고 시도하고 TCP 연결로 돌아 가기 전에 매우 긴 시간 초과를 기다리는 이론을 지원하는 것으로 보입니다.

localhost 이외의 이름으로 localhost를 참조하기 위해 hosts 파일 항목을 입력하여이 이론의 유효성을 검사하기로 결정했습니다.

        127.0.0.1       dockersucks

SSMS에서 localhost 또는 "."대신 dockersucks에 연결했는데 즉시 상황이 더 빨랐습니다. 객체 탐색기 탐색은 평소와 같았으며 데이터베이스 연결 또는 서버 속성과 같은 패널을 여는 것이 평소처럼 빠르게 발생했습니다. 그리고이 별칭을 서버 이름으로 사용하여 Windows 10 호스트에서 powershell 스크립트를 실행했을 때도 빠릅니다.

이 문제가 발생하는 이유에 대한 설명을 찾고 있으며 해당 이름으로 "localhost"에 연결하기 위해 수정하는 방법이있는 경우 답변 대신 질문에이 업데이트를 추가했습니다.


아마도 도커 인스턴스에 전원이 공급되고 있습니까? 그것이 포트 문제라면 나는 그것이 당신이 전혀 작동하지 않을 것이라고 생각합니다. 그래서 나는 그 길을 따라 많은 시간을 소비하지 않을 것입니다.
LowlyDBA

예, 그것에 대해 생각하고 있었지만 쿼리 성능이 좋아 보이므로 특정 유형의 작업에만 국한된 것 같습니다. 또한 컨테이너 내부에서 SMO 작업을 테스트하고 문제가 없는지 확인해야합니다.
NReilingh

1
나는 그 부분을 놓치지 않았다. SQL Server는 연결 풀링을 사용합니다. 나는 이것이 실망 스럽지만 컨테이너 (또는이 경우 "이상한 Hyper-V lite VM")에 충분한 RAM이 있는지 확인하고 싶습니다. PS 스크립트가 "빠르게"실행되었지만 충분한 RAM (예 : 2GB 이상)이있는 시스템에서 ~ 3000 개의 개체를 실행하는 데 몇 분이 느립니다 .
랜돌프 웨스트

1
완벽하게 정직하게 말하면 컴퓨터에서 Ubuntu Hyper-V VM을 가동하고 Linux 용 SQL Server를 설치하는 것이 좋습니다.
랜돌프 웨스트

1
@ bazzilic 나는 내 대답에 이유를 설명합니다. 설명이 필요하면 의견을 보내주십시오.
NReilingh

답변:


3

이것은 RAM 부족 문제 일 가능성이 높습니다.

확인 사항 :

  • 컨테이너에 4GB의 RAM이 할당되어 있습니까? 이 답변을 확인하십시오 .
  • 컨테이너 내부에서 SQL Server에 대한 최대 서버 메모리 설정을 구성 했습니까? 컨테이너에서 볼 수있는 RAM SQL Server의 양에 따라 1GB ~ 3.25GB로 설정 될 수 있습니다.
  • 호스트의 RAM이 모두 소모 되었습니까? Docker가 디스크로 페이징하고있을 수 있습니까? 외부 응용 프로그램을 모두 닫습니다 (웹 브라우저는 RAM을 많이 소비합니다). SSMS를 사용하려면 약 1GB의 작업 RAM이 필요합니다.
  • 재부팅 후 더 빠릅니까?

이 작업을 직접 수행하는 경우 Docker store에서 Windows 용 Docker Community Edition을 설치 한 다음 SQL Server Docker 이미지 를 설치하십시오 .

인터넷 연결이 충분히 빠르면 5 분 안에 시작하여 훨씬 더 쉽게 리소스를 할당 할 수 있습니다.

편집 : 아, 네트워킹.


당신이 이것을 이해하고 있는지 확실하지 않지만 컨테이너 내부 에서 SSMS를 실행하고 있지 않습니다 . Windows 컨테이너는 현재 RDP 연결 또는 GUI를 지원하지 않기 때문에 불가능합니다. 이미 SQL Server가 느리지 않다는 것을 알고 있습니다. 그러나이 도커 컨테이너에 리소스가 부족한지 알아 내야합니다. 컨테이너와 SSMS를 실행하는 Windows 10 호스트에는 10GB의 RAM과 2 개의 코어가 있지만 컨테이너에 할당되는 양이 확실하지 않습니다.
NReilingh

내 대답은 다시 작성되었습니다
Randolph West

추가 정보는 Q 업데이트를 참조하십시오. 이것은 Microsoft의 자체 컨테이너 이미지 빌드이므로 컨테이너 내의 설정이 문제가되지 않는다고 가정하는 것이 안전하다고 생각합니다.
NReilingh

2
그렇게 가정하지 마십시오!
랜돌프 웨스트

@NReilingh -m옵션 에 대한 조사를 위해 답변에 URL을 추가했습니다 .
랜돌프 웨스트

3

여기서 중요한 차이점은 SSMS / SMO가 IPv4 또는 IPv6에 연결을 시도하는지 여부입니다. ping localhost명령 프롬프트에서을 수행 ::1하면 IPv6에 해당하는로 확인되는 것을 볼 수 127.0.0.1있습니다. 에 연결하는 .것도 마찬가지입니다.

귀하의 docker run명령은 포트 1433를 노출합니다 127.0.0.1. netstat -a사용 가능한 포트를 확인하기 위해 실행 하여이를 확인할 수 있습니다.

생성 한 호스트 파일 별칭은로 직접 확인 127.0.0.1되지만 127.0.0.1SSMS 에서 직접 연결 하여 문제를 해결할 수 있으므로 필요하지 않습니다 . 호스트 시스템에서 IPv6을 완전히 끄면 작동 할 수도 있지만 Windows 10에서 이것이 얼마나 바람직한 지 잘 모르겠습니다.

IPv6로 인해 왜이 문제가 발생했는지 누군가가 말해 줄 수 있다면 대체 대답을 고려할 것입니다.


tcp : localhost에 연결을 시도 했습니까? 이름이 localhost 또는 (local) 또는 ""인 경우 SSMS / SMO가 공유 메모리 또는 명명 된 파이프 연결을 시도하고있을 수 있습니다. 그리고 :: 1. SSMS 17.4가 개체 탐색기에서 SMO를 확실히 사용하는지 모르겠지만 가능하다고 생각합니다.
Mister Magoo

@MisterMagoo tcp:localhost서버 이름 필드에 입력 해도 전혀 작동하지 않는 것 같지만 연결 속성에서 TCP / IP를 명시 적으로 지정하지 않고 개선하려고했습니다. 나는 여전히 문제가 127.0.0.1로컬 호스트에 ::1실패하면 실패 한다고 느낍니다 . SMO를 사용하는 스크립트가 (아마도) 새로운 연결을 반복해서 생성하는 동안 쿼리 창은 연결을 유지했기 때문에 작동한다고 생각합니다.
NReilingh

1
@NReilingh이 동일한 문제가 표시됩니다. 문제 해결 및 설명이 정말 도움이되었습니다. 호스트 환경에서 SQL Server 컨테이너를 127.0.0.1 ( localhost 아님)로 처리하는 것이 호스트와 컨테이너 연결을 정상적으로 작동 시키는 유일한 방법이었습니다 .
rogersillito
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.