Outsider's Dev Story

Stay Hungry. Stay Foolish. Don't Be Satisfied.
RetroTech 팟캐스트 44BITS 팟캐스트

NoSQL에 대해서 #2

이 포스팅은 NoSQL에 대해서 #1에서 이어진 포스팅입니다.



앞의 포스팅에서 언급했듯이 NoSQL은 생겨난 이유는 비슷하지만 각각 접근 방법은 다르기 때문에 수많은 NoSQL들을 다양한 기준에 따라 분류할 수 있습니다.

CAP 이론
Consistent - Available : Postgres, MySQL같은 전통적인 RBMS
Consistent - Partition Tolerant : BitTable, Hypertable, HBase, MongoDB, Terrastore, Redis, Scalaris, MemcacheDB, BerkeleyDB
Available - Partition Tolerant : Amazon Dynamo, Cassandra, CouchDB, Amazon SimpleDB, Riak



분산형과 비분산형
분산형 : Amazon Dynamo, Amazon S3, Scalaris, Voldemort, CouchDB, Riak, MongoDB, BigTable, Cassandra, HyperTable, HBase
비분산형 : Redis, Tokyo Tyrant, MemcacheDB, Amazon SimpleDB

분산형 데이터베이스는 확장성을 위한 Data Partitioning과 Availability를 위한 복제에 대한 책임을 가지고 있고 비 분산형은 클라이언트가 이 책임들을 가지고 있습니다. 주목할만한 분산모델은 Dynamo에서 사용되었지만 Voldemort, Riak, Cassandra에서 이 모델을 카피해서 사용하고 있으며 이질적인 하드웨어간에도 효과적입니다.



데이터 모델의 풍부함(Richness)
Key-Value Store : Amazon Dynamo, Amazon S3, Redis, Scalaris, Voldemort
Document Store :
Amazon SimpleDB, Apache CouchDB, MongoDB, Riak
Column Store :
Scssandra, Google BigTable, HBase, Hypertable

이 분류에서 한쪽 끝은 Key-Value Store이고 반대쪽은 가장 부유한 Column Store입니다. 이 두 사이에는 관계형데이터베이스의 사촌정도가 되는 Document Store가 위치하고 있고 Key-Value보다는 풍부하고 이해하기가 쉽습니다.


Disk와 Memory
Memory : Scalaris, Redis
Configurable :
BigTable, Cassandra, HBase, HyperTable
Disk : CouchDB, MongoDB, Riak, Voldemort

Scalaris는 완전한 메모리 기반이고 Redis는 메모리주도적입니다. Configurable에 분류에 포함된 데이터베이스들은 많은 컨트롤을 제공하기 위해 얼마나 큰 메모리를 얻을 것인지를 설정할 수 있으며 Disk의 범주에 있는 CouchDB, MongoDB, Riak은 on-disk B+ Tree를 사용하며 Voldemort는 BDB와 MySQL을 사용하고 있습니다.






데이터 모델의 방식에 따라 주요한  NoSQL위주로 특징들을 정리했습니다.

Key-Value Store
Key-Value Store는 가장 간단하게 가능한 데이터 모델을 제공합니다. 범위쿼리는 데이터베이스에서 명백하게 지원하지 않는다면 쉽지 않습니다. 그리고 Key-Value Store상에서의 애플리케이션 모델링은 복잡성을 가질 수 있습니다.

Amazon Dynamo

  • 분산형 Key-Value Store로 값이 시스템에 불투명합니다. 타겟 오브젝트는 보통 1MB 미만으로 Amazon내부에서 사용되고 있고 외부에서는 직접 이용할 수 없습니다.
  • 일관성 해싱을 사용해서 Partitioning을 합니다.
  • 복제 - 데이터는 다중호스트에 복제됩니다.
  • 일관성 - 업데이트는 비동기적으로 복제는 전파하기 때문에 모델은 결국 일관성을 가집니다.



Amazon S3

  • 분산형 Key-Object Store로 오브젝트는 시스템에 불투명합니다. 각 오브젝트의 사이즈는 1byte ~ 5GB의 범위내에 있으며 오브젝트의 갯수는 제한이 없는 무제한 스토리지 입니다. 오브젝트는 Amazon 데이터센터 내에서 유지가 되며 오브젝트의 위치에 대한 GEO를 결정하며 저장되는 오브젝트가 크면 유용합니다.
  • 일관성 : 새로운 PUT에서 Read Your Write1를 이루고 PUT과 DELETE를 덮어써서 결과적인 일관성을 가집니다.





Document Store
Document Store는 Key-Value Store보다 한걸음 더 나아간 구조입니다. 스키마가 테이블의 형태보다 먼저 정의되어야 하는 관계형 데이터베이스와는 달라서 각 도큐먼트는 다른 스키마를 가질 수 있습니다. 그러면서도 관계형 데이터베이스처럼 레코드간의 관계를 설명하는 것이 가능합니다. 이 먼저 정의해야하는 스키마를 제외하고는 개념적으로 관계형 데이터베이스와 아주 유사합니다.

Amazon SimpleDB

  • Erlang으로 작성되었습니다.
  • 데이터는 관계된 데이터를 함께 보관하기 위한 컨테이너로써의 도메인과 도메인으로 연결하기 위한 엔티티, 아이템의 프로퍼티로써 속성과 그 값으로 모델되었습니다.
  • 기본적으로 각 아이템은 속성을 언제나 추가/삭제 가능한 Dictionary입니다.
  • 아이템이 추가될 때 속성에 기반하여 인덱스됩니다.
  • 결과적인 일관성을 갖습니다.
  • 파티셔닝 : 도메인 - 아이템 - 어트리뷰트 모델은 각 도메인의 사이즈와 도메딩당 속성의 갯수 및 도메인의 갯수에 대한 제한을 갖는다. 그러므로 확장을 위해서는 데이터를 수동으로 파티션해야 합니다.



Apache CouchDB

  • Erlang로 작성되었습니다.
  • 데이터와 스토리지 모델 :
    • 레코드는 JSON스트링(도큐먼트)의 형식으로 직렬화됩며 각 도큐먼트는 유니크한 DocId를 같습니다.
    • B+트리를 사용하면 커밋된 데이터는 결코 덮어써지지 않고 오직 오퍼레이션만 추가합니다.
    • Append only 모델로 Read가 다중버전의 동시성 제어를 사용해서 수행됩니다.
      쓰기는 동시에 작성가능한 Blob외에는 직렬화됩니다.
    • 같은 데이터를 위한 다중 뷰를 가질 수 있습니다.
    • Design Document라고 부르는 도큐먼트의 특별한 타입에서 갑에 키를 매핑하는 Javascript함수를 사용하도록 정의되었습니다.
  • View함수는 View를 쿼리했을 때 실행되며 기본적으로 Map 함수와 Reduce 함수가 존재합니다.
  • 복제 : 다중마스터를 지원하는 마스터 슬레이브를 갖으며 오직 최신 리비전만 복제가 됩니다.
  • 멀티마스터에서의 충돌(Conflict) 핸들링 : 충돌을 탐지하고 winner를 선택하기 위해 결정론적인 알고리즘을 사용하며 여기서 winner는 기대한 것일수도 아닐 수도 있기 때문에 아닐 경우에는 애플리케이션에서 스스로 고쳐야 합니다.
  • Partitioning과 로드 밸런싱 - CouchDB Lounge에 의해서 제공됩니다.
  • Apache 2.0 라이센스를 따릅니다.



MongoDB

  • C++로 작성되었습니다.
  • 데이터 모델
    • 컬렉션 - Amazon SimpleDB의 도메인과 유사하며 비슷한 도큐먼트들을 함께 두기 위한 Bucket입니다.
    • Key-Value는 바이너리 직렬화된 JSON(BSON - Binary Serialized JSON)입니다.
    • 한 BSON 객체는 4MB 제한이 있습니다.
    • 큰 객체는 GridFS를 통해 지원하고 있습니다.
    • 인덱스를 위해서 B-Tree가 사용되며 필드를 파라미터로 받는 db.things.ensureIndex()함수를 사용해서 인덱스에서 필드를 열거합니다.
  • 스토리지
    • in-Place 업데이트입니다.
    • 부분적인 업데이트를 제공하기 때문에 전체 로우를 보내지 않고 값을 업데이트 할 수 있습니다.
    • Forward-only 커서를 지원합니다.
    • 단일 도큐먼트 원자적 업데이트를 지원합니다. 원자적인 배치 업데이트는 db.eval()을 통해서 가능하지만 파티션된 데이터는 지원안할 수도 있습니다.
  • 쿼리
    • 도큐먼트 내부에서 값을 선택하기 위한 Syntax기반의 JSON 스타일을 제공합니다.
    • 상황적인 Operator와 정규식 등을 지원합니다.
    • Forward-only 커서를 지원합니다.
    • 쿼리 옵티마이징은 다중 쿼리플랜을 시도하고 가장 잘 동작하는 것을 선택하는 형식입니다.
  • 배치 오퍼레이션 : 컬렉션에 Map-Reduce를 지원합니다.
  • 복제 : 마스터-슬레이브 보델로 자동적으로 마스터와 슬레이브의 역할을 이해하는 복제쌍(replica pair)입니다.
  • Partitioning
    • 알파스테이지에서 파티셔닝 됩니다.
    • 파편(Shards)는 Chunk라고 불리는 유닛에서 데이터를 다루며 Chunk는 최대 50MB의 컬렉션으루부터 인접하는 범위의 데이터입니다.
    • 데이터는 하나의 Shard에서 Chunk안의 다른 Shard로 마이그레이션 됩니다.
  • AGPL 3.0 라이센스를 따릅니다.





Column Store

BigTable

  • 구글에서 내부적으로 사용하면 Google App Engine를 통해서 공개됩니다.
    Block를 짓습니다.
    • Google File System를 사용하여 분산 파일시스템과 Raw 스토리지를 제공합니다. 청크서버가 청크를 저장할 책임을 가지고 있으며 각 청크는 안전을 위해 3개의 머신에 복제가 됩니다. 데이터전송은 클라이언트와 청크서버 사이에서 직접 발생합니다.
    • 스토리지 파일 포맷은 정렬된 스트링 테이블로 SSTable로 불립니다.
    • 스케쥴러는 메선에서 스케쥴 잡으로 제공됩니다.
    • 분산된 Lock과 파일, 네임 매니저로 Chubby 서비스를 사용한다.

  • 데이터 모델은 Map의 Map인 다차원 Map입니다. 데이터는 테이블로 조직화되고 테이블은 관계된 데이터를 가진 엔티티입니다.
  • Write : Write 요청이 타블렛 서버에 도달했을 때 잘 규격화 되었는지와 권한을 확인하며 유효한 변경은 커밋로그에 작성됩니다.
  • Read : Write요청과 비슷한 확인을 하며 SSTable의 순서와 Memtable의 합쳐진 View에서 실행됩니다.



Cassandra

  • BigTable의 컬럼패밀리(Column-family) 데이터 모델과 Dynamo의 분산 아키텍쳐를 합쳤습니다.
  • Java로 작성되었습니다.
  • 데이터 모델
    • BigTable같은 키에 의해 인덱스되는 다차원 맵을 사용하며 각 애클리케이션은 BigTable에서 테이블같은 Key-Space를 만듭니다. Key는 레코드를 위한 이름이고 Column은 레코드의 속성이며 타임스템프가 찍힙니다. Column-family는 컴럼의 그룹핑으로 관계형 테이블과 유사하고 Super-Column은 컬림들의 리스트입니다.
    • 소팅은 데이터의 쓰여진 시간으로 정렬되되며 컬럼들은 컬럼의 이름으로 Row내에서 정렬됩니다.
  • Partitioning : Dynamo와 유사하며 순서가 보장된 햄쉬함수를 사용하는 일관된 해시를 사용하고 Dynamo와는 다른 로드밸런싱을 위해소 Chord 접근을 사용합니다.
  • 복제 : Dynamo의 조정자 노트와 선호리스트의 건셉과 같으며 Datacenter aware Rack aware, Rack unaware같은 다양한 보제 정책들을 가지고 있습니다.
  • 퍼시스턴스 : 로컬파일 시스템에 의지하며 스토리지 구조와 접근방식은 BigTable과 유사합니다.
  • Write : Memtable에 대한 업데이트를 따르는 내구성과 복구를 위한 커밋로그를 쓰는 Bigtable의 접근과 유사하며 커밋로그를 위한 각 머신의 전용디스크는 Write를 순차적으로 만들어 쓰루풋을 최대화 합니다.
  • Read : 제공될 노드와 Read-repair를 찾는 Dynamo와 유사한 접근방식을 사용하며 스토리지 레벨에서의 접근은 BigTable과 유사한 Memtable + SSTable 시퀀스로부터 읽습니다.
    라이센스는 Apache 2를 따릅니다.
  1. Read-Your-Writes(RYW) 일관성은 레코드가 업데이트 되었을때 그 레코드에 대한 읽기시도는 업데이트된 값을 돌려주는 것을 보장해주는 것의 의미합니다. [Back]
2010/09/18 23:59 2010/09/18 23:59