카산드라

I. Key-value Based DBMS, Cassandra의 이해

가. 현재 Computing 환경에서의 이슈

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

 

나. NOSQL/NRDMBS 계열의 DBMS

구분

설명

종류

Document-Oriented DBMS

문서를 속성화 하고 문서의 내용속성을 다양하게 접근하기 위한 방법예을 제공

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

  • Cassandra는 Key-Value 구조이며 대용량 자료의 저장과 처리를 목적으로하며 높은 가용성을 가지는 DBMS.

 

 

II. 대용량 자료의 저장과 처리를 위한 Cassandra의 특징 및 자료처리

가. 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 의 이름)

[ 대용량의 데이터를 저장하고 처리해야하고 정렬에 활용되는 속성이 제한되며 데이터 변경이 잦은경우(Email,쪽지의 inbox)가 사용하기에 좋은 환경임 – Facebook의 Inbook 처리 문제에서 시작 ]

 

나. 자료처리를 위한 논리/물리 구조

1) 논리적 스토리지 구조

 

구조

설명

Column

name(이름), value(값), timestamp(시간)으록 구성

Column Family(CF)

Type이 같은 Column의 집합으로 RDBMS의 Relation과 유사하며 Column, Super Column을 하위 구조로 가질 수 있음

Keyspace

Column Family의 집합.

Cluster

Keyspace의 집합으로 최상위 개념임

 

2) 물리적 스토리지 구조

  • 하나의 서버에서 구동되고 있는 Cassandra 서버 프로세스 하나를 의미함
  • Seoul에 있는 데이터 센터에 2개, Busan에 있는 데이터 센터에 2개의 노드가 실제 논리 스토리지에서는 Cluster라는 확장 공간으로 사용함

 

다. 데이터 저장 및 무결성 유지

1) 데이터 저장

  • Token ring(0~2^127 의 자연수로 구성) 을 구성하고 노드 수에 따라 구간을 나눔
  • 데이터의 키를 해싱(MD5) 하여 해싱되 값을 바탕으로 어느 노드에 데이터가 위치할 지 결정
  • 사전에 노드간에 자신의 영역을 결정하고 적용하기 때문에 해싱된 데이터가 어느 위치에 있을지를 결정하기가 쉬움(Hashing에 들어가는 비용과 구간결정 비용만 존재)
  • Data 입력 : 데이터의 Key가 해싱 후 Node 1 구간에 있을 때 Node1에 실제 데이터 저장
  • Partitioner 를 Random으로 한 경우 실제 키 값하고 상관없이 Random으로 Node 별로 위치
  • Order 방식 : 키를 중심으로 일정 크기만큼 하나의 노드에 위치(Node 추가 삭제가 어려움)
  • 복제본 구성의 정책 : 기본 설정은 옆 Node에 저장, 저장 조회시 Consistency 레벨에 따라 저장 복구시점이 달다짐

 

2) 무결성의 유지

  • CAP 이론으로 무결성 유지 판단
  • Cassandra 의 경우 AP를 만족하고 C의 경우 Eventual Consistency에 의해 만족하게 됨(노드 구성 및 R/W시 Consistency 판단에 따라 달라짐

 

[Eventual Consistency]

  • 성능을 중시하기 위해 낙관적 기대에 의해 무결성 유지
  • T : 전체 노드수
  • N : 현재 데이터와 관련된 노드수
  • W : 정상적으로 Write 되어야 하는 노드 수
  • R : 정상적으로 Read 되어야 하는 노드
  • W+R > N일 때 무결성이 유지 됨
  • N/2 + 1 만큼의 노드에 정상적인 데이터를 쓰고 읽는 시점에서 N/2 이상의 데이터가 같으면 무결성이 유지된다고 볼 수 있음

 

3) 캐싱의 지원

  • CF마다 Row Cache와 Key Cache를 설정 할 수 있음
  • Row Cache : 실제 데이터를 메모리에 적재 해놓은 것
  • Key Cache : Key를 캐싱해 놓은 것을 의미함

 

III. 블로그를 통해 본 Cassandra

가. Cassandra적용을 위한 블로그의 업무 요건

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

 

나. 블로그 적용을 위한 상세

  • BlogEntries : 블로그 게시물의 내용인 작성자의 키(Key), 제목, 내용, 태그, 등록일이 Column 으로 구성
  • 카산드라는 해싱 알고리즘을 통한 Key 접근을 하고 이후 1차 인덱스 된 CF 의 Row key를 접근

< !– 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″ : {

},

}
–>

  • 작성자 KeySapace : 게시물 수 트위터 정보 위치 정보 등

< !—
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를 구성함
  • 키만으로 구성되면 실제 게시물의 내용은 Blog Entries 에서 가져옴

 

< !–
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의 이름으로 사전 정렬됨
  • 댓글 CF정보

< !–
ColumnFamily: Comments
게시물에 대한 Comment 데이터를 저장
Comments : {
“Blog_Key_1″ : { // Key
{time_uid_1} : { // Super Column (사전 정렬 기준)
commenter: “A”,
email: “eh@paran.com”,
comment: “기술사가 도체체 뭘까?”
},
{time_uid_1} : {
commenter: “춘자”,
email: “cj@nate.com”,
comment: “기술사 공부는 힘들어”
},
},

}
–>

  • 실제 데이터를 보이는 중심으로 미리 저장함
  • Write속도가 빠르다는 점을 기준으로 RDBMS와의 차이를 요구사항에 비추어 검토가 필요함

댓글