NoSQL 데이터베이스 가이드: 언제, 어떤 모델을 선택해야 할까
레디스(Redis)에 대해 찾아보던 중, 자연스럽게 NoSQL 데이터베이스 전반에 대한 궁금증이 생기게 되었다. 레디스도 엄연히 NoSQL이기 때문에, 이를 제대로 알기 위해서는 NoSQL에 대해서 먼저 알아둘 필요가 있다고 생각했다. NoSQL에는 어떤 특징과 차이점이 있는지 한 번쯤 정리해두면 좋을 것 같았다.
이번 포스트에서는 NoSQL의 정의와 탄생 배경부터, 대표적인 분류와 각 모델의 특징, 그리고 실제로 언제 NoSQL을 선택해야 하는지까지 핵심 내용을 정리해보려고 한다.
정의
NoSQl이란 무엇일까? ‘Not Only SQL의 약자’ 또는 ‘No SQL’이라고 알려져 있다. 이전에 다뤘던 WebSocket와 같이 공식적으로 정의된 적이 없다. 즉, 국제 표준이나 특정한 기술적 규격으로 정해진 것이 아니라, 실용적 필요에 따라 자연스럽게 자리잡은 용어다. NoSQL이라는 단어는 영국 소프트웨어 개발자 조핸 오스카슨이 오픈소스 데이터베이스의 토론을 위해 주관된 모임의 이름에서 유래되었다고 한다.
마틴 파울러의 『NoSQL: 빅데이터 세상으로 떠나는 간결한 안내서』(인사이트, 2013) 에는 NoSQL이 아래의 조건을 만족하는 데이터 저장소라고 기술되어 있다.
- 대용량 웹 서비스를 위하여 만들어진 데이터 저장소
- 관계형 데이터 모델을 지양하며 대량의 분산된 데이터를 저장하고 조회하는데 특화된 저장소
- 스키마 없이 사용 가능하거나 느슨한 스키마를 제공하는 저장소
탄생 배경
일반적으로 관계형 데이터베이스는 저장된 데이터의 양이 많아질수록 읽기와 쓰기 성능이 저하된다. 특히 쓰기 성능 저하가 두드러지는데, 이는 대부분의 관계형 데이터베이스가 채택하고 있는 인덱스 처리 방식인 B트리 구조의 한계에서 비롯된다. 대용량 데이터 환경에서는 B트리 인덱스의 노드 분할이나 재구성 과정이 빈번해지면서 쓰기 작업의 효율이 떨어질 수 있기 때문이다.
시간이 지남에 따라 구글, 아마존 등과 같이 성공한 글로벌 서비스는 기존의 관계형 데이터베이스를 사용하여 처리할 수 없을 만큼의 데이터를 생산하기에 이르게 되었다. 이러한 문제를 해결하기 위해 실시간 분산처리를 위한 오픈소스 솔루션들이 개발되었고 그 결과물이 바로 NoSQL이다.
NoSQL은 분산환경에서 대량의 데이터를 빠르게 처리하기 위해서 한두 가지 단점을 가진 채로 개발됐다. 이 부분에 대해서는 다음장을 살펴보자.
CAP 정리
단점들을 알기 위해서는 CAP정리를 먼저 알아야 한다.
CAP정리란, 이론 컴퓨터 과학 분야에서 분산 컴퓨터 시스템을 설명하는 데 사용되는 이론이다. 내용은 다음과 같다.
일관성(Consistency), 가용성(Availability), 분할 허용성(분할내성, Partition Tolerance) 모두를 동시에 지원하는 분산 컴퓨터 시스템은 없다.
NoSQL은 기본적으로 분산 시스템 환경에서 잘 동작하도록 설계되어 있다. 이 때 각 NoSQL은 일관성, 가용성, 분할 허용성 가운데 두가지 속성만을 지원하며 나머지 한 속성은 특정 조건에서만 만족한다. 이것이 CAP정리의 핵심이다.
분산 컴퓨터 시스템
각각의 조건을 알아보기 전에 분산 컴퓨터 시스템에 대해 간단히 알아보자.
인터넷에 연결된 여러 컴퓨터들의 처리 능력을 이용하여 메시지를 하나에서 다른 하나로 보냄으로써 거대한 계산 문제를 해결하려는 분산처리 모델이다.
- 노드
- 분산 시스템을 구성하는 각각의 하드웨어 또는 소프트웨어
- 클러스터
- 동일한 기능을 수행하는 노드들의 모음
- 네트워크
- 각 클러스터 간의 연결
CAP의 속성
이제 CAP의 각각의 속성을 알아보자.
일관성(Consistency)
일관성은 동시성 또는 동일성이라고도 하며 다중 클라이언트에서 같은 시간에 조회하는 데이터는 항상 동일한 데이터임을 보증하는 것을 의미한다.
일관성은 관계형 데이터베이스가 지원하는 가장 기본적인 기능이다. 하지만 NoSQL에서는 빠른 분산 처리를 위하여 일관성을 희생하기도 한다.
NoSQL은 분산 노드 간의 데이터 동기화를 위해 두 가지 방법을 사용한다.
- 동기식 방법
- 데이터의 저장 결과를 클라이언트로 응답하기 전에 모든 노드에 데이터를 저장하는 방식
- 모든 노드에 데이터 저장이 완료되는 시간 동안 클라이언트에게 저장 결과를 돌려줄 수 없으므로 느린 응답시간을 보인다.
- 비동기식 방법
- 메모리나 임시 파일에 기록하고 클라이언트에 먼저 응답한 다음, 특정 이벤트 또는 프로세스를 사용하여 노드로 데이터를 동기화하는 방식
- 빠른 응답을 줄 수 있지만, 쓰기 노드에 장애가 발생하였을 때 데이터를 일어버릴 수 있다.
위 방식을 보면 알 수 있듯이 분산 시스템에서 일관성을 유지하기 위해서는 응답시간의 희생이 따른다. 이와 같은 응답시간의 지연을 방지하기 위해 일관성과 응답시간의 적절한 타협음을 찾기도 한다. 대표적인 예로 카산드라의 일관성 레벨이 있다.
가용성(Availability)
가용성이란 모든 클라이언트의 읽기와 쓰기 요청에 대하여 항상 응답을 가능해야함을 보증하는 것으로 내고장성이라고도 한다.
내고장성을 가진 NoSQL은 클러스터 내에서 몇 개의 노드가 망가지더라도 정상적인 서비스가 가능하다.
가용성을 위한 데이터 중복 저장 방법에는 두 가지 방법이 있다.
- 마스터-슬레이브
- 동일한 데이터를 가진 저장소를 하나 더 생성하는 방식
- 피오-투-피어
- 데이터 단위로 중복 저장하는 방식
분할 허용성(Partition Tolerance)
지역적으로 분할된 네트워크 환경에서 동작하는 시스템에서 두 지역 간의 네트워크가 단절되거나 네트워크 데이터의 유실이 일어나더라도 각 지역 내의 시스템은 정상적으로 동작해야 함을 의미한다.
NoSQL 데이터베이스들의 특징
위에 서술한 것 처럼 모든 CAP의 속성을 지원하는 분산 컴퓨터 시스템은 없다. 데이터베이스가 지원하는 특징을 한 장의 그림으로 표현하면 다음과 같다.
NoSQL 데이터베이스의 특성 일관성, 가용성, 분할 허용성 중에서 어떤 두가지 속성을 지원하는지에 따라서 NoSQL의 특징이 달라지게 되는데 이는 NoSQL의 분류에서 알아보자.
NoSQL의 분류
NoSQL은 데이터 저장 방식에 따라 분류되기도 한다. NoSQL은 데이터 접근을 위해 키(Key)를 사용하는데, 키에 사용된 데이터 모델에 따라 분류하면 크게 4가지 모델로 분류할 수 있다.
키-값(Key-value)
가장 기본적인 형태의 NoSQL이며, 키 하나로 데이터 하나를 저장하고 조회할 수 있는 단일 키-값 구조를 가진다.
주요 활용 사례
단일 연산에 의하여 처리를 완료하거나 취소할 수 있는 경우에 적합하다. 대표적으로 사용자의 프로필 정보, 웹 서버의 클러스터를 위한 세션 정보, URL단축 정보 저장 등이 해당된다.
문서(Document)
키-값 모델을 개념적으로 확장한 구조다. 하나의 키에 하나의 구조화된 문서를 저장하고 조회한다.
키는 문서에 대한 ID로 표현한다. 또한 저장된 문서를 컬렉션으로 관리하며, 문서 저장과 동시에 문서 ID에 대한 인덱스를 생성한다. 문서 ID에 대한 인덱스를 사용하여 O(1)시간 안에 문서를 조회할 수 있다. 저장된 문서의 형태에 따라 키 이외의 2차 인덱스를 지원하기 때문에 값을 비교한 조회도 가능하다.
주요 활용 사례
B트리의 특성으로 인하여 한번 작성되면 자주 변하지 않는 정보를 조회하는데 적합하다. 대표적으로 중앙 집중식 로그 저장, 타임라인 저장, 통계 정보 저장 등이 이에 해당된다. 단, 조회시 특정 수량을 기준으로 잘라서 조회하는 기능 등에는 알맞지 않다.
컬럼(Column-family)
하나의 키에 여러 개의 칼럼 이름과 컬럼 값의 쌍으로 이루어진 데이터를 저장하고 조회한다. 단일 키에 의한 단일 컬럼 및 범위 조회도 가능하다. 모든 컬럼은 항상 타임스탬프 값과 함께 저장된다. 컬럼 모델에서 키는 로우키라 불린다.
주요 활용 사례
쓰기와 읽기준에 쓰기에 더 특화되어 있다. 쓰기 연산은 데이터를 먼저 커밋로그와 메모리에 저장한 후 응답하기 때문에 매우 빠른 응답 속도를 제공한다. 이와 같은 이유로 연산 대비 쓰기 연산이 많은 서비스나 빠른 시간안에 대량의 데이터를 입력하고 조회하는 서비스를 구현할 떄 좋은 성능을 보여준다. 대표적인 예로 채팅 내용 저장, 메일 저장소, 알림 내용 저장 등이 있다.
그래프(Graph)
그래프 모델은 노드와의 관계를 사용하여 데이터를 저장하고 조회하는데 관계는 속성이라는 부가정보를 가진다. 그래프 데이터베이스는 관계형 데이터베이스와 가장 유사한 NoSQL이다.
주요 활용 사례
친구 추천과 같은 연관검색을 위한 정보를 저장하고 조회하는데 적합하다. 기존 관계형 데이터베이스에 구현하기 까다로운 부분이 그래프 모델 NoSQL에서는 기본으로 제공되기 때문이다. 다중 관계를 가진 엔티티를 저장하고 조회하는데 알맞다.
언제 어떤 NoSQL을 사용해야 될까?
관계형 데이터페이스는 충분히 성숙된 기술이며 범용 데이터 저장소로서의 역할을 충분히 수행하고 있다. 복잡한 업무 로직을 처리하는 분야에서도 관계형 데이터베이스가 더 나은 성능을 보인다. 그럼에도 불구하고 NoSQL이 필요한 상황이 발생할 수 있다.
- 대량의 단순 정보를 빠르게 저장하고 조회할 때
- 관계형 데이터베이스가 처리하지 못하는 대량의 데이터를 입력할 때
- 스키마가 고정되지 않은 데이터를 저장하고 조회할 떄
위와 같은 상황에 처해 NoSQL의 도입을 확정했다면 어떤 NoSQL을 도입할지 결정해야한다. 언제 NoSQL을 사용해야 하는가 보다는 어떤 NoSQL을 도입해야하는가와 같은 질문이 더 중요하다.
NoSQL을 선택할 때 고려할 사항은 다음과 같다.
- 일관성
- 서비스에서 어느정도 일관성이 필요한지 확인해야 한다.
- 일관성은 데이터 저장 모델과는 크게 상관없다.
- 강한 일관성이 필요한 서비스를 구현하기 위해서 궁극적 일관성을 지원하는 카산드라는 득보다 실이 클 수 있다.
- 데이터 모델
- 제공하려는 기능이 키-값 모델과 같은 간단한 모델로 처리가 가능한지 여부를 확인해야한다.
- 문서 모델과 같이 중첩된 구조를 지원해야하는지 판단해야한다.
- 앞서 알아본 데이터 모델별로 필요한 기능을 구현할 수 있는지에 대해 판단해야 한다.
- 읽기 쓰기 성능
- 제공할 기능의 읽기와 쓰기 비율에 따라 선택할 NoSQL도 바뀌어야 한다.
- 읽기, 쓰기 모두가 빠른 응답시간이 필요하다면 인 메모리 NoSQL이 후보가 될 수 있다.
- 상대적으로 읽기 비율이 높다면 B트리 구조를 사용하는 문서 모델 NoSQL이 후보가 될 수 있다.
- 단일 고장점
- 선택한 NoSQL이 단일 고장점(SPOF)을 가지고 있는지 확인해야 한다.
- 단일 고장점을 가지고 있더라도 쉬운 복구가 가능한지 확인해야 한다.
- HBase는 단일 고장점을 가지고 있지만, 하드웨어적인 방법을 통해 단일 고장점을 제거할 수 있다.
- 보조 네임 노드를 사용하고 있기 때문에 장애 상황에서 빠른 복구도 가능하다.
- 무정지 서비스가 중요 목표라면 단일 고장점을 가진 NoSQL 선택을 피해야 한다.
- 원자성 지원
- 선택한 NoSQL의 트랜잭션 지원 여부를 확인해야 한다.
- 단일 연산에 대한 지원 여부 같은 CAP특징을 확인해야 한다.
- 원자성의 지원이 어느쪽(서버, 클라이언트)에서 지원되는지 확인해야 한다.
- 클라이언트에서 지원하는 단일 연산의 원자성은 코드의 복잡성을 증가시킬 수 있다.
- 하드웨어 구성
- 해당 NoSQL이 가지는 시스템 아키텍처를 확인해야 한다.
- 가용성을 지원하기 위해서 마스터-슬레이브 구조의 NoSQL을 선택했다면 저장되는 데이터의 최대 크기는 절대적인 저장소 크기의 절반이다.
- NoSQL 내부의 구성요소와 하드웨어에 대한 기본 구성 정보를 알아야 한다.
- 예를들어 HBase는 최소 5대 이상의 하드웨어에서 수행되어야만 성능의 선형 증가를 얻을 수 있다.
- 무중단 시스템
- 시스템을 확장핼 때 중단이 필요한지 여부와 같은 시스템 특성을 확인해야 한다.
위와 같은 고려사항을 확인하여 서비스에서 필요한 부분과 필요없는 부분을 먼저 선택하고 난 뒤 그에 맞는 SQL을 선택해야 한다. 즉, 필요한 요구사항을 모두 만족하는 NoSQL을 선택해야 한다.
마무리
이번 포스테서는 NoSQL의 전체적인 개념과 CAP이론, NoSQL의 분류에 대해 살펴보았다. 위에 서술 했듯 무턱대고 NoSQL을 사용하여 기능을 구현하고자 한다면 오히려 힘겹게 개발하고도 만족하지 못하는 성능을 보게 될 수 있다는 것을 알게 되었다.
NoSQL은 관계형 데이터베이스의 한계를 극복하고 모든 장점을 모아둔 솔루션이 아니다. 기존의 관계형 데이터베이스가 제공하는 테이블 조인, 트랜잭션, SQL 등 편의성을 포기하고 스케일 아웃과 같은 NoSQL의 장점을 얻은 또 다른 데이터 베이스다.
개발자에게 은총알은 없다는 것을 또 한번 깨닫게 되었다. 새로운 기술을 배울 때 내가 얻는 것과 잃게되는 것, 즉 트레이드오프를 생각하면서 공부해야겠다는 생각을 하며 이번 포스트를 마친다.





