NoSQL에 대해서 간단히 알아보자!

CAP이론?

CAP

NoSQL 소개에는 빠지지 않고 등장하는 그림이다. 이 그림을 약 3~5초정도 보면 다음과 같은 의문이 생기게 된다.

“그럼 ACID는?”

ACID(원자성, 일관성, 고립성, 지속성)는 데이터베이스 트랜젝션이 안전하게 수행된다는 것을 보장하기 위한 성질을 가리키는 약어이다.

– 위키백과, (http://ko.wikipedia.org/wiki/ACID)

ACID는 RDBMS에서 매우 중요하게 생각하는 성질이라 할 수 있다. 그런데 NoSQL에서는 찾아보기 힘든 단어이다.

2000년 Eric Brewer가 “Towards Robust Distributed Systems”라는 제목으로 CAP 이론을 소개할 때 BASE에 대해서도 소개했었다.

성능과 가용성 등을 위해서 ACID의 C와 I의 속성을 포기하고 분산 시스템에 더 적합하다고 생각되는 성질을 정리한 것이 BASE이다.

BASE가 나타내는 성질은 다음과 같다.

Basically Available : 기본적으로 Available하고
Soft-state : 사용자가 관리(refresh, modify)하지 않으면 Data가 expire 될 수도 있으며
Eventually consistency : 지금 당장은 아니지만 언젠가는 Data가 일관성을 가진다

전달하고자 하는 의미는 알겠는데 찝찝한 부분이 있다!

1. Basically Available은 Basically라는 부사를 사용하지 않고 Availablility라고만 표현해도 되고
2. Eventually consistency도 마찬가지로 Eventually라는 부사를 사용하고 있다
3. 게다가 ACID처럼 명사들 만의 약자가 아닌 Basically Available = 부사 + 형용사, Soft-state = 명사, Eventually consistency = 형용사 + 명사 로 구성되어있다.

이렇게 억지로 짜맞춘 단어처럼 보이는 BASE는 ACID와의 관계를 고려하면 좀 더 간결하고 명확한 의미 전달을 할 수 있는 명사들의 약자를 쓰지 않은 이유를 알 수 있다.

Acid와 Base의 비교 #1
acid vs base

ACID와 BASE의 비교 #2
acid vs base 2

분산 시스템에서 관리되는 데이터의 특징을 나타내는 BASE라는 단어는 의미의 전달보다는 중학교때 배운 산(Acid)과 염기(Base)와 같아보이려는 노력에 의해서 탄생했다는 것을 알 수 있다;;

CAP이론!

BASE의 탄생에 대해서는 그냥 그러려니~ 하고 넘어가고 CAP이론에 대해서 알아보자. 제일 처음에 있던 CAP 세모는 영어로 써져있고 글자도 많으니 좀 더 간단한 그림을 그려보면 다음과 같다.

CAP circle

CAP이론은
“분산 시스템에서는 위 그림의 3개 속성을 모두 가지는 것이 불가능하다!”
이다.

CAP이론에서 보여주는 3개의 속성에 대해서 각각 알아보면 다음과 같다.

Consistency

  • 우선.. CAP이론에서 말하는 Consistency는 ACID의 ‘C’가 아니다! ACID의 ‘C’는 “데이터는 항상 일관성 있는 상태를 유지해야 하고 데이터의 조작 후에도 무결성을 해치지 말아야 한다”는 속성이다.
  • CAP의 ‘C’는 “Single request/response operation sequence”의 속성을 나타낸다. 그 말은 쓰기 동작이 완료된 후 발생하는 읽기 동작은 마지막으로 쓰여진 데이터를 리턴해야 한다는 것을 의미한다.
  • 모든 노드가 같은 시간에 같은 데이터를 보여줘야 한다. (저장된 데이터까지 모두 같을 필요는 없음)
  • 정리해보면 Consistency라는 단어보다는 Atomic이라는 단어가 더 정확하게 특징을 나타낸다고 할 수 있다. (Atomic Data Object, Atomic Consistency)
  • 그럼 “CAP가 아니라 AAP가 되어야 할텐데..” 라는 생각이 들 수도 있다. 어차피 ACID와 비교하기 위해서 BASE라는 단어도 억지로 만들어내는데 AAP보다는 CAP가 더 이뻐보이니 그렇게 했다고 생각하고 넘어가면 된다.

Availability

  • 가용성
  • 흔히 보는 단어이고 의미도 크게 혼동될 이유가 없어보인다. “특정 노드가 장애가 나도 서비스가 가능해야 한다”라는 의미를 가진다.
  • 데이터 저장소에 대한 모든 동작(read, write 등)은 항상 성공적으로 리턴되어야 한다.
  • 명확해 보이는 단어이기는 하지만 분산 시스템에서의 특징을 말하는 것이기 때문에 “서비스가 가능하다”와 “성공적으로 리턴”이라는 표현이 애매하다. 얼마동안 기다리는 것 까지를 성공적이라고 할 수 있느냐에 대한 문제가 남아있다. “20시간정도 기다렸더니 리턴이 왔어! Availability가 있는 시스템이야!”라고 할 수 없기 때문이다.
  • 다시한번 “성공적으로 리턴”에 대해서 보면 모든 동작에 대해서 시스템이 “Fail!!”이라는 리턴을 성공적으로 보내준다면 그것을 Availability가 있다고 해야 하느냐에 대해서도 애매하다. CAP를 설명하는 문서들 중 “Fail!!”이라고 리턴을 하는 경우도 “성공적인 리턴”이라고 설명하는 것을 보았다.

Tolerance to network Partitions

  • 원래는 Tolerance to network Partitions인데 보통은 Partition-tolerance라고도 한다.
  • 노드간에 통신 문제가 생겨서 메시지를 주고받지 못하는 상황이라도 동작해야 한다.
  • Availablity와의 차이점은 Availability는 특정 노드가 “장애”가 발생한 상황에 대한 것이고 Tolerance to network Partitions는 노드의 상태는 정상이지만 네트워크 등의 문제로 서로간의 연결이 끊어진 상황에 대한 것이다.

CAP 이론의 이해

CAP이론은 2002년 MIT의 Seth Gilbert와 Nancy Lynch에 의해서 증명되었다. CAP이론을 증명하는 논문에는 그림이 하나도 없어서 너무너무 재미 없다. 재미없는 논문 보다는 간단한 그림으로 CAP이론을 이해해볼 수 있다.

CAP이론을 이해해보기에 앞서.. 다음과 같은 상황을 가정해본다.
understanding_cap1
– 네트워크가 N1, N2로 구분된 분산환경이다.
– 각 DB 노드는 V=V0이라는 값을 가지고 있다.
– 각 네트워크에는 A, B라는 클라이언트가 존재한다.
– A는 V=V1이라고 쓰고 B가 그것을 읽는다.

이런 환경에서 메시지 전달 과정(M)에서 문제가 생겼을 때..
understanding_cap2

1. “C”가 꼭 필요한 상황인 경우
– A가 V1이라고 썼기 때문에 B는 V1이라고 읽을 수 있어야만 한다.
– A의 쓰기 동작은 M이 복구되기 전까지는 성공할 수 없다.
– M이 복구되기 전까지는 A의 Write는 block되거나 실패해야 한다. = Availability가 없음 = CP
– M이 문제가 생길 수 없도록 구성 = Partition-Tolerance가 필요 없음 = CA

2. “A”가 꼭 필요한 상황인 경우
– 어떤 경우에도 서비스가 Unavailable하면 안된다.
– A와 B가 꼭 동일한 데이터를 읽을 필요는 없음 = AP
– M이 문제가 생길 수 없도록 구성 = Partition-Tolerance가 필요 없음 = CA

3. “P”가 꼭 필요한 상황인 경우
– 메시지 전달 과정(M)에서 문제가 생기더라도 시스템에 영향이 가서는 안된다.
– A와 B가 꼭 동일한 데이터를 읽을 필요는 없음 = AP
– A의 쓰기 동작은 M이 복구되기를 기다린다. = 그동안 쓰기 서비스 불가능 = Availability가 없음 = CP

NoSQL??

NoSQL이라는 단어에 대해서 “적극적으로” 인터넷을 뒤져보았더니 다음과 같이 설명하고 있었다.

  1. No SQL : SQL이 없다는 의미이다.
  2. Not Only SQL : SQL뿐이 아니다.. SQL말고도 더 있다
  3. NOn-relational operation database SQL : 비관계형 DB SQL

종합해보면 NoSQL은 “SQL이 없으면서도 SQL뿐만 아니라 다른거도 있는 비관계형 DB이다”라고 할 수 있다. 이건 누가 들어도 “대단해!”라고 말할만 하다.
great_nosql

하지만 이미 “BASE”라는 단어에서 느낀것이 있기 때문에 “NoSQL”이라는 단어에서 “N은 이런 의미이고 O는 이런 의미이고..”와 같이 단어 자체에 의미를 부여하려는 쓸데없는 시도는 무시하고 다시 NoSQL에 대해서 정의를 내리면 NoSQL은 “관계형 데이터 모델을 사용하지 않는 모든 Database 또는 Data Store”라고 할 수 있다.

nosql

NoSQL의 종류

NoSQL에는 어떤 것들이 있는지 웹서핑을 해봤다. 결과는 다음과 같다.

various nosql

NoSQL의 종류에 대해서는 기본부터 알아보도록 하자.

  • NoSQL의 데이터 모델은 기본적으로 Key-Value Store 모델을 사용한다.

basic nosql model

기본 데이터 모델을 기준으로 각각의 Key-Value 관리 방법을 알아보면 다음과 같다.

  1. Key-Value Oriented
    – Value가 String, Integer, List, Hash 등의 기본 자료형인 경우이다
    key-value oriented
    – 이런 형식의 데이터 모델을 사용하는 경우를 Key-Value Oriented Database라고 한다.
    – 키에 대한 접근은 빠르지만 범위 검색에 대해서는 취약하다.
    – 이런 데이터 모델을 사용하는 DB로는 Redis, Memcached, Tokyo Cabinet  등이 있다.
  2. Ordered Key-Value Oriented
    – Key-Value Oriented 모델의 경우 범위 검색에 대해서 취약하다는 단점이 있다.
    – 만약 Key, Value를 정렬해놓는다면 범위 검색에 대한 단점을 어느정도 극복할 수 있다.
  3. Column Family Oriented
    – 하나의 Key에 하나의 Value만을 저장하는 단점을 극복했다.
    – 하나의 Key에 여러개의 Column을 저장한다.
    – Column-Value의 묶음을 Column Family라고 한다.
    column family oriented
    – 흔히 Column Oriented Database라고 하지만 Column Family Oriented Database라고 해야 한다. Column Oriented는 RDBMS에서 사용하는 데이터 모델 중 하나이다.
    – 보통은 Ordered Key-Value Oriented 모델을 사용한다. 다시 말하면 Key는 정렬되어 저장되고 Column도 Column Name별로 정렬되어 저장하는 모델을 사용한다.
    – 이런 데이터 모델을 사용하는 DB로는 HBase, Cassandra 등이 있다.
  4. Document Oriented
    – Value에 저장되는 값이 Document(JSON, XML 등)이다.
    document oriented
    – 이런 데이터 모델을 사용하는 DB로는 MongoDB, CouchDB 등이 있다.

NoSQL 데이터 모델링

RDBMS의 데이터 모델링과 NoSQL의 데이터 모델링을 비교하면 다음과 같다.
modeling

다음과 같은 기능을 구현한다고 가정한다.
modeling plan

NoSQL로 구현할 때의 모델링 절차를 살펴보면 다음과 같다.

  1. 데이터 분석
    – RDBMS도 모델링을 시작하기 위해서 데이터 분석을 해야 한다. 동일한 절차이지만 RDBMS와 NoSQL은 데이터에 대해서 서로 다른 시각으로 접근을 해야 한다.
    – RDBMS에서의 데이터 분석은 다음과 같다.
    modeling rdbms 1
    – 반면에 NoSQL의 데이터 분석은 다음과 같다.
    modeling nosql 1
    modeling nosql 2
    1) 게시판 내에서 게시글은 시간순으로 정렬되어야 함
    2) 게시글:내용 = 1:1
    3) 게시글:댓글 = 1:N
    4) 댓글은 게시글 내에서 시간순으로 정렬되어야 함
    5) “정렬”에 별표
    – RDBMS는 데이터의 관계에 집중해서 데이터 분석을 진행하는 반면에 NoSQL은 표현되는 데이터와 정렬되는 특징에 집중해서 분석을 진행한다.
  2. 쿼리 디자인
    – 데이터 분석을 마치면 NoSQL은 데이터의 특징을 고려해서 어떤 종류의 쿼리가 필요한지에 대해서 디자인한다.
    modeling nosql 3
  3. 테이블 디자인
    – 쿼리 디자인에서 2가지 방법을 디자인했다. 각각의 쿼리에 맞는 테이블을 디자인하면 다음과 같다.
    – 쿼리 1
    modeling nosql 4
    – 쿼리 2
    modeling nosql 5
    – 각 쿼리에 맞는 테이블을 디자인했을 때 적합한 NoSQL 모델은 Document Oriented, Column Family Oriented 라고 할 수 있다.

NoSQL 언제 사용하면 좋을까?

NoSQL에 대해서 조사해봤더니 다음과 같은 정보를 얻을 수 있었다.
nosql how1
역시나 다들 “빅데이터 처리는 NoSQL이야!”라고 하는 것 같다. 그러면 다른 유명한 업체의 사용 경험을 들어보도록 하자!

1. Twitter twitter logo
twitter use case

2. Tumblr tumblr logo
tumblr use case

3. EVERNOTEevernote logo
evernote use case

4. 결론
use case 1818

기대하는 결과가 나오지 않을 경우 질문을 바꿔보는 것도 좋은 방법이라 생각한다.

언제 NoSQL을 사용하면 안되나?

nosql when

(바쁜 사람들을 위한 친절한)요약

  1. RDBMS가 ACID라면 NoSQL는 BASE이다
  2. 분산 시스템에서는 Consistency, Availability, Partition Tolerance의 특징을 모두 가지는 것이 불가능하다
  3. NoSQL은 관계형 데이터 모델을 사용하지 않는 모든 Database 또는 Data Store를 말한다.
  4. NoSQL의 기본 데이터 모델은 Key-Value이다. Value의 형식에 따라서 Key-Value, Column Family Oriented, Document Oriented로 구분되기도 한다.
  5. 데이터 모델링에서 RDBMS는 테이블 디자인이 중요하지만 NoSQL은 쿼리 디자인이 중요하다.
  6. RDBMS는 테이블 디자인에 정규화를 하지만 NoSQL은 데이터 비정규화를 한다.
  7. 빅데이터 처리에 NoSQL이 꼭 필요한 것은 아니다.
  8. 유행을 무조건 따르지 말고 SQL, NoSQL이 무엇인지 알아보고 내가 다루려는 Data에 대해서 파악을 한 후에 사용해야 한다!

MySQL 클론의 역습 – 1 (MariaDB 편)

사실 이 글의 제목을 처음에는 “MySQL의 형제들” 이었다.

source가 fork된것이니 형제보다는 부모 자식 관계가 더 맞지 않을까 생각되서, “MySQL의 자식들”이라고 제목을 바꾸었다가 어감이 좋지 않아서 MySQL의 창시자가 자신의 첫째딸 이름을 따서 MySQL이라고 작명한 것에 착안해 “MySQL의 딸들”이라고 바꾸었다.

그런데, 그만 코드가 복제되서 다시 분화된 것인데 이것을 부모 자식간이라고 해야 하나 형제간이라고 해야 하나 쓸데없는 고민에 빠져버렸다.

결국, 장고 끝에 제목은 “MySQL 클론의 역습”이라고 결정했다. (그런데 실제로 MySQL과 클론들끼리 정말 싸우지는 않는다. 심지어 그들 간은 사이가 좋아 보이기 까지 한다.)

헛소리는 여기까지 하고 본문으로 들어가 보자. ^^;

우리나라에서 DB라고 하면 Oracle 아니면, MySQL이다. 특히 웹서비스 환경은 MySQL이 현재까지도 대세라고 할 수 있다.

최근들어 NoSQL이니 BigData니 하는 새로운 페러다임과 프로그램들이 등장하면서 광풍의 조짐이 보이고는 있지만, 여전히 사용함에 있어서는 제한적이고 진입장벽이 만만치가 않다.

아직까지 DB의 메인스트림은 RDBMS이고, 새로운 웹 프로젝트가 진행되면, 당연하듯 DBMS로는 MySQL이 거론되곤 한다.

사실 좀 지루했었다.

뭔가 MySQL이 아닌 새로운 것을 만지고 싶었을 뿐이었다.

그래서 어떤 프로젝트에서 Postfix를 도입해 볼까 하다가 MySQL에 익숙한 엔지니어들과 개발자들의 반대에 부딛혀야 했고,  본인 스스로도 딱히 그 프로젝트에서 Postfix를 써야 할 당위성을 찾기도 힘들어서 포기한적이 있다.

최근 모바일 게임 관련 프로젝트를 진행하면서 MySQL에서 fork된 몇가지 DBMS들을 만져볼 수 있게 되었다. 이해 당사자도 적고, 약간 도전적인 프로젝트이다 보니 아무런 태클 없이 혼자서 자유롭게 DBMS를 선택할 수 있는 기회였다.

이 글은  그 때 research 했던 MySQL fork program 들에 대한 간단한 소개 글이다.

MySQL이 Oracle에 편입된 후, MySQL의 향후 운명에 대한 우려의 목소리가 많아졌다.

이러한 우려 속에서 MySQL의 대안을 찾으려는 움직임이 많아지고 있는데, 그것들 중 대표적인 것으로 MySQL에서 fork된 프로젝트들을 꼽고 싶다.

이 글에서는 MySQL fork 프로젝트들 중 가장 많이 알려진 세가지 프로젝트에 대해서 정리 하려고 한다.

1. MariaDB

MariaDB 의 주요 개발자는 Michael Monty Widenius라는 사람으로 MySQL을 개발했던 사람이고, 그 MySQL을 Sun에 10억 달러(약 1조원)에 매각하면서 핀란드 10대 부자중 한 명이 된 사람이기도 하다.

하지만 MySQL을 인수했던 Sun이 다시 Oracle로 인수되자, Monty Program AB이라는 회사를 설립하고 MySQL의 소스를 기반으로 MySQL과 완벽하게 호환이 되는 DBMS를 개발 하는데, 이것이 MariaDB이다.

MySQL, MariaDB 둘 다 Monty의 딸 이름을 따서 만들었는데 MySQL은 첫째 딸, MariaDB는 둘째딸의 이름에서 따론 것이라고 한다.(딸바보인가보다)

MariaDB는 MySQL의 소스를 가져다 만들기도 했지만, 목표자체가 MySQL을 완벽하게 대체하는 것이다 보니, 기존 MySQL과 완벽하게 호환이 된다.

프로그램의 룩앤필도 거의 똑같고 지원하는 함수들도 모두 일치하며 심지어 파일 이름들도 그대로 MySQL의 것을 가져다 쓰고 있다.

개발자들이 그냥 보기에는 이게 MariaDB인지 MySQL인지 모를 정도이다. (Client의 프롬프트가 “MariaDB” 로 뜨는 것 말고는 정말 똑같다.)

당연히 php-mysql 이라던지, jdbc-mysql-connector같은 기존 db connection library도 그대로 사용할 수 있기 때문에 실제로 개발자들은 MySQL에서 MariaDB로 DB 서버가 바뀐다고 해도 전혀 소스코드 수정이 필요없으며, 추가적인 DBMS에 대한 학습도 거의 필요가 없다.

즉, MySQL을 다룰줄 아는 개발자라면 MariaDB의 진입장벽은 거의 없는 수준이라고 할 수 있다.

하지만, MySQL을 완벽하게 대체한다는 사실만으로 기존에 MySQL을 잘 사용하던 사람들이 막연한 불안감이나 새로운 프로그램에 대한 단순한 호기심만으로 MariaDB로 갈아타지는 않을 것이다.

그럼 MySQL 대신 MariaDB를 썼을 때 얻을 수 있는 잇점들은 어떤 것이 있을까?

첫번째 장점은 월등히(?) 빠른 쿼리 타임을 들 수 있다.

인터넷이 돌아다니는 다양한 퍼포먼스 테스트 결과를 보면 전반적인 쿼리 성능이 MySQL에 비해 좋은 것을 알 수 있다.

특히, sub query나 join query 같은 경우 따로 MariaDB의 특징으로 소개할 만큼 성능 향상이 있다.

그리고 본인이 직접 테스트한 결과에서는 Partitioning table에 대한 select 쿼리 결과가 특히 눈길을 끌었는데, 자세한 테스트한 결과는 따로 추가 글을 작성할 예정이다.

두번째 장점은 다양한 추가 기능들이다.

이 글에서는 다양한 추가 기능들중 몇가지만 소개하고자 한다.

1. Microseconds in MariaDB

테이블을 생성할 때 시간관련 자료형에 정밀도를 설정 할 수 있다.

CREATE TABLE example(

col_microsec DATETIME(6),

col_millisec TIME(3)

);

정밀도는 0부터 6까지 설정할 수 있으며, 설정된 값만큼의 microseconds가 출력된다.

SELECT CURTIME(4);

–>10:11:12.3456

2. Microseconds Precision Processlist

INFORMATION_SCHEMA.PROCESSLIST 테이블에 TIME_MS 컬럼이 추가 되었다.

processlist를 볼때 MySQL에서는 실행타임이 초단위까지 밖에 나오지 않았다면 MariaDB에서는 microseconds 단위까지 확인 할 수 있다.

3. Table Elimination

여러개의 table 조인으로 구성된 쿼리의 경우, 사용하기 편하기 view table을 따로 구성하기도 하는데, view table에서 특정 컬럼을 select할 경우 실제로 조인된 table들중 쿼리에 필요 없는 테이블이 발생할 수 있다.

MariaDB는 이런 경우 자동으로 쿼리에 필요 없는 테이블을 조인쿼리에서 제거해주는 기능을 가지고 있다. (이 특징은 성능 향상쪽에 가까운것 같기도 하다.)

4. Virtual Column

다음의 테이블 스키마를 보자.

create table table1 (

-> a int not null,

-> b varchar(32),

-> c int as (a mod 10) virtual,

-> d varchar(5) as (left(b,5)) persistent);

table1의 c 컬럼은 가상컬럼이다. 실제로 storage에 저장되지 않고 query 실행시간에 계산되어 출력된다.

table1의 d 컬럼은 실제로 storage에 저장이 되는 가상컬럼으로, insert나 update 때 계산되어 저장 되는 컬럼이다.

더 많은 추가 기능들이 있는데, 추가기능에 대한 설명은 여기에서 확인 할 수 있다.

한가지 주의할 점은 MariaDB의 추가 기능들을 사용할 경우 혹시라도 부득이하게 MySQL로 돌아가야 될 경우 호환이 안될 수도 있다는 점을 유의해야 한다.

마지막으로 MariaDB는 다양한 Storage Engine을 지원한다.

1. Aria

Aria 엔진은 MyISAM과 호환되면서 추가적으로 Transactional기능이 추가된 Engine이다.

2. XtraDB

InnoDB의 대체 Engine으로 다음에 설명할 Percona사에서 개발한 Storage Engine이다.

3. PBXT

일반적인 목적의 transactional storage engine으로 현재 더이상 maintaine 되지 않고 있어서 MariaDB에 기본 탑제되어 있지 않지만, 필요한 경우 재컴파일을 통해 사용할 수 있다.

4. FederatedX

Federated Storage Engine의 fork engine으로 Federated engine은 원격 서버의 table에 접근해서 Insert, Update, Delete, Select 를 할 수 있도록 해주는 engine이다.

5. OQGRAPH

Open Query Graph storage engine의 약자로 트리나 그래프 형태로 출력될 수 있도록 데이터를 저장하는 engine이다.

6. IBMDB2I

MySQL 5.1.55에서 빠졌던 엔진인데, MariaDB에서는 아직까지 지원하고 있다.

7. SphinxSE

Full Text Search Engine 으로 Full Text Search가 필요한 경우 사용할 수 있을 듯 하다.

8. Cassandra in MariaDB-10.0

NoSQL DBMS인 Cassandra cluster에 MariaDB를 통해 접근 할 수 있도록 10.0 버전에 추가되었다.

3가지 측면에서 MariaDB의 장점에 대해서 설명했는데, 개인적으로는 첫번째 장점인 성능 향상 만으로도 MariaDB를 쓰는 이유는 충분한 것 같다.

본인 입장에서는 추가 기능의 필요성은 아직까지 피부로 와닿지 않았고, 추후 MySQL이나 Percona로 전환해야 될지도 모르는 이슈 때문에 전혀 고려대상이 되지는 못했다.

MariaDB에 대한 소개는 여기까지 하고 다음 글에서는 Percona Server에 대해 이야기 하도록 하겠다.