본문 바로가기
SingleStoreDB/엔지니어링

[SingleStore 성능 테스트] MySQL 대비 데이터 로딩 34배, 분석 쿼리 수행 약 370배 이상 성능 극대화

by 에이플랫폼 [Team SingleStore Korea] 2020. 6. 18.

서론

IoT 및 CRM 영역에서 다양한 비즈니스 분석 솔루션을 제공하는 국내 모 기업에서는 MySQL과 Oracle를 사용하여 고객에게 분석 리포트를 제공해 왔습니다. 그러나 많은 고객들이 클라우드와 온프라미스 모든 환경에서 대량의 데이터를 수용하고 이를 실시간으로 분석을 하여 비즈니스에 통찰력을 제공하는데 어려움이 있었습니다. 이로 인해 클라우드 환경에서 대량의 데이터를 실시간으로 로딩하고, 분석 성능을 크게 향상 시켜야 하는 도전 과제로 주어졌습니다. 기존 MySQL 및 Oracle의 대안으로 클라우드 네이티브 DBMS인 SingleStore를 대안 솔루션으로 테스트를 진행하였습니다. 동일한 테스트 환경과 시나리오를 적용하여 어떻게 테스트를 진행했는지 설명을 드리고자 합니다. 또한, SingleStore의 Rowstore 테이블을 사용하여 메모리에 데이터를 저장 및 처리하여 성능을 극대화한 테스트 케이스도 추가로 보여드리고자 합니다.

 


테스트 시나리오

테스트를 위한 MySQL 스키마 및 분석 퀴리문은 다음과 같습니다. 분석 쿼리문은 4개 테이블에 대해 2개의 조인컬럼으로 INNER JOIN을 수행하는 쿼리입니다. 조인을 수행하는 4개 테이블 중에 두 테이블은 날짜 컬럼으로 범위 지정되어 파티션된 크기가 큰 테이블이며, 나머지 두 테이블은 비교적 크기가 작은 테이블입니다. 분석쿼리문은 동일한 단일 서버에서 MySQL과 SingleStore 에서 각각 수행되며, 첫번째 쿼리 수행(cold query)이후, 일정한 간격을 가지고 5번 수행하여 쿼리 수행시간을 측정하였습니다.

 

select ROUND(COALESCE(SUM( F00003.salary ), 0), 0) as "r0001"
, F00004.dept_name as "r0002"
, F00005.title as "r0003"
FROM employees.dept_emp F00002
Inner JOIN employees.salaries F00003 ON F00002.emp_no = F00003.emp_no
Inner JOIN employees.departments F00004 ON F00002.dept_no = F00004.dept_no
Inner JOIN employees.titles F00005 ON F00002.emp_no = F00005.emp_no
where 1 = 1
 group by F00004.dept_name
, F00005.title;

 

 

MySQL Schema

 


테스트 환경

MySQL8.0과 SingleStore 7.1의 최신버전을 사용하여 동일한 단일 서버에서 테스트를 진행했습니다. 서버 사양은 20CPU, RAM 200GB, DISK 1.5TB(SCSI)였습니다. 단일 서버에서 진행되었기 때문에 SingleStore 클러스터는 리프 노드와 어그리게이터 각 각 하나씩으로 구성되었습니다.


데이터 로드 및 성능 차 비교

테스트를 위해 데이터 로딩을 위한 작업이 선행되었습니다. MySQL과 SingleStore에 개별적으로 테이블 SALARIES는 약 3GB의 9천2백만 건의 데이터를 로드하였고, 각각의 DB에서 데이터 로딩 성능 차이를 확인하였습니다. 공정성을 위해 아래와 같은 동일한 SQL문으로 데이터를 로드하였습니다.

load data infile './salaries.tbl'
into table salaries
fields terminated by ','
lines terminated by '\n'
(emp_no, salary, from_date, to_date) ;

 

SingleStore는 테이블 저장 영역을 메모리와 디스크 2가지로 혼용 구성하여 테스트하였기 때문에 Rowstore 테이블의 로드 수행시간과 Columnstore 테이블의 로드 수행 시간이 측정하였습니다. SALARIES 테이블에 3GB의 데이터 로드 수행 시간은 SingleStore의 2가지 케이스 모두 MySQL에 비해 월등히 좋은 성능을 보여주었습니다. SingleStore는 분산 시스템으로 하나의 테이블이 리프 노드의 여러 개의 파티션에 분산 저장이 되고, 로딩 시에 해당 파티션에 병렬로 수행이 되기 때문에 MySQL 대비 빠른 데이터 로딩이 가능합니다.

 

Data loading 성능 비교

 


SingleStore 스키마 설계

DEPARTMENTS 테이블은 기본키(PK)와 고유키(UK)가 각각 단일 컬럼으로 구성되어 있고, 작은 데이터 건수가 저장되어있습니다. SingleStore는 UK로 지정된 칼럼은 PK에 포함되어 설계되어야 합니다. 이는, 분산 시스템이 하나의 테이블의 데이터가 샤드 키(SK)를 기준으로 여러 개의 독립된 파티션으로 나누어져서 분산 저장되어야 하기 때문입니다. (SK ⊆ UK ⊆ PK)

SingleStoreL의 레퍼런스(Reference) 테이블은 여러 파티션으로 나누어 분산 저장하지 않고 SingleStore 클러스터의 모든 노드에 해당 테이블 전체가 저장이 됩니다. 그렇기 때문에 이 테이블은 위와 같은 인덱스 제약을 받지 않습니다. 따라서, DEPARTMENTS 테이블은 레퍼런스 테이블로 구성하여 기존 스키마를 변경 없이 그대로 설계를 하였습니다.

 

나머지 3개 테이블에 대해 아래와 같이 3가지 테스트 케이스로 나누어 진행을 하여 성능을 측정했습니다.

1. RowStore

2. RowStore + ColumnStore

3. ColumnStore

 

메모리 기반 RowStore 테이블과 디크스 기반 ColumnStore 테이블은 분석퀴리문의 Join 효율성을 고려하여 Join 컬럼을 샤드키(SK)로 지정합니다. 이 때에, 인덱스 제약 사항에 맞춰 PK는 SK로 지정된 컬럼을 포함해야합니다. ColumnStore 테이블은 PK를 지원하지 않습니다. 이는, 단일컬럼의 UK로 대체 지원이 됩니다. 또한, Clustered Columnstore key를 분석쿼리문의 group by, 집계(Aggragation)함수로 지정되어있는 컬럼으로 지정하면 성능향상을 기대하실 수 있습니다.

 

 


분석 쿼리 수행 및 성능 차 비교

각각의 테스트 케이스에 대해 쿼리문을 수행한 경과는 아래와 같습니다.

분석 쿼리문을 동일한 시간 간격으로 6번 수행하였을 때의 평균 수행 시간은 기존의 MySQL 보다도 월등히 좋은 결과를 보여주었습니다. 3개의 테스트 케이스 중, 첫번째 테스트는 테이블이 전부 RowStore로 구성되어 데이터를 메모리에서 저장하고 처리하기 때문에 MySQL 대비 약 370배의 결과를 보여주었습니다.

그러나, 메모리 크기에 맞지 않게 테이블의 크기가 방대하거나, 큰 데이터 집합을 참조하는 쿼리문일 경우에는 ColumnStore 테이블로 구성하는 것을 고려해야합니다. 기존 MySQL 테이블 중, 날짜 컬럼으로 범위 지정되어 파티션된 크키가 큰 테이블은 디스크 기반 ColumnStore를 적용한 두가지 테스트 케이스로 진행되었습니다. 각 각 MySQL 대비 67, 56배의 성능 향상을 보여주었습니다.

이와 같이 SingleStore에서는 아래와 같이 4가지의 테이블 유형에 따라 목적에 부합하는 테이블 설계가 가능합니다.

 

■ RowStore

■ ColumnStore

■ Reference rowstore

■ Reference columnstore

 

RowStore와 ColumnStore 테이블은 테이블을 여러 개의 파티션으로 나누어 각 각의 저장방식으로 분산 저장됩니다. RowStore 테이블은 모든 데이터를 메모리에서 저장하여 쿼리를 수행합니다. 주로 OLTP와 HTAP 워크로드에 사용됩니다. Null값에 대해 sparse압축을 지원하며 많은 데이터의 빠른 SELECT 수행과 빈번한 INSERT, UPDATE, DELETE에 뛰어난 성능을 보여줍니다. 그러나, 트랜잭션 처리에는 적합하지만 모든 데이터를 메모리에 저장하므로 큰 데이터 셋을 RowStore에 저장하는데에는 비용이 많이 소요 될 수 있습니다.

ColumnStore 테이블은 데이트를 디스크에 저장하기 때문에 Rowstore보다 더 경제적입니다. 큰 데이터 셋을 빠르게 분석해야 쿼리에 매우 튀어난 성능을 발휘합니다. 또한 실시간으로 대량의 데이터를 insert하고 bulk delete하는데 활용성이 매우 큽니다. ColumnStore은 아래와 같이 유용한 기능을 통해 성능을 극대화하고 있습니다.

 

■ 해시 인덱스 지원

■ 하위 세그먼트 액세스를 통해 로우에 대한 액세스 속도 향상

■ 로우 레벨의 잠금 지원

 

ColumnStore 테이블 또한 DW의 차원(Dimemsion) 테이블과 같이 비교적 작은 테이블을 레퍼런스 테이블로 설계할 수 있습니다. 모든 클러스터의 노드에 이 테이블이 저장되어 있기 때문에 다른 테이블과의 Join 수행시에 분산된 저장된 데이터를 로컬 조인을 위해 임시 테이블을 만드는 단계가 필요치 않게 됩니다. 따라서 임시테이블 생성을 위한 데이터 이동의 오버헤드가 발생하지 않아 빠른 Join이 가능해집니다.

 


결론

금번 테스트를 통해 2가지 도전과제인 실시간 데이터 로딩과 분석 퀴리 모두에서 기존 MySQL 대비 SingleStore가 월등한 성능 차이를 보여주었습니다. SingleStore는 실시간으로 데이터를 로딩 하기 위한 다양한 파이프라인(Kakfa, filesystem, HDFS 등)이 내장 되어 있고 별도의 CDC 툴도 제공을 하고 있습니다. 해당 기업은 향후 기존 CDC(ETL) 툴인 인포메티카를 SingleStore CDC 툴로 대체를 위해 기능 및 성능 테스트를 수행하였고, 추가로 실시간 데이터 적제를 위해 Kafka 파이프라인에 대한 테스트도 수행을 하고 있습니다. 이를 통해 모든 솔루션 영역에 대해 SingleStore 적용을 단계적으로 진행 중에 있습니다.