Cassandra DBMS 에 대하여

플랫폼, 서비스 등 다양한 모습으로 존재하는 Computing 환경은 그 대상이 되는 Data 를 기반으로 하고 있습니다. 주로 Data 는 DBMS (DataBase Management System) 에 의해 관리되며 대부분의 설계자/개발자는 이러한 DBMS가 해줄 수 있는 것, 또 가지고 있는 문제를 어떻게 해결해 줄 수 있는가에 따라 많은 수고를 덜게 됩니다.

따라서 DBMS 를 활용하기로 했다면 그것이 무엇을 해줄 수 있고 우리가 가진 문제를 어떻게 또 어느 정도까지 해결해 줄 수 있는가? 에 초점을 두게 될 것입니다.

아마도 개발자 특히 응용 소프트웨어 개발자라면 RDBMS(Relational DBMS) 에 익숙할 것입니다. MySQL, Oracle, MSSQL 등이 대표적일 텐데요. 아시다시피 정말 많은일을 해줍니다. 자료만 넣어놓으면 거의 대부분의 일을 할 수 있으니까요. “어떻게”라는 고민을 무색하게 해줍니다.

하지만 요즘 우리가 가진 문제는 조금더 복잡하고 다양한 경우가 많습니다. 대표적인걸 적어 보면 다음과 같겠네요.

  • 대용량 데이터의 저장과 처리가 가능해야 하며 대용량이라고 해서 점점느려지면 안됨
  • 실제 서비스 중인 환경에 추가로 서버를 붙이면 저장 공간이 커지고 따라서 처리 성능 또한 분산되어 유지보수 비용을 줄임
  • 혹시 서버가 다운되거나 디스크가 망가져도 데이터 유실이나 서비스에 영향을 주면 안됨
  • 우리가 살고 있는 환경에서 모든 개체(Object) 가 모두 같은 기준의 속성으로 바라보기 힘든 경우가 있다. 즉 개체의 개성이 중시되는 경우가 있음
  • 서비스, 플랫폼이 진화하면서 스키마가 바뀌게 되는데 스키마를 기반으로 Constraints 를 구성하고 무결성을 유지하는 RDBMS 의 경우 유연하지 못함
  • Relation 모델의 Table, Tuple 규칙이 모든 처리 환경에 있어서 최적은 아니다. 예를 들어 문서 구조, 그래프 구조를 이용하면 더욱 좋을 환경이 있음

위의 문제에 대해 RDBMS 는 엄격한 규칙을 가지고 그 규칙하에서의 처리 환경을 가지기 위해 다양한 기능 요소(예: 캐싱, 독립된 클러스터링 환경)를 구현하고 있습니다.

또한 모든 데이터는 Relation 이라는 틀 속에 구현되어야 하기 때문에 데이터의 분산 및 처리를 구현하기가 쉽지 않습니다. 쉽지 않은 것 중 대표적으로 JOIN, 다양한 구간 및 조건하에서의 복합 질의 등이 있습니다.

RDBMS 가 할 수 있는 모든걸 원하진 않지만 위와 같은 다양한 문제의 해결이 더욱 중요한 경우 바로 NoSQL(Not SQL) 또는 NRDBMS(Not-RDBMS) 계열의 DBMS 를 이용합니다.

이러한 DBMS 는 RDBMS 처럼 일반적 목적을 태생의 배경으로 하고 있지 않기에 각기 다른 특징을 가집니다. 대표적인걸 보면 다음과 같습니다.

  • Document-Oriented DBMS : 문서를 속성화 하고 문서의 내용(속성)을 다양하게 접근하기 위한 방법(예: Secondary Index)을 제공 (MongoDB, OrientDB, CouchDB …)
  • Key-Value Based DBMS : DHT(Dynamic Hash Table)의 키와 값을 저장하고 이를 접근하기 위한 방법을 제공 (Cassandra, Amazon Dynamo …)
  • Graph DBMS : 개체(Node, Vertex)와 그에 대한 연결(Edge) 를 기반으로 하며 Semantic Web DBMS 들이 주류를 이룸, 개체(Node, Vertex)간 Traverse 제공 (Neo4j, OrientDB, GraphDB, Bigdata, …)

자 여기서 저는 DHT 기반의 Cassandra 를 소개할까 합니다. 기대되시죠?^^

1. Cassandra 는 무엇일까요?

앞서 언급한대로 Cassandra 는 Key-Value 구조의 DBMS 입니다. Amazon 의 Dynamo (Amazon 의 고객 정보, 상품 정보를 저장하고 처리하는 대용량 처리 환경)을 디자인 한 사람 중 한명인 Avinash Lakshman (현재는 Facebook 의 infrastructure 를 담당)과 Facebook 의 Prashant Malik 가 최초 만들었고 Facebook 에 적용해서 쓰다가 2008년 Google Code 를 통해 오픈 소스로 배포되었고 많은 사람들에 의해 몇가지 요구에 의한 단순한 DBMS 에서 보다 다양한 요구사항을 포함하는 형태로 진화하는 계기가 됩니다.

2009년 3월 아파치의 인큐베이터 프로젝트가 되었고 불과 1년만인 2010년 2월 Top-level 아파치 프로젝트가 되었습니다.

Amazon 의 Dynamo 의 특정인 Hash 알고리즘을 이용한 Key-Value 스토리지, Eventual Consistency (아래에서 따로 설명) 구조를 가지고 있으면서 논리 구조로 Google 의 Bigtable 구조인 계층적 Column 구조를 배경으로 하고 있습니다.

2008년 초 소스 공개 이후 오픈 소스로 개발되다 보니 빠른 기능 추가, 문제 해결, 개선이 이루어 지지만 반대로 이로 인한 문제점 파악이 최신 버전을 기준으로 느리다/잠재되어 있다는 단점이 있습니다. 따라서 Cassandra 를 실제 환경에서 이용한다면 해당 버전이 어느 정도 안정화 단계에 들었을 때 그 버전을 이용하는게 좋습니다.

2. 어떨때 쓸까요?

Cassandra 는 대용량 자료의 저장과 처리를 목적으로 하며 높은 가용성을 가지게 합니다. 주요 특징은 다음과 같습니다.

  • 토큰링을 배경으로 Key 구간 설정으로 서버(노드)의 추가 및 제거만으로 전체 저장 공간이 유연하게 확장/축소 됩니다.
  • 다른 서버(노드)에 데이터 복제본을 구성하여 특정 노드 장애시에도 서비스에 영향을 주지 않고 데이터 유실되지 않도록 합니다.
  • Key-Value 구조로 Hash 알고리즘을 통한 O(1) 접근으로 빠른 엑세스 성능을 보여줍니다.
  • Write(수정/추가/삭제)시 실제 스토리지 구조에 적용하기 전 CommitLog 에 변경사항을 먼저 기록하므로 빠른 성능을 보입니다.(MySQL 대비 8~15 배)
  • RDBMS 의 엄격한 Schema 를 적용하지 않습니다. (Row 마다 속성을 다르게 정의 가능)
  • RDBMS 에서 제공하는 산술/자료 처리 함 수들을 모두 지원하지는 않습니다. (현재 극히 일부만 제공, 점진적 확장)
  • RDBMS 에서 사전에 정의해 놓은 Entity 에 대한 JOIN 을 지원하지 않습니다. (응용 환경에서 구현해야 함)
  • 특이하게도 1차 인덱스는 Column Family 의 Column 이름을 기반으로 합니다. (2차 인덱스는 Column 의 Value)
  • RDBMS 처럼 주요 접근에 대해 Order by 를 수행 할 경우 수행 시점에서 정렬이 이루어 지지만 Cassandra 의 경우 사전 정해진 인덱스(1차 à Column 명, 2차 à Column 값)에 대해서만 수행 가능
  • 데이터 전송 프로토콜로 Thrift 를 이용합니다. Thrift 는 Facebook 에서 시작된 프로젝트인데 Cross-Language 를 지원합니다. 사실상 언어에 의존성 없이 모든 환경에서 이용가능합니다.
  • 물리 파일 저장 구조로 SSTable 을 사용합니다. SSTable 은 구글에서 제안한 것으로 Bigtable 의 구조 형태로 데이터를 저장하고 있습니다. Sorted String Table 의 약자인 만큼 물리 파일 저장 구조 자체가 1차 정렬 조건에 맟추어 사전 정렬된 형태를 유지하게 됩니다.(Cassandra 의 경우 CF 의 Column 의 이름)\따라서 대용량의 데이터를 저장하고 처리해야 하고 정렬에 활용되는 속성이 제한되며 데이터 변경이 잦은 경우(예: 메일 및 쪽지의 Inbox)가 사용하기 가장 좋은 환경이라 볼 수 있습니다.(본래 Cassandra 는 Facebook 의 Inbox 처리 문제에서 시작함)

3. 자료는 어떻게 저장하고 처리하나요?

어떻게 저장하고 처리하는지를 얘기하기에 앞서 논리, 물리 구조를 잠시 보겠습니다.
A. 논리 스토리지 구조
카산드라의 논리 스토리지 구조
“Column” 은 name(이름), value(값), timestamp(시간) 을 가지고 있습니다.
“Column Family” (타입이 같은 Column 의 모임, 이하 CF) 은 RDBMS 의 Relation(비공식: Table) 과 비슷한 의미를 가지고 있습니다. 특이하게도 CF 는 바로 Column 을 하위 구조로 가질 수도 있고 Column 의 모임인 Super Column 을 하위 구조로 가질 수 있습니다.

“Keyspace” 는 CF의 모임입니다. 예를 들자면 “사람”, “음악” 이 Keyspace 고 사람 또는 음악이 가지는 다양한 특징을 구분지어 놓으면 CF 가 되는 것이지요.

“Cluster” 는 최상위 개념으로 이러한 Keyspace 의 모임입니다.

B. 물리 스토리지 구조

카산드라 물리 스토리지 구조
Node (노드)라는 개념이 하나의 서버에서 구동되고 있는 Cassandra 서버 프로세스 하나가 바로 Node 입니다. (하나의 서버에서 여러 노드를 구현도 가능하지만 필요가 있을지는 모르겠군요. 서버를 안사주나요?ㅎ)

위의 구조는 Seoul에 있는 데이터 센터에 2개, Busan에 있는 데이터 센터에 2개의 노드가 있습니다. 이렇게 묶어서 실제 논리 스토리지에서는 Cluster 라는 확장(가상) 공간으로 사용하는 것이지요.

C. 어떻게 데이터를 저장하고 있을까요?

카산드라 토큰링

위와 같이 Token ring(0~2^127 의 자연수로 구성) 을 구성하고 노드 수에 따라 구간을 나눔니다. 이후 데이터의 키를 해싱(보통 MD5)하여 해싱된 값을 바탕으로 어느 노드에 데이터가 위치할 지를 결정합니다. 사전에 노드간에 자신의 영역을 결정하고 적용하기 때문에 해싱된 데이터가 어느 위치에 있을지를 결정하는 것은 아주 쉽습니다. (Hashing 에 들어가는 비용과 구간 결정 비용만 존재)

따라서 Data 가 입력되고 Data 의 Key 가 해싱 후 Node 1 구간에 있을 때 위의 그림과 같이 Node 1 에 실제 데이터가 저장되게 됩니다. Partitioner 를 Random 으로 한 경우 실제 키의 값하고는 상관없이 Random 으로 Node 별로 위치하게 됩니다. Order 방식으로 한 경우 키를 중심으로 일정 크기만큼 하나의 노드에 위치하게 됩니다. (하지만 Node 추가/삭제 등에 비효율적임)

이후 복제본 구성을 위한 정책(기본 설정은 옆 노드에 저장)에 따라 저장되는 노드 위치가 다르게 되고 저장/조회시 Consistency 레벨에 따라 저장 시점 및 복구 시점이 달라지게 됩니다.

위의 그림은 기본 설정일 때로 Node 1 에 저장된 값이 저장 Consistency 가 QUORUM (기본, N/2+1 노드에 처리가 완료되어야 성공)으로 설정된 경우 옆 노드인 Node 2에 복제본이 저장되게 됩니다. (Node 4의 옆 노드는 Node 1)

D. 무결성은 어떻게 유지 하나요?

RDBMS 의 경우 ACID 를 보장해야 하기 때문에 엄격한 Constraints (제약 조건)을 적용합니다. 성능저하의 대표적 이유이기도 하지요. 하지만 Cassandra 와 같은 NoSQL 의 경우 보통 CAP(Brewer의 이론) 로 무결성 유지에 대한 판단을 합니다.

  • C : Consistency (무결성)
  • A : Availability (가용성)
  • P : Partition tolerance (분할에 대한 내구성 à 분할 처리)

보통 이 중 2가지를 만족하고 1가지는 상황에 의해 만족하게 됩니다. Cassandra 의 경우 AP 를 만족합니다. C의 경우 Eventual Consistency 에 의해 만족하게 됩니다. 즉 노드 구성 및 읽고 쓸때의 Consistency 판단에 따라 달라집니다.

Eventual Consistency 는 성능을 중시하기 위해 낙관적 기대에 의해 무결성을 유지하게 됩니다. 이름에서 보여지지만 결국은 무결성을 유지한다는 것이지요. Cassandra 는 쓸 때 읽을 때 각각 Consistency 레벨을 부여합니다.

  • T : 전체 노드수
  • N : 현재 데이터와 관련된 노드수
  • W : 정상적으로 Write 되어야 하는 노드 수
  • R : 정상적으로 Read 되어야 하는 노드 수

W+R > N 일 때 무결성이 유지됨

수식과 조건이 들어가니 어려워 보이시죠?^^ 하지만 생각하면 쉽습니다.

3개의 노드가 있다고 할 때 2개의 노드에 정상인 데이터가 저장되어야 한다고 조건을 세우고 쓰는 시점에 정상적으로 완료되었다고 해봅니다. 이후 읽어낼 때도 2개의 노드에 저장된 복제본을 정상적으로 읽을 수 있고 두 복제본이 같다면 이는 정상인 데이터라고 판단하는 것입니다.

만일 2개를 정상적으로 썻는데 읽어낸 데이터가 다르다면 둘 중 어떤게 진짜인지는 정확히 알 수가 없게 됩니다. (timestamp 속성을 가지지만 완전하다 보기는 힘든, 노드별 시간차도 존재)

반대로 쓸 때 2개의 노드에 정확히 써졌어야 했지만 그렇게 되지 못한 경우는 이후 데이터가 정상인지를 판별할 수 없게 됩니다. 따라서 다음과 같이 볼 수도 있습니다.

N/2 + 1 만큼의 노드에 정상적인 데이터를 쓰고 읽는 시점에서 N/2 이상의 데이터가 같으면 무결성이 유지된다고 볼 수 있습니다. (만일 N/2는 모두 같은데 마지막 1개가 다른 경우 다른 값들이 맞다고 보고 이를 복구)

E. 캐싱은 어떻게 지원하나요?

각 CF 마다 Row Cache 와 Key Cache 를 설정 할 수 있습니다. Row Cache 는 실제 데이터를 메모리에 적재해놓는 것을 의미하고 Key Cache 는 Key 를 캐싱해 놓는 것을 의미합니다. 0.8 이후 부터는 캐싱된 데이터에 대한 LifeCycle 을 관리하기 시작했습니다.

가장 기본적인 형태로 캐싱을 지원하는데요. Hit 되면 주고 없으면 가져다 놓습니다. (Max 로 설정된 값까지)

4. 어떻게 사용하나요?


A. 설계는 어떻게?

먼저 Keyspace 에 대한 설계를 합니다. 실 세계에서 상위 개체 단위가 바로 이 구분의 기준이 됩니다. 예를 들어 다음과 같은 블로그를 Cassandra 로 설계 해 봅시다.

  • 단순한 하나의 블로그
  • 모든 게시물은 “제목”, “내용”, “날짜” 를 가짐
  • 여러명의 Author 가 있을 수 있음
  • 모든 게시물은 특정 태깅이 되어 있으며 태그가 지정되지 않은 경우 __NoTag__ 라는 태그로 태깅
  • Author 이외의 모든 사람들이 Comment 를 게시물에 대해 남길 수 있음
  • 모든 게시물은 시간에 대해 반정렬 순서로 보여짐
  • 태그 안의 모든 게시물은 시간에 대해 반정렬 순서로 보여짐

이 블로그에서 Keyspace 단위로 구분 될 수 있는 건 “블로그 게시물”, “Author” 일 것입니다.

즉 각각의 Keyspace 에 블로그 게시물 및 Comment 에 대한 내용, 작성자에 대한 정보가 담겨 있게 됩니다.

카산드라로 단순 블로그를 설계

BlogEntries 에는 블로그 게시물의 내용이 담겨 있습니다. 작성자의 키(Key), 제목, 내용, 태그, 등록일이 Column 으로 구성되어 있습니다. (JSON 형태로 보면 다음과 같습니다.), 카산드라는 해싱 알고리즘을 통한 Key 접근을 하고 이후 1차 인덱스로 구성된 인 CF 의 Row Key 를 접근합니다. (이 Index 의 경우 순서를 가짐), 마지막으로 2차 인덱스를 통해 각 Row 의 Column 의 값을 기준으로 Sort 를 할 수 있습니다. (버전 0.7 이상)

<!– Keyspace : Blog
ColumnFamily: BlogEntries // 일반 CF
BlogEntries : { // CF
“Blog_Key_1″ : { // Columns (Row) & Their Row key (1차 인덱스)
title: “Test Title”, // Column
content: “테스트가 어쩌고 저쩌고…”,
author: “김C“, // Authors CF 의 key
tags: “Test,김C”, // 콤마로 구분된 태그 리스트
regDate: “1024152313″ // 등록 날짜(Timestamp)
},
“Blog_Key_2″ : {

},

}
–>

또한 작성자는 별도의 Keyspace 로 구성되어 있으며 다음과 같은 구성으로 되어 있습니다. 게시물 수, 트위터 정보, 위치 정보를 담고 있습니다. 같은 이름의 Column 의 값들을 모아 2차 인덱스(보조 인덱스, Secondary Index, 버전 0.7 이상)를 구성할 수도 있습니다.

<!—
Keyspace : Authors
ColumnFamily: Authors // 일반 CF
Authors : { // CF
김C” : { // Columns (Row) & Their Row key
numOfPosts: 91,
twitter: “kimC@twitter”,
location: “Seoul” // 2차 인덱스를 구성하여 나중에 Seoul 에 사는 사람을 조회
},
“someone” {

}
}
–>

실제 이용자는 리스트 형태로 볼 것입니다. 반순서의 시간 기준이 정렬 조건일 것이구요. 또한 이러한 리스트는 각각의 태그별로 보기도 하고 전체 리스트를 보기도 합니다. 이러한 리스트 View 를 저장하는 CF 를 구성합니다. 또한 키만 가지고 있게 되며 실제 게시물 내용은 BlogEntries 에서 가져옵니다.

<!–
Keyspace : Blog
ColumnFamily: TaggedPosts
TaggedPosts : { // CF
test : { // 태그명
{time_uid_1} : “Blog_Key_1“,
{time_uid_2} : “Blog_Key_2″,
},
all : { // 전체 게시물
{time_uid_1} : “Blog_Key_1″,
{time_uid_2} : “Blog_Key_2″,
{time_uid_3} : “Blog_Key_3″,
},
__NoTag__ : { // 태그가 없는 게시물
{time_uid_3} : “Blog_Key_3″,
}
}
–>

여기서 중요한 점은 {time_uuid_1} 이라는 Column 의 이름으로 사전 정렬 되어 있게 된다는 점입니다. 보시면 아시다시피 각각의 태그에 대해 모든 게시물을 저장해 놓았습니다. RDBMS 와는 달리 완전히 반정규화 된 형태이지요. 게시물 하나를 쓰게 되면 BlogEnties 에 쓰고, TaggedPosts 에도 2개의 Row 를 써야 합니다. (전체, 해당 태그)

마지막으로 댓글 CF 를 구성합니다. 하나의 게시물에 대해 다양한 댓글이 담길 수 있으므로 2차원 CF 를 사용해야 합니다. (각각의 게시물에 대해 여러 개의 Row 를 가짐) 마찬가지로 SSTable 에 사전 정렬된 형태로 저장됩니다. (기준은 Super Column 의 이름)

<!–
ColumnFamily: Comments
게시물에 대한 Comment 데이터를 저장
Comments : {
“Blog_Key_1″ : { // Key
{time_uid_1} : { // Super Column (사전 정렬 기준)
commenter: “윤은혜”,
email: “eh@paran.com”,
comment: “오빠 왜케 잼없어요”
},
{time_uid_1} : {
commenter: “춘자”,
email: “cj@nate.com”,
comment: “나는 오빠가 좋던데”
},
},

}
–>

위의 CF 들을 통해 아주 간단한 Blog 를 만들어 보았습니다. “다소 복잡해 보이고 비효율적인 처리를 해야 하는 구나” 라는 의문을 가지실 수도 있겠습니다. 하지만 실제 데이터를 보이는 중심으로 미리 저장해 놓는다는 점과 Write 속도가 빠르다는 점을 기준으로 RDBMS 와의 차이를 요구사항에 비추어 검토해보면 좋습니다. (RDBMS 는 Read 속도를 증가시키기 위해 다양한 캐싱 매커니즘 이용, Write 속도는 떨어짐, 예를 들면 일반 블로그는 RDBMS 가 좋겠지요. Read 가 절대적이니 만큼, 하지만 실시간으로 짧은 메시지를 등록하고 공유할 때에는 Cassandra 가 좋습니다. à Twitter)

B. 자료 처리는? 또 DBMS 가 해줄 수 있는 것들은?

현재는 기본 CRUD 와 집계는 Column Count 만 지원 (앞으로 다양해질 예정)

Read 의 경우 Column 의 이름으로 구성된 1차 인덱스, 사전에 정의된 Column Value 로 구성된 2차 인덱스에 의해서만 정렬이 가능하며 해당 인덱스에 대해 Range 를 설정하고 가져옴 (예: 특정 값을 포함하여 그 이상의 값을 가진 데이터 10개를 가져옴)

RDBMS 의 Sequential 속성이 최근 추가되었습니다.(0.8) 즉 기존에는 Cassandra DBMS 에서 읽어온 후 가감을 하고 다시 저장해야 했지만 현재는 가감을 DBMS 에 요청하면 되는 것이지요.

C. 운영은 어떻게?

Cassandra 는 nodetool 과 clustertool 을 제공(0.8 에서 제거)하며 이 툴은 다음과 같은 명령어(기능)을 제공합니다.

  • move : 실제 운영 도중 하나의 노드에 있는 모든 데이터를 다른 노드로 이전합니다. 이전을 위해 0.7 버전 이하에서는 anti-compact 를 수행하고 데이터를 스트림으로 다른 노드로 복사 합니다. 이후 복사가 완료되면 소스 노드는 클러스터에서 빠지게 됩니다.(decommission + bootrap)
  • removetoken : 클러스터에서 노드를 제거합니다. 제거시 해당 노드의 데이터를 다른 노드로 전송하지는 않습니다. 즉 다른 노드에 복사본이 있다면 그것으로 서비스를 하게 됩니다.
  • cleanup : 해당 노드에 할당된 키영역을 제외한 불필요 데이터를 정리합니다. 노드 추가에 의한 분할 등을 수행하고 난 후 다른 노드로 이동된 데이터를 보통 정리(삭제)하지 않는데 이 경우 읽는 시점에서 충돌이 발생하기도 합니다.
  • bootstrap : 새로운 노드가 추가 될 경우 해당 노드를 활성화 하기 위한 과정을 bootstrap 이라 합니다. 즉 새로운 노드가 추가된 경우 자동으로 수행되거나 (옵션에 따라) 이 명령어를 통해 진행되기도 합니다. 이 명령어가 실행되면 전체 데이터 중 새로운 노드에 할당될 영역을 정하게 되고 다른 노드에 통보하게 됩니다. 그러면 모든 노드는 자신이 가져야할 데이터가 아닌 부분을 때어내어 각각의 노드에 스트림으로 전송합니다. 이 과정 동안에 새 노드는 클러스터에 참여하지 않습니다. 이 과정이 종료되면 결국 새로운 노드에는 자신의 영역에 할당되어야 할 데이터를 다른 노드들에게서 받아 놓은 상태가 됩니다. 이 과정은 실시간으로 이루어 집니다.(노드들이 데이터를 전송하는 과정, 전송 후에도 실제 서비스는 유지 됩니다. 또 전송 후에 불필요 데이터를 삭제하지는 않습니다 à cleanup 을 통해 정리) 전송 과정이 끝나면 새로운 노드를 클러스터에 추가하고 서비스를 개시합니다.
  • decommission : removetoken 과 유사하게 클러스터에서 해당 노드를 제거합니다. 하지만 다른점은 제거되기 전에 자신의 데이터를 재구성될 클러스터의 노드들에게 분산 전송합니다. 전송이 완료되어 다른 노드들이 데이터를 모두 가지게 될 때 실제로 클러스터에서 제거 됩니다.
  • flush : 앞서 Cassandra 는 write 성능을 위해 Commilog 를 유지하게 됩니다. 설정에 따라 다르지만 threshold 에 도달하면 실제 파일에 쓰기 시작합니다. 이 과정을 flush 라고 하는데 별도의 명령어로 현재 상황에 관계 없이 강제 요청하는 것을 의미합니다.
  • repair : Cassandra 는 기본적으로 Read 시점에서 복구를 수행합니다.(위의 Consistency 관련 정책 참조). 하지만 이와는 별도로 repair 명령어를 통해 전체 데이터에 대한 검사와 복구를 서버에 요청할 수 있습니다. 이 과정은 실시간으로 이루어 집니다. 또한 전체 데이터를 대상으로 하기에 오랜시간이 걸릴 수 있습니다.
  • compact : Cassandra 는 SSTable 로 파일에 기록하는데 이러한 데이터는 쪼개져 있게 됩니다. 즉 최근의 데이터를 별도의 파일에 저장하고 일정 시간 이전 자료는 하나의 파일로 합쳐 놓습니다. 이 과정을 compact 라고 하는데 이를 서버에 강제 요청하게 됩니다. (보통은 데이터 크기, 유휴 시간 등을 바탕으로 결정), 강제 요청이기 때문에 해당 데이터에 대한 요청이 실패할 수도 있습니다.
  • streams : 위에서 노드 추가/제거/이동 등 다양한 명령어에 의해 노드간 데이터가 이동될 수 있음을 볼 수 있습니다. 이 명령어는 이동되는 상태를 볼 수 있습니다.
  • cfstats : CF(Column Family) 의 상태를 볼 수 있습니다. (메모리에 적재된 Row/Key 캐쉬, 데이터 수등)
  • tpstats : 처리에 대한 상태를 볼 수 있습니다. 각종 Stage 별로 상태를 보여 줍니다.

이외에도 Cassandra 는 물리 파일 구조인 SSTable 에 대한 Import / Export 를 지원합니다. (JSON 포멧)

D. 최근 동향은?

2011년 6월 현재 0.8 버전까지 나옴

CQL (Cassandra Query Language) 지원 (>=0.8) : SQL 과 비슷한 형태로 Cassandra Storage 이용

Column 의 Value 에 대한 인덱스 지원 (>=0.7) : Column 의 Value 를 기반으로 정렬, Range Query 가 가능해짐

증가 감소 기능을 가진 속성 추가 (>=0.8) : DBMS 가 증가 감소를 직접 관리하는 속성이 추가됨 (기존 버전의 경우 Read à Update à Write 에 의해 응용소프트웨어가 수행)

CF 밑의 구조 대해서는 Schema-less 이지만 (Row 마다 다른 구조) CF 이상의 구조는 최근 실시간 변경을 지원함 (>=0.7)

메모리 이용 최적화(mmap 사용이 일부 환경에서 적용되었고 이로 인한 문제가 있었지만 최근 인덱스만 mmap 을 이용하도록 함, 이와는 별도로 다양한 환경에서 메모리 이용 최적화가 이루어짐)

버그&문제점 개선 (예: snapshot 구성시 compaction 과 경쟁하는 문제 해결)

5. 관련하여 어떤 좋은게 있나요?

  • OCM (Object Cassandra Mapping)

환경 속성 및 인덱스 등을 정의한 메타 파일을 구성하면 이를 Java Object 로 만들어 줌, 이 Object 는 Save, Delete 등의 DBMS 엑세스 메소드와 속성에 대한 Setter/Getter 를 포함함

  • Hector

Cassandra Java Client 로 여러 노드에 대한 접속을 관리하고 접속 Pool 을 통해 Failover, Load-balance 를 수행

  • CQL

Cassandra 를 Query Language 로 이용할 수 있도록 합니다. 0.8 버전부터 자체 제공되는데 아래 링크에서 문법을 확인 할 수 있습니다.(대체적으로 RDBMS 의 Selection/Projection 을 그대로 따릅니다. DDL 도 일부 지원하고 있습니다. CF 단위 이상의 구조에 대해 실시간 변경이 지원되면서 말이죠. 하지만 여전히 Order by/Group by 와 같은 별도의 유연한 정렬/그룹화 기능은 제공하지 않습니다.)

https://svn.apache.org/viewvc/cassandra/trunk/doc/cql/CQL.textile?revision=1132406&view=co

Cassandra 홈페이지 : http://cassandra.apache.org

(주)리화이트 대표 / CEO & Founder

Next Article“넷플릭스(Netflix)” 2011년 6월 경 사용하던 Oracle 을 버리고 AWS 환경에 구성된 Cassandra (no SQL) 전환