디스크 읽기 방식
디스크 읽기 방식
컴퓨터의 CPU나 메모리처럼 전기적 특성을 띤 장치의 성능은 짧은 시간 동안 매우 빠른 속도로 발전했지만 디스크 같은 기계식 장치의 성능은 상당히 제한적으로 발전했다. 비록 최근에는 자기 디스크 원판에 의존하는 하드 디스크 보다 SSD 드라이브가 많이 활용되고 있지만, 여전히 데이터 저장 매체는 컴퓨터에서 가장 느린 부분이라는 사실에는 변함이 없다. 데이터베이스나 쿼리 튜닝에 어느 정도 지식을 갖춘 사용자가 절감하고 있듯이 데이터베이스의 성능 튜닝은 어떻게 디스크 I/O를 줄이느냐가 관건일때가 상당히 많다.
하드디스크(HDD), 솔리스 스테이트 드라이브(SSD)
컴퓨터에서 CPU나 메모리 같은 주요 장치는 대부분 전자식 장치지만 하드디스크 드라이브는 기계식 장치다. 그래서 데이터베이스 서버에서는 항상 디스크 장치가 병목이 된다. 이러한 기계식 하드 디스크 드라이브를 대체하기 위해 전자식 저장매체인 SSD(Solid State Drive)가 많이 출시되고 있다. SSD도 기존 하드 디스크 드라이브와 같은 인터페이스(SATA나 SAS)를 지원하므로 내장 디스크나 DAS또는 SAN에 그대로 사용할 수 있다.
직접 연결 저장장치(Direct-attached storage : DAS)란 서버 또는 컴퓨터에 네트워크를 거치지 않고 직접 연결되는 저장장치를 말하는 것으로, 스토리지 에어리어 네트워크 또는 네트워크 결합 스토리지 와 상반되는 네트워크에 연결되지 않은 저장장치를 나타내기 위해 사용된다.
SSD는 기존 하드 디스크 드라이브에서 데이터 저장용 플래터(원판)를 제거하고 그 대신 플래시 메모리를 장착하고 있다. 그래서 디스크 원판을 기계적으로 회전시킬 필요가 없으므로 아주 빨리 데이터를 읽고 쓸 수 있다. 플래시 메모리는 전원이 공급되지 않아도 데이터가 삭제되지 않느다. 그리고 컴퓨터의 메모리(D-Ram)보다는 느리지만 기계식 하드 디스크 드라이브보다는 훨씬 빠르다.
컴퓨터의 주요 부품별 처리 속도를 보여준다. Y축의 “Operations / second”란 초당 처리 가능한 연산의 횟수를 의미하므로 이 값이 클수록 처리 속도가 빠르다는 것을 의미한다. 메모리와 디스크의 처리 속도는 10만배 이상의 차이를 보인다. SSD는 1000배 가량의 차이를 보인다. 시중에 판매되는 SSD는 대부분 기존 하드 디스크 드라이브보다는 용량이 적으며 가격도 비싼 편이지만 예전보다는 SSD가 훨씬 더 대중화된 상태이며 요즘은 DBMS용으로 사용할 서버에는 대부분 SSD를 채택하고 있다.
디스크의 헤더를 움직이지 않고 한 번에 많은 데이터를 읽는 순차 I/O에서는 SSD가 하드 디스크 드라이브보다 조금 빠르거나 거의 비슷한 성능을 보이기도 한다. 하지만 SSD의 장점은 기존 하드 디스크 드라이브보다 랜덤 I/O가 훨씬 빠르다. 데이터베이스 서버에서 순차 I/O 작업은 그다지 비중이 크지 않고 랜덤 I/O를 통해 작은 데이터를 읽고 쓰는 작업이 대부분이므로 SSD의 장점은 DBMS용 스토리지에 최적이라고 볼 수 있다. SSD와 하드 디스크 드라이브에서 랜덤 I/O의 성능을 벤치마크한 것이다. 트랜잭션의 내용별로 수치는 많이 달라질 수 있다.
SSD는 초당 436개의 트랜잭션을 처리했지만 하드 디스크 드라이브는 초당 60개의 트랜잭션밖에 처리하지 못했다. OLTP 환경의 데이터베이스에서는 SSD가 하드 디스크 드라이브보다는 훨씬 빠르다.
랜덤 I/O와 순차 I/O
랜덤 I/O라는 표현은 하드 디스크 드라이브의 플래터(원판)을 돌려서 읽어야 할 데이터가 저장된 위치로 디스크 헤더를 이동시킨 다음 데이터를 읽는 것을 의미하는데, 사실 순차 I/O 또한 이 작업 과정은 같다.
순차 I/O는 3개의 페이지(3 * 16KB)를 디스크에 기록하기 위해 1번 시스템 콜을 요청했지만, 랜덤 I/O는 3개의 페이지를 디스크에 기록하기 위해 3번 시스템 콜을 요청했다. 즉, 디스크에 기록해야 할 위치를 찾기 위해 순차 I/O는 디스크의 헤드를 1번 움직였고, 랜덤 I/O는 디스크 헤드를 3번 움직였다. 디스크에 데이터를 쓰고 읽는 데 걸리는 시간은 디스크 헤더를 움직여서 읽고 쓸 위치로 옮기는 단계에서 결정된다. 결국 순차 I/O는 랜덤 I/O보다 거의 3배 정도 빠르다고 볼 수 있다. 즉 디스크의 성능은 디스크 헤더의 위치 이동 없이 얼마나 많은 데이터를 한 번에 기록하느냐에 의해 결정 된다고 볼 수 있다. 그래서 여러 번 쓰기 또는 읽기를 요청하는 랜덤 I/O 작업이 작업 부하가 훨씬 더 크다. 데이터베이스 대부분의 작업은 이러한 작은 데이터를 빈번히 읽고 쓰기 때문에 MySQL 서버에는 그룹 커밋이나 바이너리 로그 버퍼 또는 InnoDB 로그 버퍼 등의 기능이 내장돼 있다.
디스크 원판을 가지지 않는 SSD는 랜덤 I/O와 순차 I/O의 차이가 없을 것으로 예측하지만, 실제로는 그렇지 않다. SSD 드라이브에서도 랜덤 I/O는 여전히 순차 I/O보다 전체 스루풋(Throughput)이 떨어진다. 그래서 SSD 드라이브의 사양에도 항상 순차 I/O와 랜덤 I/O의 성능 비교를 구분해서 명시한다.
랜덤 I/O나 순차 I/O 모두 파일에 쓰기를 실행하면 반드시 동기화(fsync 또는 flush 작업)가 필요하다. 그런데 순차 I/O인 경우에도 이러한 파일 동기화 작업이 빈번히 발생한다면 랜덤 I/O와 같이 비효율적인 형태로 처리될 때가 많다. 기업용으로 사용하는 데이터베이스 서버에는 캐시 메모리가 장착된 RAID 컨트롤러가 일반적으로 사용되는데, RAID 컨트롤러의 캐시 메모리는 아주 빈번한 파일 동기화 작업이 호출되는 순차 I/O를 효율적으로 처리될 수 있게 변환하는 역할을 한다. 하드 디스크 드라이브뿐만 아니라 SSD를 사용하는 경우에도 여전히 RAID 컨트롤러는 중요한 역할을 하기 때문에 RAID 컨트롤러와 RAID 컨트롤러에 장착된 캐시의 성능을 무시하지 말자.
사실 쿼리를 튜닝해서 랜덤 I/O를 순차 I/O로 바꿔서 실행할 방법은 그다지 많지 않다. 일반적으로 쿼리를 튜닝하는 것은 랜덤 I/O 자체를 줄여주는 것이 목적이라고 할 수 있다. 여기서 랜덤 I/O를 줄인다는 것은 쿼리를 처리하는 데 곡 필요한 데이터만 읽도록 쿼리를 개선하는 것을 의미한다.
인덱스 레인지 스캔은 데이터를 읽기 위해 주로 랜덤 I/O를 사용하며, 풀 테이블 스캔은 순차 I/O를 사용한다. 그래서 큰 테이블의 레코드 대부분을 읽는 작업에서는 인덱스를 사용하지 않고 풀 테이블 스캔을 사용하도록 유도할 때도 있다. 이는 순차 I/O가 랜덤 I/O보다 훨씬 빨리 많은 레코드를 읽어올 수 있기 때문인데, 이런 형태는 OLTP 성격의 웹 서비스보다는 데이터 웨어하우스나 통계 작업에서 자주 사용된다.