스레드 및 태스크 아키텍처
- Version : SQL Server 2005, 2008, 2008R2
스레드는 응용프로그램 논리를 여러 동시 실행 경로로 분리할 수 있게 하는 운영체제 기능이다. 이 기능은 여러 태스크를 동시에 수행 할 때 유용하다.
운영체제는 응용프로그램 인스턴스를 실행 할 때 인스턴스를 관리하는 프로세스라는 단위를 만든다. 프로세스에는 실행 스레드가 하나씩 있으며 실행 스레드는 응용 프로그램 코드가 수행하는 일련의 명령이다.
- 프로세스 개념 : http://sqlmvp.kr/140189245176
예를 들어 차례로 수행되는 단일 명령 집합의 경우 응용 프로그램 하나에 하나의 스레드만 있다. 그러나 복잡한 응용프로그램의 경우 차례 대로 실행 되지 않고 동시에 수행 될 수 있는데(대부분의 프로그램은 동시 수행을 한다.) 여러 태스크를 포함한다. 이 경우 응용 프로그램은 각 태스크에 대해 별도의 프로세스를 시작해야 한다.
프로세스를 시작하는데 많은 리소스가 필요하다. 따라서 응용 프로그램은 프로세스를 시작하는 대신에 별도의 스레드를 시작한다. 이렇게 하면 상대적으로 사용량이 줄어들며 각 스레드는 프로세스와 관련된 다른 스레드와 독립적으로 실행되도록 예약 할 수 있다.
- 스레드 개념과 다중 스레드 : http://sqlmvp.kr/140189762500
스레드는 단일 CPU가 있는 복잡한 응용 프로그램에서 더 효율적으로 사용 할 수 있다. 하나의 CPU가 있으면 한 번에 하나의 스레드만 실행 할 수 있다. 한 스레드가 디스크 읽기 또는 쓰기와 같은 CPU를 사용하지 않은 장기 실행 작업을 실행하는 경우 첫 번째 작업이 완료될 때까지 다른 스레드를 실행 할 수 있다. 다른 스레드가 작업이 끝날 때까지 기다리는 동안 스레드를 실행 할 수 있으면 응용프로그램이 CPU의 사용을 최대화 할 수 있다.
데이터베이스 서버와 같이 여러 사용자가 사용하는 디스크 입출력 집중형 시스템에서는 스레드의 장점이 잘 활용 되는 시스템이다. 여러 CPU가 있는 시스템에서는 동시에 여러 스레드를 실행 할 수 있다. 예를 들어 CPU가 8개이면 동시 실행 스레드는 8개 이다.
SQL Server의 각 인스턴스는 별도의 운영체제 프로세스이다. 각 인스턴스는 잠재적으로 동시에 발생하는 사용자의 수 많은 요청을 처리해야 한다. SQL Server 인스턴스는 Microsoft Windows 스레드 또는 파이버를 사용하여 동시 태스크를 효율적으로 관리 한다.
SQL Server 인스턴스는 항상 시스템 프로세스에 대해 몇 개의 스레드를 실행 한다. 각 서버 Net-Library에 대한 하나 이상의 스레드, 네트워크 I/O를 처리하기 위한 네트워크 스레드 및 서비스 제어 관리자와 통신하기 위한 신호 스레드 등 여러 스레드를 실행 한다.
각 SQL Server 인스턴스에는 운영체제와 비슷한 환경을 구현하는 내부 계층이 있다. Windows 커널을 호출하지 않고도 동시 태스크 일정을 예약하고 동기화 하는데 이 내부 계층이 사용 된다. 또한 파이버나 Windows 스레드의 일정을 예약하는 데도 이 내부 계층을 효과적으로 사용 할 수 있다.
각 SQL Server 인스턴스는 사용자 쿼리를 처리하기 위한 Windows 스레드 또는 파이버 풀을 유지 관리 한다. 이러한 풀의 최대 크기는 max worker threads 서버 구성 옵션으로 제어 할 수 있다.
- Max worker threads : http://sqlmvp.kr/140150957238
[현재 적용된 Max worker threads] --6core, 2CPU, Hyper Thread, x64, RAM 74G SELECT MAX(SI.cpu_count) as logical_cpu_count, MAX(SI.scheduler_count) as scheduler_count, MAX(SI.max_workers_count) as max_workers_count, SUM(OS.current_workers_count) as current_workers_count, SUM(OS.active_workers_count) as active_workers_count FROM sys.dm_os_sys_info SI, sys.dm_os_schedulers OS GO
select 512 + (24-4)*16 GO
|
스레드 및 파이버는 리소스를 많이 사용하지 않지만 계속해서 소비 한다. 수 많은 사용자가 연결된 시스템에서 연결당 하나의 작업자 스레드가 있으면 리소스 사용량이 많아 SQL Server의 효율성이 감소할 수 있다.
대부분의 연결이 실제 클라이언트로부터 일괄처리를 받는데 많은 시간을 소비하므로 각 사용자 연결에 전용 작업자 스레드를 할당 할 필요가 없다. 대신 SQL Server 인스턴스는 작업자 스레드 풀을 사용한다.
작업자 스레드 풀은 해당 인스터턴스에서 동시에 일괄 처리를 실행하는 사용자 연결 수를 처리하기에 충분할 만큼 필요하다. Max worker threads 옵션을 0 (기본값)으로 유지하면 SQL Server 인스터턴스가 여러 작업자 스레드간에 사용자 연결을 적절히 매핑하여 리소스를 너무 많이 사용하지 않도록 한다.
Lightweight pooling 서버 구성 옵션은 SQL Server 인스턴스가 스레드 또는 파이버를 사용할지를 제어한다. 이 옵션의 기본값은 0이며 이 값은 SQL Server 인스턴스가 max worker threads 옵션에 설정된 값만큼 작업 스레드당 하나씩 Windows 스레드를 예약함을 나타낸다.
Lightweight pooling을 1로 설정하면 SQL Server에서 Windows 스레드 대신 파이버를 사용한다. 이를 파이버 모드 실행이라고 한다. 파이버 모드에서는 SQL Server 인스턴스가 SQL 스케줄러당 Windows 스레드를 하나씩 할당한 다음 max worker threads 설정된 값만큼 작업 스레드당 하나씩 파이버를 할당 한다. SQL Server 인스터턴스는 Windows 스레드 또는 파이버를 사용 할 때 동일한 알고리즘을 통해 태스크를 예약하고 동기화 한다.
SQL Server Express에선느 파이버 모드를 지원하지 않음. |
일상적인 작업에는 파이버 모드를 사용하지 않는 것이 좋다. 파이버 모드를 사용하면 컨텍스트 전환을 활용하지 못해 성능이 저하될 수 있으며 SQL Server의 일부 구성요소가 파이버 모드에서 제대로 작동하지 않을 수 있다.
- 컨텍스트 전환 : http://sqlmvp.kr/140189479939
응용프로그램에서 데이터베이스 엔진에 연결하면 응용프로그램에 세션ID(SPID)가 할당 된다. 연결 유효 기간 동안 유지 관리되어야 하는 모든 정보는 이 SPID와 연결된 내부 데이터 구조를 통해 관리 된다.
SQL Server 인스터턴스가 클라이언트로부터 일괄 처리를 받으면 일괄 처리를 하나 이상의 태스크로 나눈 다음 작업자 스레드 풀의 사용 가능한 작업자 스레드를 각 작업에 연결 한다. 작업자 스레드는 작업 유효기간 동안 태스크에 바인딩 된다. 작업자 스레드는 스레드와 연결된 SQL 스케줄러에서 요청을 실행 한다.
사용할 수 있는 빈 작업자 스레드가 없고 max worker threads 값에 아직 도달하지 않은 경우 SQL Server 인스턴스가 새 일괄 처리에 새 작업자 스레드를 할당 한다. 사용할 수 있는 빈 스레드 또는 파이버가 없고 max worker threads 값이 이미 도달한 경우 SQL Server 인스턴스가 작업자 스레드가 해제될 때까지 새 태크스를 차단한다.
작업자 스레드를 태크스에 연결하면 일괄 처리에서 생성한 마지막 결과 집합이 클라이언트에 반환되는 경우와 같이 작업이 완료 될 때까지 이 연결 상태가 유지 된다. 작업이 완료되면 작업자 스레드가 해제되어 다음일괄 처리에 있는 태스크와 연결 할 수 있다.
데이터베이스 엔진은 일괄 처리를 받은 시점부터 결과가 클라이언트에 반환 될 때까지 연결에 대해 작업을 수행 해야 한다. 이 기간 동안 일괄 처리에 대해 처리 작업이 필요하지 않을 때도 있다. 예를 들어 읽기 작업이 현재 쿼리에 필요한 데이터를 읽어 들이는 동안 또는 다른 일괄 처리의 잠금을 해제할 때까지 데이터베이스 엔진에서 대기해야 할 때가 있다. 태스크와 작업자 스레드 간 연결은 일부 리소스에 대해 작업이 차단된 경우에도 유지 된다.
데이터베이스 엔진에서는 일괄 처리와 연결된 태스크 처리를 시작 할 때마다 작업과 연결된 작업자 스레드가 작업을 수행하도록 일정을 예약한다. 작업자 스레드가 해당 태스크에 대해 작업을 완료하면 SQL Server 인스턴스가 준비된 다음 작업으로 작업자 스레드를 디스패치한다. SPID는 해당 연결의 유효기간 동안 일정하게 유지 된다.
오래 실행되는 연결에는 다수의 작업자 스레드에 의해 실행되는 개별 일괄 처리 태스크가 여러 개 있을 수 있다. 일부 작업은 병렬처리 할 수도 있다. 이 경우 동시에 다수의 작업자 스레드에 의해 실행되는 여러 개의 태스크가 일괄 처리에 포함 될 수 있다.
- 쿼리 병렬 처리 수준 : http://sqlmvp.kr/140189464520
[참고 자료]
- 스래드 및 태스크 아키텍처 :
http://msdn.microsoft.com/ko-kr/library/ms176043(v=sql.105).aspx
- SQL Server 일괄 처리 또는 태스크 일정 예약 :
http://msdn.microsoft.com/ko-kr/library/ms189267(v=sql.105).aspx
2013-06-13 / 강성욱 / http://sqlmvp.kr
'SQL Server > SQL Server Tip' 카테고리의 다른 글
스레드 및 파이버 실행 (0) | 2015.07.22 |
---|---|
CPU에 스레드 할당 및 lightweight pooling 옵션 사용 (0) | 2015.07.22 |
메모리 관리 아키텍처 – NUMA 버퍼 풀 증가 및 축소 (0) | 2015.07.22 |
메모리 관리 아키텍처 – NUMA 지원 방법 (0) | 2015.07.22 |
메모리 관리 아키텍처 – NUMA(Non-Uniform Memory Access)이해 (0) | 2015.07.22 |