4 분 소요

앞선 글까지 NoSQL의 4가지 종류(분산 KVS, WCS, Document Store, Search Engine)에
대해서 살펴보았다. 각 문서에서는 RDBMS와 비교했을시 NoSQL의 성능이 더 우수하다고
되어있지만 글로만 봐서는 체감이 되질 않는다.

그래서 이제는 실제로 얼만큼 성능의 차이가 나는지 체크 해보고자 한다.

이번 POST에서는 RDB(SQLITE) + NoSQL(분산 KVS, WCS, Document Store, Search Engine)간에 성능 테스트를 주제로 글을 작성해 보고자 한다.

Document Store의 경우에는 schemaless한 데이터들을 유연하게 적재할 수 있다는게 장점이기 때문에 성능 비교와는 거리가 먼 것 같아서 제외하도록 한다.

Performance 측정은 RDBMS에서도 가능하고 NoSQL에서도 가능한 목록들에 대해서 한번 체크를 해보려고 한다.

떠오르는 것들은 다음과 같다.

index RDBMS NoSQL What?
1 SQLITE-Index KVS(DynamoDB, Cassandra) Read/Write 속도 비교
2 SQLITE-FTS SearchEngine(ElasticSearch) 검색 속도 비교

하나씩 차례대로 확인해보자.



1. RDBMS vs Key-Value Store 성능 비교

첫번째로 Key-Value Store와 RDBMS 사이에 어떠한 차이가 있는지에 대해서 비교를 해보자.
Key-Value Store의 장점은 Key별로 빠르게 데이터를 Read 하거나 Write를 할 수 있다는 점이다.
예를 들면 유저정보와 같이 Key를 통해서 데이터를 빠르게 주고받아야 할때 강점을 발휘한다.

과연 얼마나 차이가 날까? 한번 Test 해보자.
RDBMS는 SQLITE, Key-Value Store는 Apache Cassandra를 사용해 Test를 진행한다.
( 앞서 소개한 KVS인 DynamoDB는 요금 걱정때문에 우선은 제외.. )

유저 정보에 관한 Schema는 아래와 같이 정의해보았다.

유저 정보(client_info) Schema

Column Column(eng) Description Type 범위
고객 id user_id 고객의 id text uuid_4
고객 pw user_pw 고객의 pw text 12자리 알파벳 + 숫자의 조합
고객 성명 user_name 고객의 이름 text -
회원/비회원 is_member 고객이 회원인지 비회원인지? boolean 0 = 비회원, 1 = 회원
성별 sex 고객의 성별 boolean 0 = 여성, 1 = 남성
나이 age 고객의 나이 int 12~70
직업 job 고객의 직업에 대한 정보 text -
주소 home_address 배송이 이뤄져야할 위치에 대한 정보 text -

Test 1. 유저 정보 Read / Write

실시간 웹 서비스에서 유저의 정보를 빠르게 저장하고 가져오고 싶은 상황이 있다고 가정하자.
첫번째로 테스트할 내용은 실제 Write 속도가 얼마나 차이가 있을지에 대한 차이다.

아래의 테스트 환경으로 진행을 해보자.

Environments

  • PC 사양
    • CPU - AMD Ryzen 5 3500X 6-Core Processor(3.60 GHz)
    • RAM - 16GB
    • OS - Window 10 Home
  • DB Engine : SQLITE3( Local ), Cassandra( Local, 1 Server )
  • 최대 1000만명의 유저가 있다고 가정하고 Read/Write Test 진행.
  • Key = 고객 id(user_id)

Test 1-1. Write Test

개수별로 차이가 있을 수 있어 이를 고려하여 100만, 500만, 1000만 rows를 대상으로 테스트해보았다.

alt

100만 rows를 write 할때는 속도가 크게 차이가 나지 않지만,
1000만 rows에서는 SQLITE가 무려 1.5배나 느린 것으로 확인되었다.

https://www.sqlite.org/speed.html에 따르면 sqlite는 다른 대표적인 RDBMS인 MySQL, PostgreSQL와 비교했을때 속도가 빠른 편이다. (꽤 오래 된 자료이기 때문에 현재는 다를 수 있음.)

이를 인용하면 일반 RDBMS보다는 cassandra에 Write를 하는 것이 더 빠르다고 볼 수 있을 것 같다.

아래 표를 보면 sqlite(no-index)의 경우가 가장빠르지만 실제 운영 환경에서는 read 속도를 위해 index를 생성할 것이므로 무시해도 될 것 같다.


Test 1-2. Read Test

다음은 Read Test를 진행해보았다.

Case 소요시간(sec) image
SQLITE3 Read 1 record(No Index) 1760 ms alt
SQLITE3 Read 1 record(Index) 1~4 ms alt
CASSANDRA Read 1 record 3 ms alt

1000만 rows를 기준으로 read test시에는 속도가 거의 비슷하게 나왔다.
sqlite3에서는 1~4 ms를 유지하고, Cassandra에서는 3ms를 유지하고 있다.

Read 속도는 큰 차이가 없는 것으로 확인된다.
sqlite에서 index가 없는 경우에는 무려 1.7초나 걸린다.

Query : select * from client_info where user_id = '7888a4bc-51c8-42a3-9f73-2b898a0a14e6'



2. ElasticSerach VS SQLITE3-FTS5 성능 비교

다음은 ElasticSearch와 SQLITE3-FTS5의 성능을 비교해보자.
FTS5(Full-Text-Search)는 SQLITE3에서 제공되는 검색 용도로 사용하는 Virtual Table이다.

단순히 title, content로 이루어진 posts table(혹은 class)를 탐색하는 속도를 비교해보고자 한다.

게시글(posts) Schema

Column Column(eng) type
글제목 title text
글내용 content text

input 데이터 제작

elasticsearch에 bulk 하기 위해 json 형식의 input 데이터가 필요하다.
이 후, linux 서버에서 아래 쿼리를 날려 bulk 하는 방식으로 데이터를 삽입하고자 한다.

query : curl -XPOST http://localhost:9200/_bulk?pretty -–data-binary @[json_file_name] -H 'Content-Type: application/json'

bulk 데이터 삽입시에는 아래 이미지와 같이 index 정보가 미리 들어가 있어야 하므로 주의가 필요하다. ( _index = database, _type = table 로 생각하면 된다. )

alt

sqlite3용 데이터는 csv를 bulk하면 되므로 별도로 설명하지는 않겠다.
fts5 사용방법은 https://www.sqlitetutorial.net/sqlite-full-text-search/를 참조했다.

Test 방식

elasticserach, sqlite3 모두 python을 통해 test를 진행했다. content 기준 keyword 검색시 matching 되는 항목들의 title을 가져오는 방식으로 테스트를 시도해보았다.

1
2
3
4
5
6
7
8
9
# elasticsearch 
resp = es.search(index="posts", size=10000, query={"match" : { "content" : keyword}})
    for hit in resp['hits']['hits']:
        result.append(hit['_source']['title'])

# sqlite3
for row in cursor.execute(
        "SELECT title from posts where content MATCH '" + keyword + "'"):
        result.append(row[0])

test 결과

alt

10만개의 record를 대상으로 테스트 진행시 sqlite가 약 10배 정도로 빨랐다.
하지만 Http transport를 하는것과 local에서 가져오는 것의 차이가 있기에 당연히 Elasticsearch가 sqlite 보다는 느릴 수 밖에 없을 것이라 생각한다.

그래도 ElasticSearch도 10만개의 record를 대상으로 약 163ms 만에 게시글을 검색이 가능하다는 점은 매우 흥미로웠다. REST API로 쉽게 사용도 가능하고 저정도면 속도도 나쁘지 않은 것 같아보인다.

match_size는 실제로 검색을 통해 찾은 항목들의 개수인데 두 개 모두 일치하는 것을 알 수 있었다.



글을 마치며

책에서 본 내용을 바탕으로 NoSQL를 접해보고, 성능 비교를 위해 이들을 간단하게나마 사용해 볼 수 있었다.
사실 테스트를 제대로 한건지도 의문이긴 하지만 더 깊게 파고들면 공부할 것이 많아질 것 같아 이정도까지만 해보고 마치려 한다.

확실히 RDBMS 만으로는 만족하지 못하는 요구사항들이 존재하는 것이 있었고, 이것들을 충족시키기 위해 다른 컨셉의 DB가 필요하다는 것을 확실히 알 수 있었다.

물론 이번에 해본 것은 모두 빙산의 일각이겠지만 그래도 재미난 경험이었다.
개인적으로 좀 더 확실한 테스트 환경 구성을 위해 EC2를 사용했어야 하지 않았나 싶지만 이것은 다음 기회에 도전해봐야겠다.

이 글이 비슷한 주제로 궁금증을 가지는 사람들에게 조금이나마 도움이 되었으면 한다.
(o゚v゚)ノ (o゚v゚)ノ

댓글남기기