Introduction of Cassandra
카산드라는 구글의 BigTable 컬럼 기반의 데이타 모델과 FaceBook에서 만든 Dynamo의 분산 모델을 기반으로 하여
제작되어 Facebook에 의해 2008년에 아파치 오픈소스로
공개된 분산 데이타 베이스 입니다.
기존의 관계형 데이타 베이스와 다르게 SQL을 사용하지 않는 NoSQL의 제품중의 하나이며, 대용량의 데이타 트렌젝션에 대해서
고성능 처리가 가능한 시스템이다.(High-Scale). 노드를 추가함으로써 성능을 낮추지 않고 횡적으로
용량을 확장할 수 있다.
얼마전에
트위터도 MySQL에서 Cassandra로 데이타베이스를
전환하였다고 한다..
자바로 작성되었음에도 불구하고, 데이타베이스라는 명칭에 걸맞게 여러
프로그래밍 언어를 지원합니다. Ruby,Perl,Python,Scala,Java,PHP,C#
데이타간의 복잡한 관계 정의(Foreign Key)등이 필요없고, 대용량과 고성능 트렌젝션을 요구하는 SNS (Social Networking
Service)에 많이 사용되고 있습니다. 성능이나 확장성과 안정성이 뛰어나지만 안타깝게도 Global Scale (여러 국가에 데이타 센터를 분리 배치하여 배포하고, 데이타
센타간 데이타를 동기화 하는 요구사항) 은 지원하지 않습니다.
Global Scale이 필요하다면, MySQL기반의
geo replication과 Sharding이 아직까지는 가장 널리 쓰이는 아키텍쳐 같습니다.
Data Model
카산드라의 데이타 모델은 다음과 같다.
전통적인 관계형 데이타 베이스와 다른 구조를 가지고 있다.먼저 데이타 모델에 대한 개념을 잡아보면
Column
컬럼은 컬럼 이름과, 값으로 이루어진 데이타 구조체이다.
{name: “emailAddress”, value:”cassandra@apache.org”}
{name:”age” , value:”20”}
Column Family
컬럼 패밀리는 컬럼들의 집합이다. 관계형 데이타 베이스의 테이블을
생각하면 되는데, 약간 그 개념이 다르다. 차이점은 나중에
설명하기로 하고, 컬럼 패밀리는 하나의 ROW를 식별하기
위한 Key를 갖는다. 하나의 Key에 여러개의 컬럼이 달려 있는 형태가 컬럼 패밀리이다.
하나의 Row를 예를 들어보면
Cassandra = { emailAddress:”casandra@apache.org” , age:”20”}
과 같은 형태이다. Cassandra가 해당 Row에 대한 Key가 되고,
emailAddress와 age라는 이름의 두개의 컬럼을 가지고 있으며 각 컬럼의 값은
“casandra@apache.org” 와 “20”이다.
여러개의 Row를 가지고
UserProfile이라는 이름의 컬럼 패밀리를 보면
UserProfile={
Cassandra={ emailAddress:”casandra@apache.org”
, age:”20”}
TerryCho= { emailAddress:”terry.cho@apache.org”
, gender:”male”}
Cath= { emailAddress:”cath@apache.org”
, age:”20”,gender:”female”,address:”Seoul”}
}
과 같이 표현할 수 있다. 여기서 주목할만한 점이 각 Row의 데이타 스키마가 다르다는 것이다. Cassandra Row는 emaillAddress와 age라는 컬럼을 가지고 있고, Terry.Cho는 emaillAddress와 gender라는 컬럼을 가지고 있다. 이 처럼 카산드라는 각 Row마다 다른 형태의 데이타 스키마를 가질 수 있는데, 이러한 특징은
“Schemeless”라고 한다.(키에 바인딩되는 데이타
구조는 같은 컬럼 패밀리라도 각 키별로 다를 수 있다.)
KeySpace
KeySpace는 논리적으로
ColumnFamily를 묶어주는 개념입니다. 단지 묶어만 줄뿐 데이타 구조나 관계에서는
별다른 영향을 주지 않습니다.
Super Column & Supper Column Family
앞에서 설명드렸던 컬럼에서 컬럼의 Value는 String이나 Integer와 같은 Primitive형 뿐만 아니라 컬럼 자체가 다시 들어갈 수 있습니다. 예를 들어 이런 구조입니다.
{name:”username”
value: firstname{name:”firstname”,value=”Terry”}
value: lastname{name:”lastname”,value=”Cho”}
}
username이라는 컬럼 안에
firstname과 lastname이라는 두개의 컬럼이 들어가 있는 구조입니다.
마찬가지 형태로 Column Family 안에도 Column Family가 들어가는 Super 구조가 가능합니다.
UserList={
Cath:{
username:{firstname:”Cath”,lastname:”Yoon”}
address:{city:”Seoul”,postcode:”1234”}
}
Terry:{
username:{firstname:”Terry”,lastname:”Cho”}
account:{bank:”hana”,accounted:”1234”}
}
}
UserList라는 Column
Family 안에, 각각 Cath Key는 username과 address라는 Column Family를 가지고 있고, Terry라는 Key는 username과
account라는 Column Family를 가지고 있습니다.
Data Model for Java Developer
간단하게 카산드라의 데이타 구조에 대해서 살펴보았는데, 자바 개발자분이시라면 HashTable이 떠오를겁니다. 데이타 모델을 HashTable과 비교해서 설명해보면 다음과 같은
형태가 됩니다.코드로 이야기 하면 대략 다음과 같은 형태가 되겠지요
앞서 들었던 Column Family의 데이타 구조를 자바 코드로
표현하면 다음과 같은 구조가 됩니다.
UserProfile={
Cassandra={ emailAddress:”casandra@apache.org” , age:”20”}
TerryCho= { emailAddress:”terry.cho@apache.org” , gender:”male”}
Cath= { emailAddress:”cath@apache.org” , age:”20”,gender:”female”,address:”Seoul”}
}
자바 코드
class Keyspace{
HashTable
keyspaces = new HashTable();
createColumnFamily(String
name){
keyspaces.put(name,new
HashTable);
}
putValue(String
columnFamily,String key,Object value){
Hashtable
cf = keyspaces.get(columnFamily);
cf.put(key,value);
}
}
class TerryVO{ // Terry is a Key
String
emailAddress; // each column
String
gender;
// setter & getter
}
class CathVO{ // Cath is a Key
String
emailAddress;
String
age;
String
gender;
// setter & getter
}
KeySpace myspace;
myspace.createColumnFamily("UserProfile");
myspace.putValue("UserProfile","TerryCho",new
TerryVO("terry.cho@apache.org","male");
myspace.putValue("UserProfile","Cath",new
CathVO("cath@apache.org","20","female")
자바 개발자분들이시라면 쉽게 이해하실 수 있을것 같고
구조를 분석하다보니 오라클의 데이타 그리드 솔루션은 Coherence와 데이타 구조가 매우 유사합니다. 요즘 이게 유행인가 보네요
Cassandra Test
개념을 이해했으면 실제 테스트를 한번 해보도록 하겠습니다.
먼저 아파치 카산드라 프로젝트(http://incubator.apache.org/cassandra/)
에서 카산드라를 다운 받습니다. 압축을 푼후에
bin/cassandra.bat를 실행시킵니다. (클러스터로 기동할 수 도 있으나 여기서는 단순하게 하나의 노드만 뛰어보도록 합니다.)
이제 카산드라 커맨드 라인 인터페이스(CLI)를 시키고(/bin/cassandra-cli.bat) 다음 카산드라 노드에 연결합니다. 포트는 디폴트로 9160 포트가 지정되어 있으며 /conf/storage-conf.xml에서 Listen Address와 Port를 변경할 수 있습니다.
/conf/storage-conf.xml 파일에는 default로 Keyspace1이라는 이름으로 Keyspace가 정의되어 있습니다. Keyspace1에 지정되어
있는 Column Family(CF) 형식은 다음과 같습니다.
Standard2 CF에 Terry이라는 Key로 Gender라는
Column에 Male이라는 값을 넣고 다시 조회해보겠습니다.
다음번에는 Java Code를 이용하여 카산드라에 접근하는 방법에
대해서 알아보도록 하겠습니다.
참고 할만한 자료
본인은 구글 클라우드의 직원이며, 이 블로그에 있는 모든 글은 회사와 관계 없는 개인의 의견임을 알립니다.
댓글을 달아 주세요
잘 정리해 주셨네요. 감사...
쉽게 잘 정리되어 있어서 도움이 많이 되었습니다.
node 내에서 write에 대한 설명시 'Insert가 요청된 데이타는 DISK에 바로 기록되지 않고 메모리 내의 MemTable이라는 곳에 기록이 된다.' 이 부분은 오해를 일으킬 수 있습니다.
MemTable이 메모리 상의 캐쉬라서 디스크에 기록하는 걸 백그라운드에서 하는 거고, MemTable에 put하기 전에 기록하는 commit log가 바로 디스크 상의 파일입니다.
언급하신 바와 같이 Oracle의 redo log & buffer cache 매커니즘과 다른 부분이 없습니다.