본문 바로가기

SQL Server/SQL Server Tip & Tech

Disk Partition Alignment

개요
스토리지의 성능 최적화를 위해 우리가 고려해야할 요소가 많습니다.

아마 디스크 개수, RAID Mode, Stripe Size, File Allocation Unit Size 등을 떠올릴 수 있을 겁니다.

그런데 이런 요소들 중 과소 평가되거나, 혹은 아예 고려하지 않는 것으로 "Disk Partition Alignment" 라는 부분이 있습니다.
우리말로 하면 "디스크 파티션 정렬" 정도가 되겠군요.

참고로 파티션을 정렬한다는 것은 파티션이 시작하는 시작점을 특정 값으로 설정하는 것을 의미합니다.


첫번째 의문
- 파티션은 원래 0번째 byte 지점에서 시작하는게 아닌가?

네, 아닙니다.

디스크에서 기록이 시작되는 맨 앞부분의 63 섹터 (= 31.5 KB)는 MBR - Master Boot Recoder - 영역이기 때문인데요.
따라서 파티션의 기본 시작 지점은 64번째 섹터부터가 됩니다.

두번째 의문
- 이게 필요한 작업이라면 SE 분들이 알아서 해주지 않나? DBA가 이런 것 까지 신경써야하는 이유가 있을까?

개인적인 경험으로는 6개국의 퍼블리셔를 통해 게임을 런칭하면서 "디스크 파티션 정렬"을 언급하거나 적용한 SE팀은 한 곳도 없었습니다.

경험많은 SE에게도 SQL Server의 스토리지 최적화를 위해 디스크 파티션을 정렬해야 한다는 것은 생소하다는 의미라는 거겠죠.

세번째 의문
- 이 작업이 성능 최적화에 도움이 되는 이유는 무엇인가?

몇 가지 배경 지식이 필요합니다.

1. Stripe Unit Size
대부분의 서버 장비는 디스크를 RAID로 구성합니다.
RAID 설정을 만져보신 분들은 잘 아시겠지만, Stripe Unit Size는 RAID 설정 과정에서 결정하게 되는 값 중 하나죠.
글로 설명하면 장황할 것 같으니 좀 더 자세한 내용을 알고 싶으시다면, 잠깐 구글링하고 오시면 되겠습니다. ^^

2. Cluster Size = File Allocation Unit Size
FAT, FAT32, NTFS.. 이게 무엇인지 잘 아실겁니다. Windows OS에서 사용하는 File System이죠.
이제는 PC에서도 NTFS를 사용하기 때문에 각각의 차이를 굳이 언급하진 않겠습니다.

여기서 중요한건 우리가 NTFS를 선택하여 파티션을 포맷할 때 클러스터 사이즈를 얼마로 정할 것인가 입니다.
역시 클러스터 사이즈에 대한 자세한 내용은 구글링을 추천합니다.

참고로 NTFS의 기본 클러스터 사이즈는 4KB입니다.

3. SQL Server에 적절한 Stripe Unit Size 및 Cluster Size 는?
SQL Server가 디스크에 데이터를 입출력하는 I/O의 단위는 extent입니다.

1 extent = 8 pages = 64KB

하드웨어 공급자가 특별히 권고하는 값이 없다면, Stripe Unit Size와 Cluster Size는 모두 64KB로 설정하는 것이 일반적입니다.

단, 이 내용이 절대적으로 옳은 것은 아닙니다.
예를 들어 Stripe Unit Size = 128KB & Cluster Size = 32KB와 같은 조합에서 성능이 더 좋은 경우도 있습니다.

하지만 일반적인 권고를 따랐을 때, 보통은 상위의 성능이 나온다고 볼 수 있습니다.


이제 핵심은 아래 그림이 잘 설명해 주고 있습니다.


(출처 : http://msdn.microsoft.com/en-us/library/dd758814(v=SQL.100).aspx)


위 그림은 Stripe Unit Size와 Cluster Size가 모두 64KB일 때의 상황입니다.
세번째 줄은 정렬되지 않은 파티션이고, 네번째 줄은 정렬된 파티션이군요.


세번째 줄을 보시면 파티션이 64번째 섹터에서 시작합니다.
어떤 문제가 생길까요?

1개의 클러스터를 읽거나 쓸때마다 2개의 Stripe Unit에 대한 I/O가 발생합니다.

이에 비해 네번째 줄은 파티션의 offset 값이 64KB (= 128 sector)로 정렬되어 있습니다.
따라서, 1개의 클러스터를 읽을 때 오직 한번의 I/O가 발생하고 있습니다.

이게 파티션 정렬이 필요한 이유입니다.

이론 적으로는 위 그림처럼 파티션의 시작 offset 값으로 64를 지정하는게 적절해 보입니다.

하지만, 하드웨어 벤더의 권고로 Stripe Unit Size를 128KB 또는 256KB를 선택할 수도 있습니다.
그 밖에도 미처 예상하지 못한 예외가 있을 수 있는데요.


그래서 offset을 1024로 설정하는 것이 일반적인 권고입니다.
1024는 여타의 설정값이 예상 가능한 범주에서 조금 유동적이라고해도 파티션이 잘 정렬되는 값이기 때문입니다.


네번째 의문

- MS가 이런 사실을 모를리 없을텐데, 이 문제가 여전히 발생하고 있나?

엄밀히 말해 파티션의 offset이 31.5KB인 것은 Windows 2003을 포함한 이전 버전에 한합니다.
Windows 2008부터는 offset 값이 1024KB이므로, 맨 앞 1024KB가 끝나는 직후부터 파티션이 시작하도록 변경되었죠.

하지만 상황에 따라 이 기본값이 지켜지지 않는 경우도 존재하기 때문에, Windows 2008 이후의 버전을 사용한다해도 디스크 파티션의 offset 값은 명시적으로 지정해 주는 것을 권장하고 있습니다.

다섯번째 의문
- 이 작업이 정말 성능 최적화에 도움이 되는가?
- 파티션을 정렬하는 구체적인 방법은?


사실 이 주제는 예전에도 한번 포스팅한 적이 있습니다.
파티션을 정렬하는 방법에 대해서는 아래 글에 언급한 방법을 그대로 적용하시면 됩니다.

2008/07/08 - [SQL] - diskpart.exe를 사용한 파티션 오프셋 설정으로 디스크 I/O 최적화 하기

위의 글을 포스팅할 당시에는 이로 인한 성능 향상이 대략 10%정도 된다고 언급했습니다만, 이 주제로 쓰여진 글을 최근에 다시 찾아보니 그렇지 않다는 것을 알게됐습니다.

시나리오에 따라 차이가 있지만 대략 30%의 성능 향상 효과가 있는 것 같습니다.

(출처 : http://msdn.microsoft.com/en-us/library/dd758814(v=SQL.100).aspx)





마치며...
SQL Server의 디스크 구성을 잘 하느냐 못 하느냐에 따라 큰 성능 차이가 발생합니다.
디스크도 여러개 사용하고 심지어 DAS까지 붙였는데 제 성능을 내지 못한다면 정말 안타까운 일이겠죠.

SE 분들이 챙겨 주신다면 고마운 일이지만, 미리 이런 내용을 안내해 주는 것이 더 좋겠습니다. ^^