Relevance Framing 🧩
목적
: 쿼리튜닝의 목표를 이해하기 위해서
쿼리와 Disk I/O와의 관계
쿼리를 사용하면 필연적으로 디스크 I/O 작업을 거쳐야 한다.
해당 Disk I/O 작업은 다시 랜덤 I/O와 순차 I/O로 나뉘는데, 이는 디스크에 접근을 몇 번 하느냐에 따라 종류가 나뉜다.
쿼리튜닝은,
기존 쿼리와 동일한 데이터를 더 빠른 시간안에 사용자에게 전달할 수 있도록 쿼리를 개선하는 작업을 말한다.
디스크에 접근하는 횟수가 적을수록 속도가 개선됨은 당연한 이야기 이므로,
**쿼리 튜닝의 목표는 최대한 Disk I/O를 적게 하는 것에 있다.
0. 전제 상황
디스크 I/O에 대한 개념을 명확히 이해하기 위해, OS 페이지 캐시와 InnoDB 버퍼 풀에 찾으려는 데이터가 100% 없는 상황이라고 가정하고 밑의 설명을 이어간다.
1. 개념 설명
(0) 디스크 I/O란?
원하는 곳에 데이터를 쓰거나 혹은 특정 위치의 데이터를 읽어오기 위해 디스크에 접근하는 행위를 말한다.
(1). 순차 I/O
: 디스크 내의 물리적으로 연속된 데이터들을 한 번의 디스크 I/O로 모조리 읽어오는 접근 방식
(2). 랜덤 I/O
: 디스크 내의 산재된 데이터들을 모두 읽기 위해 여러번의 디스크 I/O를 행하는 접근 방식
2. 서버는 이 둘을 어떻게 구분하여 명령을 내릴까?
결론
: InnoDB가 OS 시스템 콜 호출을 몇 번 하느냐에 따라서 둘은 구분된다.
밑은 pread()
라는 시스템콜 호출 함수이다.
pread(fd, buf, total_size, offset);
각 인자의 의미는 다음과 같다.
매개변수 | 설명 |
---|---|
fd |
디스크의 파일 디스크립터 (파일 디스크립터: 운영체제가 파일을 식별하기 위해 사용하는 번호) |
buffer |
읽어들인 데이터를 저장할 사용자 메모리 주소 |
160 * 1024 |
읽고자 하는 바이트 수 = 여기선 160KB |
offset_for_page_100 |
파일 내 읽기를 시작할 바이트 위치 (오프셋) = 페이지 100의 시작 위치 |
함수에서 알 수 있듯이, 순차 I/O
는 pread()를 한 번만 부르면 된다. 단지 읽고 싶은 양에 따라 3번째 인자인 바이트 수를 조절하면 될 뿐이다.
반면, 랜덤 I/O
는 구조상 해당 함수를 한 번만 이용할 수 없다. 따라서 해당 함수를 여러 번 불러야 한다.
(1) 예제
A. 순차 I/O
먼저 순차 I/O의 경우 예를 들어보자. 상황은 다음과 같다.
- 한 페이지의 크기: 16KB
- 조회 페이지 번호: 100번부터 109번까지 (총 10 Page = 160KB)위의 명령어 한 번이면 모두 읽을 수 있다. 3번째 인자에 16의 10배를 입력해 한 번에 10페이지를 읽는 것을 볼 수 있다.
pread(fd, buffer, 160 * 1024, offset_for_page_100);
B. 랜덤 I/O
랜덤 I/O를 볼까?
- 한 페이지의 크기: 16KB
- 조회 페이지 번호: 100, 117, 203, 350한 페이지씩 4번 읽어야 한다.
pread(fd, buffer1, 16 * 1024, offset_for_page_100); pread(fd, buffer2, 16 * 1024, offset_for_page_117); pread(fd, buffer3, 16 * 1024, offset_for_page_203); pread(fd, buffer4, 16 * 1024, offset_for_page_350);
3. 랜덤 I/O와 순차 I/O의 속도 차이
위에서 살펴보았듯이 당연히 순차 I/O 쪽이 더 빠르다.
이를 HDD의 관점과 SSD의 관점에서 알아보려고 한다.
(1) HDD 관점에서
결론
: SEEK TIME과 Rotational Latency의 횟수 차이
순차 I/O의 경우, 플래터 내의 데이터가 존재하는 트랙 찾기 (Seek Time) 과 트랙 내부에 데이터를 읽을 시작점인 Sector 찾는 것을 최초 한 번만 하면 된다.
반면, 랜덤 I/O의 경우 위와 같이 Pread()
한 번 당 SeekTime과 Rotational Latency가 매 번 존재한다. 따라서 순차 I/O와 비교하면 월등히 느릴 수 밖에 없다.
(2) SSD의 관점에서
결론
: 순차 I/O는 골고루 병렬 읽기가 가능하지만, 랜덤 I/O는 균일한 병렬 읽기를 장담하지 못한다.
A. SSD의 병렬읽기란?
SSD에서의 병렬 읽기란, SSD 컨트롤러가 다수의 채널에서 병렬적으로 데이터를 읽어오는 것을 말한다.
이것의 성립을 위해서는 NAND 메모리가 메모리 인터리빙 형식으로 데이터를 저장하고 있다는 것이 전제되어야 한다.
B. 메모리 인터리빙이란?
데이터를 여러 메모리 뱅크에 분산 저장 시켜서 병렬적인 데이터 접근을 가능하게 하는 데이터 저장 전략이다. 여기서 메모리 뱅크란 _논리적인 데이터 저장소_를 뜻한다.
NAND에서 뱅크란 개념을 대체할 수 있는 언어로는 Package
가 있다. 때때로 Die
라는 단위 또한 뱅크를 지칭할 수 있기도 하다.
잠시, 다시 SSD의 NAND 메모리의 구조를 알아보자.
- 논리적 구성요소
- Channel: 컨트롤러와 Package 사이를 잇는 통신선
- Package: 데이터를 나누는 가장 큰 단위
- Die: 패키지 내의 데이터 영역을 나누는 단위
- Plaine: Die 내부를 나누는 단위
- Block: 여러 페이지들의 집합 (보통 128 ~ 512 Page로 이루어져 있다. HDD의 Track에 해당)
- Page: 가장 작은 읽기/쓰기 단위 (보통 4KB, HDD의 섹터에 해당)
├── Channel (채널) ← 병렬 데이터 통신 라인
│ ├── Package (NAND 패키지)
│ │ ├── Die (다이) ← 실제 실리콘 칩. 독립 동작 가능
│ │ │ ├── Plane (평면) ← 병렬 액세스 가능한 하위 단위
│ │ │ │ ├── Block ← 지우기 단위 (128~512 Page)
│ │ │ │ │ └── Page ← 읽기/쓰기 단위 (보통 4KB)
메모리 인터리빙을 구현하는 방식은 많지만, 필자는 자주 쓰이는 저차원 인터리빙(Low-Order Interleaving)
을 예시로 설명하겠다.
저차원 인터리빙은 메모리 주소의 하위 비트를 활용해 데이터의 저장 위치를 설정하는 방식이다.
다음은 4-way 인터리빙 전략이라는 저차원 인터리빙의 세부 방법 중 하나로 데이터를 분산 저장한 예시이다.
메모리 주소 0: 0b00 -> 뱅크 0
메모리 주소 1: 0b01 -> 뱅크 1
메모리 주소 2: 0b10 -> 뱅크 2
메모리 주소 3: 0b11 -> 뱅크 3
메모리 주소 4: 0b00 -> 뱅크 0
메모리 주소 5: 0b01 -> 뱅크 1
(계속 반복)
이런 식으로 저장하면, 연속적인 데이터들이 각각 다른 뱅크에 저장되어 데이터가 균일하게 분산된다.
(고차원 인터리빙이라는 것 또한 있으나, 이는 특정 메모리 접근 패턴을 위한 것이라 복잡한 하드웨어 설계를 요한다. 나는 소프트웨어 엔지니어임으로 이까지만 다루겠다 ㅎ)
C. 다시 병렬 읽기로 돌아와서…
이제 메모리 인터리빙이란 저장 전략에 대해서 알았으니, 다시 병렬읽기로 돌아와보자. SSD 컨트롤러 내부는 채널 컨트롤 유닛이라는 복수의 스레드로 이루어진 멀티 스레딩 구조이다.
이제 해당 스레드들이 채널에 병렬로 읽기를 요청한다.
이는 위의 전개도에서 데이터를 읽는 경우만 따로 떼어내서 보여주는 사진이다.
인터리빙을 한 경우는 채널 컨트롤 유닛이라는 각개의 스레드가 데이터를 병렬로 읽으면서 더 빨라진다.
D. SSD 내부 구조가 위와 같을 때, 순차 I/O와 랜덤 I/O를 다시 보자.
이제 메모리 인터리빙을 마치고 병렬 읽기가 가능한 상태에서, 순차 I/O와 병렬 I/O 중 뭐가 더 유리할 지 생각해보자.
순차 I/O의 경우, 균일한 병렬 읽기가 일어날 것임이 예상된다. 왜냐하면 순차 I/O는 데이터를 읽는 범위가 연속적이기 때문에, 처음 분산했던 채널마다 균일한 데이터를 읽어오기만 하면 될 뿐이기 때문이다.
반면, 랜덤 I/O의 경우, 병렬읽기가 일어날 것임을 장담하지 못한다. 사용자가 원하는 데이터가 channel 1에만 있을 수도 있기 때문이다. 따라서 랜덤 I/O가 순차 I/O보다 느릴 가능성이 높다.
4. 소결
따라서 랜덤 I/O는 순차 I/O보다 다음과 같은 이유로 느릴 가능성이 다분하다.
- DB 서버 단에서 시스템 콜 호출이 더 많이 일어남.
- HDD의 경우, 랜덤 I/O가 순차 I/O 보다 물리적 움직임이 훨씬 많음
- SSD의 경우, 랜덤 I/O는 SSD의 최대 장점인 병렬 읽기를 활용하지 못할 가능성이 있음.
모르는 단어 정리 to Layman's term 𓂃🖊
없음
참고 문서
메모리 인터리빙이 무엇일까?
마흔 여덟 번째 키워드인 '메모리 인터리빙'을 알아봅시다!
velog.io
메모리 인터리빙(Memory Interleaving)
문제 11) 메모리 인터리빙(Memory Interleaving) 답) 병렬 메모리 접근, 메모리 인터리빙(Memory Inter...
blog.naver.com