이해하기 어려운 단어와 약자들을 정리했습니다.
IO Bound
: 계산을 완료하는 데 걸리는 시간이 입출력 작업 시간에 의해 결정되는 조건을 말한다.
Rotation penalty
: 하드 디스크가 회전할 수 있는 RPM이 높을 수록 비트 전송률이 높아지기 때문에 디스크에서 더 빨리 읽고 쓸 수 있다. 회전에 페널티가 생긴다는 건 부하로 인해 읽고 쓰는 성능이 떨어지는 걸 의미한다.
OLTP
: Online transaction proccessing
의 약자로 트랜잭션을 지원하는 소프트웨어를 의미합니다.
OLTP_RO
: Online transaction proccessing_Read Only
입니다.
OLTP_RW
: Online transaction proccessing_Read and Wirte
입니다.
Update-NoKEY
: 인덱싱된 열을 변경하지 않았다라고 볼 수 있습니다.
어떤 서비스를 개발하든 초기에는 범용 DBMS를 선택하게 될 것이고, 사용량이나 데이터가 커지면 전용 DBMS를 선택해 확장해야 합니다. 그렇기 때문에 어떤 서비스를 개발하더라고 DBMS를 선택해야 하는 위치에 놓이게 됩니다.
어떤 DB를 사용해야 할지 모를 때, 가상 우선적으로 고려할 부분은 자신이 가장 잘 활용할 수 있는 DBMS를 선택
하는 것이 중요하지만, 그럼에도 고민이 된다면 다음과 같은 사항을 고려할 수 있습니다.
쉽게 확인할 수 있는건 커뮤니티 인지도인데, 안정성과 성능이 보장될 수록 인지도가 높아지고 언급이 많이 되기 때문에 고려 사항 중 하나라고 볼 수 있습니다.
MySQL의 인지도가 상위권에 위치하는 만큼 어느 정도의 안정성과 성능이 보장된다고 볼 수 있고 커뮤니티 에디션인 경우 오픈 소스이므로 범용 DBMS로 선택이 비용을 줄이는 방법으로 진행할 수 있습니다.
사용해야 할 DB 선정 기준은 자신이 가장 잘 활용할 수 있는 DBMS를 선택
이었습니다. 좋은 성능을 유지하고 이슈 상황에 대처하기 위해서 MySQL에 익숙해질 필요가 있고, 버전마다 어떤 성능 차이가 발생하는 지 확인할 필요가 있습니다.
MySQL이 오라클에 인수되면서 5.5 버전에서 5.7 버전까지는 안정성과 성능 개선에 집중했으며, 8.0 버전에서는 상용 DBMS가 가지는 기술이 추가 됐습니다. 그 중 어떤 버전을 선택할 지 기준을 선정했습니다.
MySQL에서 안정성과 성능이 높아지는 버전은 크게 5.6, 5.7, 8.0 버전입니다. 세 버전의 성능 차이를 비교해 어떤 버전을 선택하는 게 가장 좋을 지 고려했습니다.
MySQL 8.0 버전에 들어서면서 IO Bound에 의한 처리량 제한을 개선했습니다.
개선되는 하드웨어
랜덤으로 읽는 상황에서는 미리 캐시하거나 프리 패치할 수 없기 때문에 HDD rotation penalty
를 가하고 있습니다. 지금은 플래시 스토리지 덕에 이 문제를 어느정도 해결할 수 있습니다.
압축과 페이지 분할
참고 : MySQL Benchmarks
제한 삭제
압축과 분할을 활용한 방식은 InnoDB의 모든 IO 작업이 global lock (fil_system mutex)
로 인해 IO 속도가 제한되기 때문에 부분적으로 사용할 수 있었지만, MySQL 8.0 이후 제한이 사라졌습니다.
즉, 8.0 버전에서는 압축과 분할을 통해 4 배 더 많이 읽고, 4 배 더 많이 처리할 수 있는 방식을 고안해 QPS를 획기적으로 개선할 수 있습니다.
OLTP_RW
/Update-NoKEY
글은 OLTP_RW
과 Update-NoKEY
를 기준으로 성능을 측정하고 있습니다. 즉, 트랜잭션이 발생하는 상황에서 키를 건들지 않고 테스트를 해보겠다라는 의미입니다. OLTP_RO
와 비교하면 좋을 것 같아 OLTP_RO
성능 비교 표도 가져왔습니다.
OLTP_RO
성능 비교
결론은 5.6 버전이 아닌 경우 성능이 보장된다는 점입니다.
TPS 비교표를 봤을 때, 5.6 버전을 사용한다면 5.7 버전으로 업그레이드를 고려할 필요가 있습니다.
OLTP_RO
성능 비교에서는OLTP_RO
에서는 큰 성능 차이는 발생하지 않지만, 5.7 버전과 8.0 버전의 차이는OLTP_RW
에서 발생합니다.
OLTP_RW
성능 비교
이곳에서 테스트 단위는 OLTP_RO 쿼리 + 2 * UPDATE 쿼리 + DELETE 쿼리 + INSERT쿼리
로 진행합니다.
TPS 비교표를 봤을 때, 8.0 버전이 우월한 성능을 보여주고 있습니다. 번외로 5.7 버전이 5.6 버전보다 낮은 성능을 보여주고 있습니다. (MariaDB는 5.7 버전의 InnoDB를 채택했기 때문에 5.7 버전과 비슷한 성능을 보여주고 있습니다.)
즉,
OLTP_RW
/Update-NoKEY
상황에서 8.0 버전과 5.7 버전 처리량 차이는 최대 5배 차이가 발생합니다.
이중 쓰기 버퍼(Double Write Buffer, DBLWR
)는 쓰기 페이지가 데이터 파일의 적절한 위치에 페이지를 쓰기 전, 버퍼 풀에 플러시되는 저장 영역을 의미합니다.
디스크 파일로 플러시 할 때 일부만 기록되는 문제가 발생하면 페이지 내용을 복구할 수 없는데,
DBLWR
를 활용해 데이터 무결성을 보장합니다.
DBLWR
은 데이터 무결성을 보장하는 방식이기 때문에 동시성 처리 상황에서는 좋지 않은 성능을 보였지만, MySQL-8.0.20 릴리즈에서 업데이트됐습니다. 그렇기 때문에 부하 테스트를 통해 8.0.19와 8.0.20 버전의 성능 차이가 비교됩니다.
IO 바인딩이 되지 않는 경우
IO 바인딩이 발생하지 않는 경우 동일한 성능을 보장합니다. 즉, 페이지의 플러시가 REDO 쓰기를 따라갈 수 있을 만큼 빠르게 진행되면 안전합니다.
IO 바인딩이 발생하는 경우
페이지 쓰기가 지연되면 IO 바인딩이 되고, DBLWR
의 경우 IO 바인딩이 되는 상황에서 성능 효과를 발휘합니다.
이러한 결과 차이가 발생한 이유는 이전 버전의 DBLWR
디자인이 높은 동시성을 위해 만들어지지 않았기 때문입니다. 결과적으로 메모리에 크기에 따라 TPS 영향을 받게 되지만, 8.0.20에서 개선된 DBLWR
를 활용해 성능 저하를 막을 수 있습니다.
IO Bound
상황에서 QPS(Query per sec)
를 개선했다.OLTP_RO
인 상황에서 TPS(Transaction per sec)
는 5.7에서 개선됐다.OLTP_RW
/Update-NoKEY
상황에서 TPS(Transaction per sec)
를 개선했다.DBLWR
가 개선되면서 IO Bound
상황에서 CPS(Commit per sec)
를 개선했다.IO Bound
상황에서 발생하는 성능 저하 문제를 개선했습니다.