본문 바로가기

훌륭한 논문

Running TPC-C on MySQL/RDS

원제 : Running TPC-C on MySQL/RDS

번역 : Running TPC-C on MySQL/RDS

나는 최근에 MySQL에 바탕을 둔 RDS 데이터베이스를 이용한 TPC-C 벤치마크 결과를 발견했습니다. 여러분도 여기서 보면 됩니다. 이 결과는 일반적으로 MySQL 확장성과 특수하게 RDS의 확장성에 관련된 많은 질문에 대한 해결책을 주는 것 같다고 생각합니다.(공개하자면, 나는 요즘 내부적인 확장 TPC-C 벤치마크를 수행하는 ScaleBase에서 일하고 있고, 결과는 곧 발표하려 합니다.)

TPC-C

TPC-C는 표준 데이터베이스 벤치마크이며, 데이터베이스를 측정합니다. 데이터베이스 제작사는 이 테스트를 수행하는데 많은 돈을 투자하며, 어떤 데이터베이스가 더 빠르고, 확장성이 좋은지 자랑합니다.

이 테스트는 쓰기 집중 테스트(write intensive test)이며, 여러분의 응용프로그램의 데이터베이스 성향을 꼭 반영하지 않습니다. 그러나 테스트는 무거운 부하에 있는 데이터베이스로부터 무엇을 예상할 것인지에 대한 매우 중요한 통찰을 줍니다.

The Benchmark Process

먼저, 벤치마크 수단에 대한 몇 가지 이야기를 하고자 합니다.

  1. Generally - 벤치마크는 기술적인 방법론이 아니라 질서정연하게 이루어졌습니다 -  결과의 신뢰성을 올려줍니다.
  2. 벤치마크 발생 클라이언트는 Percona가 제공한 오픈소스로 구현된 tpcc-mysql 입니다.Apache가 제공하는 DBT-2가 더 넓게 사용되지만, 좋은 구현입니다. 
  3. 벤치마크에서 다른 TPC-C 트랜잭션의 가중치 혼합을 빠뜨렸습니다. TPC-C 벤치마크는 6 종류의 트랜잭션이 있으며 (“new order”, “delivery”, “stock query”, etc.) 가중치 혼합은 중요합니다.
  4. 벤치마크는 지연이 아니라 처리량(throughput)에 관심을 둡니다. TPC-C가 대부분 처리량에 대한 것이지만 또한 지연을 다루는 것을 추천합니다.
  5. TPC-C "웨어하우스 개수"가 테스트할 데이터베이스 크기를 결정합니다. 이 벤치마크에서 웨어하우스 개수는  1~32  입니다. MB로 보자면 100MB~3GB입니다. 이 정도는 통상 작은 데이터베이스이고, 1000 웨어하우스(약 100GB)또는 그 이상일 때  벤치마크가 어떻게 나올지 관심이 있습니다.
  6. small 부터 quadruple Extra Large (4XL)까지 전체 범위 RDS 인스턴스를 실험했습니다.매우 흥미로운 결과가 나왔고, 이 블로그에서 집중으로 다루도록 하겠습니다.

Results Analysis

벤치마크 결과는 놀랐습니다.

  1. 데이터베이스 크기라고, MySQL 64 동시 사용자 근처에서 최적의 처리량에 도달했습니다. 이 수치보다 높을 때는 처리량 감소가 발생했습니다.
  2. 장비가 좋아질수록 처리량은 개선되었습니다. 하드웨어 추가가 성능에 도움이 안되는 지점, sweet-spot이 존재합니다. sweet-spot은 7000tpm 정도의 처리량에 도달하는 XL 부근입니다. 2XL과 4XL 장비는 이 한계를 넘어서지 못합니다.

Scale-Up 확장 접근법은 한계와 경계가 있다고 보여집니다. 불행히, 일부는 밀접한 경계가 있습니다.

자, 병목은 어디입니까?

  • CPU 는 예상 밖의 후보인데, CPU 능력은 2XL에서 두배, 4XL에서 4배입니다.
  • I/O 또한 예상 밖의 후보입니다. 장비의 메모리(RAM)이 2XML에서 두배, 4XL에서 4배입니다. 더 많은 RAM은 I/O를 감소시키는 더 많은 데이터베이스 캐시 버퍼를 의미하지 않습니다.
  • 동시성? 동시 사용자수?  최적의 처리량이 데이터베이스의 동시 세션 64개 부근에서 성취된 것을 보았습니다. 벤치마크 보고서의 그림 4b를 보세요. 1사용자가 사용자당 1,000 트랜잭션 처리량이지만, 256 사용자는 사용자당 1 트랜잭션으로 떨어집니다!

Results Explanation

더 많은 병렬 사용자가 추가되면, 성능 감소현상이 발생하다는 것은 확실합니다 - 적은 병렬 사용자가 한명일 때보다 더 적은 처리량을 보입니다.

자, 병목은 데이터베이스 서버 자체입니다. 데이터베이스는 복잡한 정교한 장비입니다. 동작할 때 매 밀리초마다 수행할 수톤의 작업을 가집니다. 쿼리마다, 데이터베이스는 분석, 최적화, 실행 계획을 찾고, 실행하고, 트랜잭션 로그, 트랜잭션 분리, 저수준 잠금을 관리합니다.

다음 예를 생각해봅시다. 간단한 업데이트 명령이 업데이트 하고, 로우를 읽고, 각 로우를 잠그는 제한된  로우를 얻기 위한 실행 계획을 필요로 합니다. 명령이 만개의 로우를 업데이트하려면 - 시간이 걸립니다. 그리고, 업데이트가 테이블, 테이블과 관련된 인덱스에서 수행되고, 트랙잭션 로그를 파일에 씁니다. 이런게 바로 단순한 업데이트입니다.

또 다른 예제 - 복잡한 쿼리는 동작에 시간이 많이 필요합니다. 단지 1초라도 매우 높은 부하의 데이터베이스에서는 많은 시간입니다. 쿼리가 실행되는 동안, 쿼리의 소스 테이블에서 가져온 로우가 업데이트됩니다(또는 추가 또는 삭제됩니다). 데이터베이스는 "분리 수준"을 유지해야 합니다 (isolation level blog을 보세요). 사용자의 결과는 쿼리가 시작될 때와 같은 쿼리의 스냅샵이어야함을 의미합니다. 쿼리가 시작된 후에 업데이트된 로우의 새로운 값은, 커밋되었다 해도, 결과의 부분일 수 없습니다. 그보다는, 데이터베이스는 로우의 "이전 스냅샵"을 찾아야 하고, 로우가 쿼리가 시작할 때를 찾아야 함을 의미합니다. InnoDB는 테이블스테이스에 로우의 전 버전에 대한 정보를 저장합니다. 이 정보는 롤백 세그먼트라 부르는 데이터 구조에 저장됩니다. 앞 예제로 돌아가면 - 데이터베이스가 해야 하는 또 다른 작업이 있는데 - 롤백 세그멘트 갱신입니다.

데이터베이스에 하달한 모든 명령어는, 실제로 데이터베이스 엔진안에서 십여개의 재귀 명령어를 발생시킨다는 것을 기억해야 합니다. 세션이나 사용자 동접이 올라가면, 데이터베이스 안쪽의 부하는 지수적으로 올라갑니다. 데이터베이스는 멋진 장비지만, 자체 한계가 있습니다.

So What Do We Do?

자, 우리는 데이터베이스가 크라우드되고, Scale Up 해법을 복잡하게 만드는 하드웨어 sweet-spot을 가진다고 알았습니다. Scale Up은 비싸고, 요구된 성능 끝점을 제공하지 않습니다. 특수한 데이터베이스가 자체 한계를 가진다고 해도, 그리고 sweet-spot이 바뀌어도, 모든 데이터베이스는 sweet-spot을 가집니다.

이 문제에대한 가능한 해법이 많습니다 - 데이터베이스 히트를 감소시키는 캐싱 계층을 추가하거나, 데이터베이스 히트를 감소시키는 어떤 작업이라도 좋습니다(NoSQL 해법).

그러나 실제 데이터베이스 솔루션은 scale-out 입니다. 하나의 데이터베이스 엔진을 대신해서, 여러개를 가지는데, 10개라 합시다. 128 동접자 또는 256 동접자 대신에(TPC-C 벤치마크에서 최악의 결과였던), 10개의 데이터베이스에 26 사용자를 배치하고, 데이터베이스마다 64 사용자까지 도달가능합니다(640 동시 사용자가 가능합니다). 물론, 필요하다면, 증가한 규모를 다루기 위해 더 많은 데이터베이스를 추가할 수 있습니다.

scale out 솔루션이 데이터베이스를 위해 TPC-C를 다루는 방법은 매우 재밌습니다.