HDD와 SSD
CPU의 처리 속도와 RAM과 같은 전기적인 원리로 동작하는 메모리의 I/O 속도는 지속적으로 빠르게 발전해왔다. 반면, 디스크와 같은 기계적 장치는 CPU나 RAM에 비해 발전 속도가 상대적으로 제한적이었다. 특히 HDD는 마치 LP판과 유사한 원리로 동작한다. 디스크 헤드가 특정 위치로 이동해 플래터(원판)를 회전시키며 데이터를 읽거나 쓰는 방식으로 작동하기 때문에 속도가 느릴 수밖에 없다. 이를 보완하기 위해 플래시 메모리를 활용한 SSD가 등장했으며, SSD는 HDD에 비해 훨씬 빠른 속도를 제공한다.
컴퓨터 컴포넌트별 IOPS 비교
HDD와 메모리 간의 I/O 속도 차이는 약 10만 배에 달한다. 반면, SSD는 플래시 메모리를 사용하여 메모리와의 속도 차이를 약 1,000배 수준으로 줄였다. 특히 순차 I/O의 경우 SSD는 HDD보다 약간 빠른 수준이지만, 랜덤 I/O에서는 SSD가 HDD에 비해 월등히 우수하다. 이는 대부분의 DBMS I/O가 랜덤 I/O로 발생하기 때문에 중요하다.
책 Real MySQL 8.0에 따르면, HDD와 SSD를 비교했을 때 초당 트랜잭션 처리 성능은 SSD가 HDD 대비 약 7배 높은 성능을 보인다. 이러한 이유로 최근 DBMS 서버는 대부분 SSD를 채택하고 있다.
DBMS에서 SSD와 HDD의 성능 차이가 설계 및 운영에 미치는 영향
SSD의 도입은 데이터베이스 설계 및 운영 방식에 큰 변화를 가져왔다. 과거 HDD 기반 환경에서는 디스크 I/O의 높은 지연 시간 때문에 디스크 접근을 최소화하는 설계가 필수적이었다. 이를 위해 인덱스 최적화, 데이터 압축, 파티셔닝 등 다양한 기법이 활용되었다. 반면 SSD는 훨씬 빠른 I/O 성능을 제공하므로, 일부 설계 요소를 단순화하거나, 데이터 중복을 허용하여 읽기 성능을 극대화하는 전략이 가능하다.
또한 SSD는 랜덤 I/O 성능이 뛰어나므로, 데이터 분산 및 샤딩 전략에서 물리적 연속성을 고려할 필요가 적어졌다. 하지만 SSD도 무한한 성능을 제공하는 것은 아니며, 특히 쓰기 성능 저하와 셀 마모 문제가 있기 때문에 로그 쓰기 또는 캐싱 전략을 통해 SSD 수명을 최적화해야 한다.
랜덤 I/O와 순차 I/O
랜덤 I/O는 읽어야 할 데이터가 물리적으로 불연속적인 위치에 있을 때 발생하며, 디스크 헤더를 여러 번 이동시키면서 데이터를 읽는다. 이 과정에서 디스크 헤더의 이동 시간, 즉 Seek Time이 성능에 큰 영향을 미친다. 반면, 순차 I/O는 데이터가 물리적으로 연속적으로 저장된 경우에 발생하며, 디스크 헤더를 이동시키지 않고 데이터를 읽을 수 있다. 따라서 디스크의 성능은 순차적으로 데이터를 저장하고 읽는 능력에 크게 좌우된다.
SSD는 디스크 원판이 없기 때문에 랜덤 I/O와 순차 I/O 간의 성능 차이가 적을 것처럼 보이지만, SSD에서도 랜덤 I/O는 순차 I/O에 비해 처리율(throughput)이 떨어지는 경향이 있다.
SSD 내부에서 랜덤 I/O 성능이 순차 I/O보다 떨어지는 이유
SSD 내부 구조는 플래시 메모리 셀로 구성되어 있으며, 데이터는 페이지 단위로 읽고 블록 단위로 쓰인다. 랜덤 I/O가 순차 I/O보다 느린 이유는 크게 두 가지로 나뉜다. 첫째, SSD의 내부 컨트롤러는 데이터의 위치를 추적하기 위해 논리적 블록 주소(LBA)와 실제 물리적 주소를 매핑하는 작업을 수행해야 한다. 랜덤 I/O가 많아질수록 이 매핑 테이블의 참조와 갱신 빈도가 증가하면서 컨트롤러의 부하가 커진다.
둘째, SSD는 데이터 쓰기 시 기존 데이터를 직접 덮어쓰지 못하고, 새로운 블록에 데이터를 기록한 뒤 가비지 컬렉션(Garbage Collection)을 통해 이전 블록을 정리하는 방식으로 동작한다. 랜덤 I/O가 많을수록 이 과정에서 비효율이 발생하며, 특히 여러 블록에 분산된 데이터를 처리할 경우 병목현상이 심화된다.
DBMS에서 I/O 최적화의 중요성
DBMS는 디스크에 데이터를 빈번히 읽고 쓰는 작업을 수행하기 때문에, MySQL 서버는 그룹 커밋, 바이너리 로그, InnoDB 로그 버퍼 등 다양한 최적화 기능을 내장하고 있다. 쿼리를 튜닝한다고 해서 랜덤 I/O가 순차 I/O로 변하는 일은 흔하지 않다. 따라서 쿼리 튜닝의 목적은 랜덤 I/O를 줄이고 꼭 필요한 데이터만 읽도록 개선하는 데 있다.
인덱스 레인지 스캔은 주로 랜덤 I/O를 사용하고, 풀 테이블 스캔은 순차 I/O를 사용한다. 큰 테이블에서 많은 데이터를 읽어야 할 경우, 옵티마이저가 인덱스 사용 대신 풀 테이블 스캔을 유도하는 전략을 선택할 수도 있다. 이러한 상황에서는 쿼리 성능 최적화를 통해 불필요한 랜덤 I/O를 줄이는 것이 중요하다.