RDB 혹은 nosql 중 어떤 것을 사용 하는게 내 사이드 프로젝트에 맞을까?
하루 밖에 없어서 러프하게 진행
create table latlng.tbl_latlng
(
n_id int auto_increment
primary key,
lat_st float not null comment 'latitude value',
lng_st float not null comment 'longtitude value',
lat_offset float default 0 not null comment 'lat buffer value',
lng_offset float default 0 not null comment 'lng buffer value',
buffer_text text null comment 'HASH',
create_dt datetime default current_timestamp() null,
region_cd varchar(4) null,
lat_now float null,
lng_now float null
);
create table latlng.tbl_latlng
(
uuid uuid,
lat_st float,
lng_st float,
region_cd varchar,
buffer_text text,
create_dt timestamp,
lat_now float,
lat_offset float,
lng_now float,
lng_offset float,
primary key (uuid, lat_st, lng_st, region_cd)
)
with caching = {'keys': 'ALL', 'rows_per_partition': 'NONE'}
and compaction = {'max_threshold': '32', 'min_threshold': '4', 'class': 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'}
and compression = {'class': 'org.apache.cassandra.io.compress.LZ4Compressor', 'chunk_length_in_kb': '16'}
and speculative_retry = '99p';
단순 성능 비교를 위해 싱글 스레드로 INSERT
진행
단순한 INSERT
행위는 mariadb가 cassandra보다 느리다.
다만 싱글 스레드로 돌렸다는 점이 어느정도 오류로 보일 수 있겠지만 이번 벤치마킹에서 멀티쓰레딩은 고려사항이 아니다.
만약 RDB 및 nosql을 커넥션풀 + 멀티쓰레드로 돌리면 처리량은 배 이상으로 올라 갈 것으로 예상은 할 수 있겠다.
또한 nosql은 UPDATE
를 제외하고는 (원자성인 Atomicity를 준수하고자 노력한다) ACID
를 신경쓰지 않으므로 멀티쓰레딩 측면을 고려했을 때에는 극단적인 성능차이가 나타 날 것으로 추측된다
(이 부분은 차후 테스트를 따로 해봐야겠다.)
nosql에서는 트랜잭션이 없어서 따로 Lock이 걸리지 않는다.
이로인해 멀티쓰레딩 시 성능이 많이 올라 갈 것으로 예상된다.
jmeter, ycsb와 같은 benchmarking tool을 이용해 멀티 쓰레딩을 고려 할 수도 있지만 이번 테스트 벤치마킹에서는 제외한다.
핵심기능과 같은 조건으로 UPDATE
DML을 수행한다.
속도차이가 너무 나서 그래프를 어떻게 그려도 이상하게 나오는 관계로 테이블로 표현..
횟수 | Mariadb INSERT | Mariadb UPDATE | Cassandra INSERT | Cassandra UPDATE |
---|---|---|---|---|
1000 | 4.8 sec | 0.00810 sec | - | - |
5000 | 23.1 sec | 0.02054 sec | - | - |
10000 | 46.7 sec | 0.03315 sec | - | - |
30000 | 144.4 sec | 0.10007 sec | - | - |
100000 | 481.4 sec | 0.28355 sec | 72.8 sec | 70.04 sec |
UPDATE
에 걸리는 시간이 유의미 할 정도로 오래 걸리지 않는다.INSERT
, UPDATE
를 진행 하지 않은 이유는 두 행위가 작동하는 방법이 같아서 시간이 가장 많은 처리량 하나만 봐도 앞의 결과를 예측 할 수 있다. (case1 에서의 insert 결과 참조)핵심기능을 임시로 구현해 보았으나 성능이 너무 떨어졌다.
Cassandra는 사이드 프로젝트 핵심 기능의 관리 측면에서는 우수하다. 하지만 Query 수행 성능은 적합하지 않다는 것이 내 결론이다.
아직까지 nosql에서 지원하는
counter
자료형은 전부 64bit Integer형으로 float 데이터를 연산 하는 것이 불가능하다.
counter
자료형이 _64-bit Integer 이기 때문이다.
참고 자료 sylladb Counter
참고 자료 cassandra Counter
이번 벤치마킹을 통해 nosql은 불합리한 것으로 판단 완료
내가 원하는 지역별 DB 분산은 구현 할 수 없겠으나 그러지 않아도 될 정도로 UPDATE
성능이 우수하므로 mariadb를 사용 한다
이 이상의 조사는 바이크 쉐딩이 되므로 개발에 착수하자
구현해야 하는 핵심기능의 조건은 특정 테이블 전체 ROW에 대해 일괄적인 UPDATE
를 수행하는 것이 핵심이다.
옵션으로 물리적인 지역성을 가질 수 있으면 좋다. (부하분산)
지역성을 가질 수 없다면 상대적으로 성능이 많이 뛰어나야 한다.
또한 1인 개발이므로 거인의 어깨와 같이 많은 자료를 가지고 있어야 하며 오픈소스 이어야 한다.(문서화가 잘 되어 있는 것)
라이센스는 커머셜 프리로 사용 할 수 있는 Apache License
, MIT License
가 달려있는 오픈소스를 사용한다.
조사 후 RDB는 maraidb
, nosql은 지역성을 가질 수 있는 wide-column database 중 cassandra
를 테스트 대상으로 올렸다.
postgresql의 query plan은 구현 할 핵심기능의 동작에 비교해서 생각해봤을 때 매력적인 기능이다.
하지만 mariadb에서 제공하는 query cache 또한 훌륭한 기능이고 반복적으로 사용 했을 때 성능이 좋아지는 query plan 보다는
수행 즉시 사용 가능한 query cache가 이득이 클 것으로 예측 된다.
물론 context switching 같은 면에서는 postgre가 더 뛰어나지만 현대에 사용하는 HW가 이런걸 고려 할 정도로 느리진 않다고 생각해서 방점을 찍을 정도로 중대한 부분은 아니라고 본다.
(*devops에서 할 일을 지금 부터 걱정 할 필요가 있겠는가)
정리하면 mariadb query cache가 내 사이드 프로젝트 핵심 기능 면에서는 더 적합할 것으로 판단한다.
nosql을 통해 내 서비스 핵심기능을 구현 할 수 있는 다른 합리적인 방법이 있는지 더 찾아보고 싶었으나 남은 시간이 얼마 없어 비교적 간단하게 끝내는 점이 많이 아쉽다. 또 nosql을 고려 할 때 지역성을 고려하지 않고 단순 Key-Value 혹은 Document Store를 고려했으면 어땠으려나..