검수요청.png검수요청.png

카산드라

해시넷
이동: 둘러보기, 검색
카산드라(Cassandra)
카산드라(Cassandra)

카산드라(Cassandra)는 대용량 데이터 처리가 가능한 비관계형 분산 데이터베이스 관리 시스템(DBMS)이다. 빅데이터 처리를 위한 노에스큐엘(NoSQL)의 일종이다. 페이스북(Facebook)이 개발했고 오픈소스로 공개했다. 정식 명칭은 아파치 카산드라(Apache Cassandra)이고, 아파치재단에서 관리하고 있다.

개요[편집]

아파치 카산드라(Apache Cassandra)는 자유 오픈 소스 분산형 노에스큐엘(NoSQL) 데이터베이스 관리 시스템(DBMS)의 하나로, 단일 장애 점 없이 고성능을 제공하면서 수많은 서버 간의 대용량의 데이터를 관리하기 위해 설계되었다. 카산드라는 여러 데이터센터에 걸쳐 클러스터를 지원하며 마스터리스(masterless) 비동기 레플리케이션을 통해 모든 클라이언트에 대한 낮은 레이턴시 운영을 허용하며, 성능 면에서 높은 가치를 보인다. 2012년, 노에스큐엘 시스템을 연구하는 토론토 대학교 연구원들은 "확장성 면에서 실험 가운데 분명한 승자가 있다. 카산드라는 모든 실험의 최대 노드 수에서 가장 높은 처리량을 성취한다."고 결론을 내렸으며 그럼에도 불구하고 "높은 쓰기 및 읽기 레이턴시의 대가가 있다"고 이야기했다.[1]

등장배경[편집]

카산드라는 아마존의 다이나모DB(DynamoDB) 설계에 참여한 아비나쉬 락슈만(Avinash Lakshman)과 페이스북의 프라샨트 말릭(Prashant Malik)이 최초로 만들었다. 아마존 다이나모DB의 분산 디자인과 구글 빅테이블(Bigtable)의 데이터 모델을 기반으로 설계되었다. 노에스큐엘 솔루션 중 하나인 카산드라는 그 이름을 그리스 신화의 예언녀 카산드라에서 빌려왔다고 한다. 신화 속의 카산드라가 트로이인들에게 정확한 미래를 예측하고 제공했듯이 빅데이터 시대의 카산드라 데이터베이스빅데이터의 불확실한 환경에서 정확성과 미래 예측을 제공하는 주요 구성원으로서의 바람을 담아 명명됐을 것이다.[1]

페이스북오픈소스를 기반으로 소셜 서비스를 시작할 무렵부터 개발 및 활용한 카산드라는 여느 분산 데이터베이스와 마찬가지로 수많은 서버들 사이에서 측정 불가능할 정도의 데이터를 저장 및 관리하고자 하는 목적에서 디자인, 설계, 개발됐다. 2008년에 이르러 카산드라는 페이스북의 품에서 떠나 아파치 인큐베이터 프로젝트로 출발해, 2010년에 이르러 탑 레벨 아파치 프로젝트로 인정받게 된다. 또한, 2년 만에 오픈소스 커뮤니티에서 핵심 프로젝트로 인정받게 된 것이다. 피투피 시메트릭(peer-to-peer symmetric) 노드를 기본 설계 개념으로 하고 시스템 실패 시 싱글 포인트 에러를 미연에 방지하는 핵심 기능을 제공하는 등, 카산드라는 빅데이터 시대의 핵심적인 분산 환경 데이터베이스를 제공한다. 카산드라가 제공하는 빅데이터 분산 데이터베이스 환경에서의 또 다른 장점은 관리자(admini strator)가 어떤 데이터가 복제되고 또 얼마나 많은 데이터가 카피 될 것인지를 결정할 권한을 가지게 된다는 것이다.

페이스북에서 처음 카산드라를 개발한 아비나쉬 라쉬만(Avinash Lakshman)에 따르면 카산드라는 피투피(P2P) 네트워크에서의 스트럭처드(structured) 스토리지 시스템으로서 시작됐다. 페이스북 내에서 인덱스 서치(index search) 문제를 어떻게 풀지를 고민하던 아비나쉬는 전 세계에서 매초마다 페이스북 사용자들이 만들어내는 엄청난 데이터의 저장과 그 데이터양의 증가에 맞게 처리할 수 있도록 고안된 카산드라를 만들어내게 된다. 즉, 하드디스크와 메모리 소요와 같은 비용(cost)을 최소화하면서 데이터의 처리 속도가 데이터양에 일직선으로 비례하는 솔루션을 찾게 된 것이다. 데이터 모델의 초창기 구성철학을 살펴보면 다음과 같다. 먼저 모든 로우(row)는 유니크 키에 의해 인식된다. 키는 스트링이며 그 사이즈에 제한이 없다. 두 번째, 카산드라의 인스턴스는 하나의 테이블을 갖는다. 테이블은 하나 이상의 사용자에 의해 정의된 칼럼(column) 구성을 지닌다. 칼럼들은 이름, 밸류, 사용자 정의된 타임스탬프(timestamp)로 구성된다. 무한대의 칼럼들로 구성 가능한 수퍼칼럼(supercolu mn)이 있으며 구성 시 칼럼과 수퍼칼럼 둘 중 하나를 선택할 수 있다.[2]

특징[편집]

카산드라(Cassandra)는 확장성(scalability)과 고가용성(high availability)에 최적화된 대표적인 분산형 데이터 저장소(Data storage)이다. 일관된 해싱(Consistent hashing)을 이용한 링(Ring) 구조와 가십 프로토콜(Gossip protocol)을 구현했으며, 때문에 각 노드 장비들의 추가, 제거 등이 자유롭고, 데이터센터까지 고려 할 수 있는 데이터 복제 정책을 사용하여 안정성 측면에서 많은 장점을 가지고 있다. 카산드라를 이용하면 쉐어링(Sharding)을 고려해야 할 필요도 없고 마스터-슬레이브(master-slave)와 같은 정책이 없이도 장애에 대응할 수 있으며, 필요에 따라 장비들을 늘리고 줄이는 데 큰 비용이 들지 않는다. 물론 그렇다고 해서 카산드라가 완벽한 솔루션은 아니다. 당연한 이야기지만 모든 일에는 균형(trade off)이 있듯이 저러한 강력한 기능들이 구현됨으로써 반대로 수많은 단점들 역시 발생한다. 카산드라는 연결(Join)이나 거래(Transaction)를 지원하지 않고, 인덱스(Index) 등의 검색을 위한 기능도 매우 단출하다. 게다가 카산드라의 구조상 관계형 데이터베이스 관리 시스템(RDBMS)와 같은 Paging을 구현하는 것이 힘들고 키 스페이스(Key space)나 테이블(Table) 등을 과도하게 생성할 경우 메모리 오버플로어(Memory Overflow)가 발생할 수 있음을 고려해야 한다. 따라서 카산드라가 기존의 관계형 데이터베이스 관리 시스템들의 완벽한 대체품이라고 할 수는 없음으로, 개발하게 될 제품의 기능과 특징에 따라 카산드라를 사용할 것인지 관계형 데이터베이스 관리 시스템을 사용할 것인지를 신중히 결정해야 한다.[3]

장단점[편집]

장점
분산화와 집중화

카산드라는 분산형이므로 여러 머신에서 동작하지만, 사용자에게는 통합된 하나로 보인다. 카산드라는 단일노드로도 동작하지만, 카산드라 운영의 장점을 깨달으려면 다중머신에서 운영해야 한다. 그래서 물리적으로 떨어져 있는 데이터센터 간에도 단일 카산드라 클러스터를 운영할 수 있다. 마이에스큐엘(MySQL), 빅테이블과 같은 데이터 저장소를 확장하려면 일부 노드는 마스터로 설정해서 슬레이브로 설정한 다른 노드를 조직화해야한다. 그러나 카산드라는 "비집중화"이므로 모든 노드가 같다. 그러므로 조직화 연산을 수행하는 마스터가 없다. 대신 카산드라는 피투피(P2P) 프로토콜이며 활성 노드와 비활성 노드의 목록을 동기화하고 유지관리한다.[4]

탄력적인 확장성

약간의 성능 저하를 동반하지만, 계속해서 더 많은 요청을 처리할 수 있는 시스템의 아키텍처 특징이다. 가장 쉬운 방법은 단순히 기존 머신에 더 많은 메모리와 하드웨어 용량을 추가해서 확장성을 얻는 수직 확장이다. 수평 확장은 데이터 전체나 일부를 갖는 머신을 추가해서 요청처리를 여러 머신이 나눠 갖는 방법이다. 그러나 이렇게 하려면 클러스터에 있는 다른 노드와 데이터를 동기화하고 유지하는 내부 매커니즘이 필요하다. 탄력적인 확장성(elastic scalability)은 수평 확장의 특별한 속성으로, 클러스터의 중단 없이 규모를 확대하거나 축소할 수 있다는 뜻이다. 단지 새로운 머신을 추가해라. 그러면 카산드라가 새로 추가된 머신을 찾아내고 작업을 할당한다. 규모축소(scaling down)는 클러스터에서 처리 용량의 일부를 제거하는 것을 말한다. 애플리케이션의 일부를 다른 플랫폼으로 이전하거나 애플리케이션의 사용자가 떠나고 하드웨어를 매각해야 한다면 이렇게 할 것이다. 규모축소를 하더라도 전체 구성을 건드릴 필요는 없다.[4]

고가용성과 결함 허용

일반적인 아키텍처 용어로 시스템의 가용성은 요청을 수행하는 능력으로 측정한다. 고가용성 시스템을 구축하려면 일반적으로 다중네트워크로 구성된 컴퓨터, 클러스터에서 운용할 수 있는 소프트웨어, 노드 장애를 인식하고 시스템의 다른 파티션으로 요청을 대체 할 수 있는 기능을 갖춰야 한다. 카산드라는 고가용성을 지원한다. 클러스터에서 시스템을 중단하지 않고 장애가 발생한 노드를 교체 할 수 있고, 다중 데이터 센터에 데이터를 복제해 로컬 성능을 개선할 수 있으며, 한 데이터 센터가 화재나 홍수 같은 치명적인 재앙을 당하더라도 다중 데이터 센터에 데이터를 복제해서 서비스 중단을 예방할 수 있다.[4]

조정가능한 일관성

일반적으로 일관성은 항상 가장 최근에 기록된 값을 읽는다는 뜻이다. 예를 들어, 전자상거래 사이트에서 동시에 같은 상품을 장바구니에 추가하려는 두 고객이 있다고 해보자. 다른 사람이 장바구니에 상품을 추가한 직후에 마지막 남은 상품을 내 장바구니에 추가한다면 마지막 상품은 다른 사람의 장바구니에 있어야 하며, 나에게는 구매할 수 없는 상품이라고 알려줘야 한다. 일관성은 쓰기의 상태가 데이터를 가진 모든 노드에서 일관될 때 보장된다. 그러나 데이터 저장소를 확장한다는 것은 데이터의 일관성, 노드 가용성, 그리고 파티션 허용 사이에 등가교환이 발생한다는 뜻이다. 즉 카산드라는 전체가용성을 달성하기 위해 일관성을 약간 희생한다.[4]

단점

칼럼형 데이터베이스로 로우형 데이터베이스인 관계형 데이터베이스와는 다른 생소한 개념이라 진입장벽이 높다. 많은 사용자를 대상으로 대량 데이터를 다루는 서비스가 아닐 경우 쓸 필요는 없다. 그리고 복잡한 조건의 검색이 불가능하다. 로우 키와 칼럼 두가지에 대한 인덱스만 가능하기 때문에 데이터는 대량이지만 검색 조건은 단순한 서비스에 적합하다. 슈퍼 칼럼 구성(Super Column family)의 하위 칼럼에 대한 인덱싱은 불가능하다. 키 값을 통한 범위 검색은 데이터 분산 방식을 오더프레스파티셔너(OrderPresservingPartitioner)로 설정하여 키 값을 통해 데이터를 서버에 분배했을 경우에만 가능하다. 데이터를 입력 시에도 자동화한 처리가 어렵다. 데이터에 대한 락을 사용하려면 주키퍼(Zookeeper)와 같은 전체분산 서버를 관리하는 프로그램을 추가해서 별도로 설정해야 한다. 데이터에 대한 동시 갱신 요청이 발생할 가능성이 높거나 자동화한 트랜잭션이 필요한 서비스에서는 다른 데이터베이스를 고려해야 한다. 마지막으로, 버전 1이 정식으로 나오지 않아 안정적이지 않은 시스템이라는 것도 단점이 된다.[5]

데이터 구조[편집]

카산드라 데이터 구조
카산드라 링
카산드라 링에 저장되는 데이터
카산드라 데이터 테이블로 변경
카산드라 쿼리 언어(CQL)의_테이블_형태

카산드라의 데이터 구조는 비교적 간단하다. 최상위에 논리적 데이터(Data) 저장소인 키 스페이스(Key space)가 있고, 키 스페이스 아래에는 테이블(Table)이 존재한다. Table은 다수의 로우들로 구성되어있으며 각 로우는 키 값(Key Value)으로 이루어진 칼럼들로 구성된다. 관계형 데이터베이스 관리 시스템의 데이터베이스 테이블 로우 칼럼(DB-Table-Row-Column)의 형태와 유사한 구조를 하고 있다는 걸 알 수 있다. 더구나 카산드라는 카산드라 쿼리 언어(CQL)를 지원하고 있다.[3]

카산드라는 기본적으로 링(Ring) 구조를 띠고 있다. 그리고 링을 구성하는 각 노드에 데이터(Data)를 분산하여 저장한다. 파티션 키라고 불리는 데이터의 해시(hash)값을 기준으로 데이터를 분산하게 된다. 처음 각 노드가 링에 참여하게 되면, 카산드라의 conf/cassandra.yaml에 정의된 각 설정을 통하여 각 노드마다 고유의 해시 값 범위를 부여받는다. 그런 뒤에, 외부에서 데이터의 요청이 오게 되면 해당 데이터의 파티션 키의 해시 값을 계산하여 해당 데이터가 어느 노드에 저장되어 있는지 알고 접근할 수 있는 것이다. 그리고, 카산드라는 이렇게 계산된 hash의 값을 토큰(token)이라고 부른다.카산드라 쿼리 언어의 사용을 권장하고 있지만 카산드라 쿼리 언어가 처음부터 제공되었던 것은 아니다.[3]

초기의 카산드라는 절약 프로토콜(Thrift protocol)을 이용한 클라이언트 API(client API)를 제공했고, 아예 카산드라에 직접 접근해보고 싶다면 bin/cassandra-cli 유틸리티를 이용하여 데이터를 확인할 수 있다. 이러한 기존의 절약(Thrift) 기반의 API(에이피아이)와 씨엘아이(CLI) 유틸리티들은 카산드라 데이터 구조(Cassandra Data layer)를 있는 그대로 표현해주었지만, 절약이 가지는 여러 가지 한계점을 같이 가지고 있다. 때문에 카산드라 1.2버전 이후에는 기본 프로토콜(Native Protocol)을 기반으로 한 API와 카산드라 쿼리 언어 문법이 추가되었고, 3.0 버전부터는 기존의 절약 기반의 bin/cassandra-cli 유틸리티는 아예 파괴(Deprecated)되어 사라졌다. 더구나 이 시기에 카산드라에는 다른 많은 변화가 같이 있었다. 슈퍼 칼럼(Super Column)이라고 하는 칼럼 안에 칼럼 형태를 가지는 자료구조가 아예 스펙에서 제외되어 수집(Collection)이라는 것으로 새롭게 대체되었으며, 기존의 칼럼 구성(Column Family)이라고 불리는 자료구조는 테이블(Table)로 명칭이 변경되었다. 이 과정에서 카산드라 쿼리 언어는 이렇게 새롭게 구성된 카산드라 데이터 구조를 추상적으로 표현하는 문법으로 구성되었고, 따라서 실제 데이터 구조(Data Layer)의 용어들과 카산드라 쿼리 언어에서의 표현이 1:1로 매칭되지 않고 달라지게 되었던 것이다.[3]

초창기 카산드라 데이터 구조는 키 스페이스(Key space) > 칼럼 구성(Column Family) > 로우 > 칼럼 형태로 구성되어 있다. 키 스페이스와 칼럼 구성에 대한 정보는 모든 카산드라 노드(Cassandra node)의 메모리에 저장되며, 실제 유저의 데이터들이 저장되는 로우는 각 로우 키를 가지고 이것의 해시 값인 토큰을 기준으로 각 노드에 분산 저장된다. 그리고, 로우에 속하는 칼럼들은 칼럼 이름을 기준으로 정렬되어 저장된다. 이러한 형태는 카산드라 1.2 에 들어서 키 스페이스 > 테이블 > 로우 > 칼럼 으로 명칭이 바뀌게 된다. 하지만, 이때 함께 등장한 카산드라 쿼리 언어은 이를 있는 그대로 표현하지 않고, 한 단계 추상화하여 표현한다.[3]

여전히 같은 의미로 사용되는 키 스페이스(Keyspace)와 테이블(Table)과는 다르게, 카산드라 쿼리 언어 로우와 칼럼은 실제 데이터가 저장되는 지금까지 보았던 카산드라 데이터 구조(Cassandra Data Layer)에서의 로우, 칼럼과 그 의미가 다르다. 카산드라 쿼리 언어에서 로우와 칼럼은 관계형 데이터베이스 관리 시스템의 뜻,속성(Tuple, Attribute)과 유사하다는 것을 알 수 있다. 하지만, 이렇게 구성된 카산드라 쿼리 언어 테이블은 최소 1개 이상의 칼럼을 기본 키(primary key)라는 것으로 지정해야 하며, 카산드라는 이렇게 primary key로 지정된 칼럼들 중에서 파티션 키로 지정된 column의 가치(value)를 기준으로 데이터를 분산하게 된다.[3]

쿼리 언어 키[편집]

카산드라의 쿼리 언어 키는 파티션 키와 클러스터 키(Cluster Key)로 구성되어 있다. 기본 키 설정은 테이블을 생성할 때 적용할 수 있다. 관계형 데이터베이스 관리 시스템의 쿼리문과 비슷하게 사용할 수 있다. 파티션키는 필수적으로 설정되어야 하고, 복합 키(composite key)로도 설정이 가능하다. 카산드라의 데이터는 파티션키를 기준으로 저장되기 때문에, 파티션의 크기, 파티션 내 데이터 순서, 클러스터 노드 간 파티션 분포를 고려하여 최소 1개 이상의 파티션 키를 가져야 한다. 클러스터링 키는 파티션키 내부에서 데이터 순서를 정렬한다. 이 값은 필수적으로 설정하지 않아도 된다. 하지만 데이터를 최적화된 성능으로 가져오기 위해 데이터 구조에 맞는 클러스터 키를 설정한다. 복합 키로 설정할 땐 기본 키를 활용하여 괄호로 구분하면 된다.[6]

용어 정리
  • 파티션 키(Partition key) : 카산드라 쿼리 언어 문법에서 카산드라에 데이터를 분산 저장하기 위한 유니크한 키이다. 파티션 키는 특정 테이블(table)을 구성할 때 반드시 1개 이상이 지정되어야 하며, 여러 개 지정될 수도 있다. 파티션키가 단 1개일 경우, 해당 파티션 키로 지정된 카산드라 쿼리 언어 칼럼의 가치가 실제 카산드라 데이터 구조의 로우 키(low key)로 지정된다. 파티션 키가 여러 개 일 경우, 각 파티션 키로 지정된 카산드라 쿼리 언어 칼럼들의 가치들을 문자와 함께 조합한 값들이 실제 카산드라 데이터 구조의 로우 키로 저장된다.[7]
  • 클러스터 키(Cluster key) : 카산드라 데이터 구조에서 로우에 속한 모든 칼럼들은 항상 정렬된 상태로 저장된다. 따라서 클러스터 키는 이러한 정렬에 대한 기준 역할을 담당한다. 카산드라 쿼리 언어에서 클러스터 키로 지정된 카산드라 쿼리 언어 칼럼들의 가치는 나머지 칼럼들의 이름 및 문자와 함께 조합되어, 이 값이 실제 카산드라 데이터 구조의 칼럼 이름으로 저장된다. 만약 클러스터 키가 전혀 없는 경우에는 카산드라 쿼리 언어 칼럼의 이름이 그대로 카산드라 데이터 구조의 칼럼 이름이 된다.[7]
  • 기본 키(Primary key) : 카산드라 쿼리 언어 테이블에서의 각 로우를 각자 유니크하게 결정해주는 기준 역할을 담당한다. 기본 키는 최소 1개 이상의 파티션 키와 0개 이상의 클러스터 키(cluster key)로 구성된다.[7]
  • 복합 키(composite key) : 1개 이상의 카산드라 쿼리 언어칼럼들로 이루어진 기본 키이다.[7]
  • 복합 파티션 키(composite partition key) : 2개 이상의 다수의 카산드라 쿼리 언어 칼럼으로 이루어진 파티션 키를 의미한다.[7]
  • 칼럼(Column) : 카산드라 데이터 모델의 데이터 구조에서 가장 기본이 되는 단위다. 칼럼은 이름, 값, 클록(clock)이라는 트리플릿(triplet)으로 구성된다. 클록은 현재 시간에 대한 타임스탬프라 할 수 있다. 관계형 분야의 "칼럼"에 익숙하겠지만, 카산드라에서도 이렇게 생각하면 헷갈리기만 한다. 무엇보다도 관계형 데이터베이스의 설계는 테이블의 모든 칼럼에 이름을 지정하고 테이블의 구조를 설계하는 방식을 따른다. 또한, 테이터를 쓸 때는 미리 정의한 구조에 값을 넣기만 한다. 그러나 카산드라에서는 칼럼을 미리 정의하지 않아도 된다. 다시 말해서 키스페이스에 원하는 칼럼 구성만 정의하고, 어딘가에 칼럼을 정의하지 않아도 데이터 쓰기를 시작할 수 있다. 이런 이유 때문에 카산드라는 모든 컬럼의 이름을 클라이언트에서 받는다. 칼럼 구성만 정의하면 되기 때문에 애플리케이션에서 데이터를 다루는 방법에 융통성을 발휘할 수 있으며, 시간의 경과에 따라 유기적으로 진화하는 설계가 가능하다. 이름과 값에 쓰이는 데이터 타입은 자바의 바이트 배열이며 종종 문자열로 제공되기도 한다. 이름과 값이 바이너리 타입이므로 길이에 제한이 없다. 클록의 데이터 타입 0.7 버전에서는 하위 호환성을 위해 타임 스탬프가 유지될 것이다.[8]
  • 클러스터(Cluster) : 단일 노드에서만 실행할 거라면 카산드라가 최선의 선택이 아닐 것이다. 카산드라 데이터베이스는 다중 머신에 분산되어 운영되지만 최종 사용자에게는 단일 인스턴스처럼 보이도록 설계되었다. 그래서 카산드라의 가장 바깥쪽 구조가 클러스터이며, 이를 링(ring)이라 부르기도 한다. 이는 카산드라가 링에 데이터를 배열하고 그 데이터를 클러스터의 노드에 할당하기 때문이다. 노드는 범위가 다른 데이터의 복제본(replica)을 유지한다. 첫 번째 노드가 다운되면 복제본이 쿼리에 응답할 수 있다.[8]
  • 키 스페이스(Key space) : 클러스터는 키 스페이스의 컨테이너다. 키 스페이스는 카산드라에서 데이터 컨테이너의 최외곽 컨테이너로 관계형 데이터베이스와 매우 비슷하다. 관계형 데이터베이스처럼 키 스페이스는 이름과 키스페이스 전체 행위를 정의하는 속성 집합(set)을 갖고 있다. 애플리케이션마다 단일 키 스페이스를 생성하는게 좋은 생각이라고 조언하지만, 이에 대한 실질적인 근거가 많지는 않다. 분명히 수용할 수 있는 방법이지만, 애플리케이션에서 필요한 만큼의 키 스페이스를 생성하는 것이 좋다.[8]
설정 방법
  • 칼럼에 직접 설정
 CREATE TABLE emp(
      emp_id int PRIMARY KEV,
      emp_name text,
      emp_city text,
      emp_sal varint,
      emp_phone varint,
 ); 
  • 기본 키로 설정
 CREATE TABLE emp2(
     emp_id int,
     emp_name text,
     emp_city text,
     emp_sal varint,
     emp_phone varint,
     primary key (emp_id, emp_city)
 );
  • 복합 키 설정(파티션 키 : emp_id, emp_name, 클러스터링 키 : emp_city)
  CREATE TABLE emp2(
     emp_id int,
     emp_name text,
     emp_city text,
     emp_sal varint,
     emp_phone varint,
     primary key ((emp_id, emp_name), emp_city)
 );      
  • 복합 키 설정(파티션 키 : emp_id, 클러스터링 키 : emp_sal, emp_city)
  CREATE TABLE emp2(
     emp_id int,
     emp_name text,
     emp_city text,
     emp_sal varint,
     emp_phone varint,
     primary key (emp_id, ( emp_sal, emp_city))
 );      
 
  • 복합 키 설정(파티션 키 : emp_id, emp_name, 클러스터링 키 : X)
  CREATE TABLE emp3(
     emp_id int,
     emp_name text,
     emp_city text,
     emp_sal varint,
     emp_phone varint,
     primary key ((emp_id, emp_city))
 );        
  • 복합 키 설정(클러스터링 키 구체적인 옵션 부여)
 CREATE TABLE emp5(
     emp_id int,
     emp_name text,
     emp_city text,
     emp_sal varint,
     emp_phone varint,
     primary key (emp_id, emp_city)
 )WITH CLUSTERING ORDER BY (emp_city DESC);
파티셔너

파티셔너(partitioner)는 로우키를 토큰으로 변환해주는 모듈이다. "conf/cassandra.yaml"의 파티셔너 항목을 보면 카산드라가 어떤 파티션을 사용했는지 확인 할 수 있으며, 랜덤 파티셔너(RP), 엠쓰리피(M3P), 바이트 오더드 파티셔너(BOP)라는 이름의 세 가지 파티션을 제공한다. 랜덤 파티셔너는 로우키를 MD5(Message Digest 5)로 해싱(hashing)하여 토큰을 생성한다. 엠쓰리피는 머머5(MurMur5)로 해싱하여 토큰을 생성한다. 하지만, 바이트 오더드 파티셔너는 조금 다르다. 바이트 오더드 파티셔너는 로우키를 16진수 형태로 변환하여 이 값을 토큰으로 사용한다. 즉, 바이트 오더드 파티셔너로 변환된 토큰은 문자 순서로 정렬되어 각 노드에 분산된다는 이야기다. 만약, 바이트 오더드 파티셔너를 쓴다면 로우키들이 문자순서로 정렬되어 있으니 대용량 데이터를 특별한 가공 없이 그대로 범위 질의(range query)를 할 수 있는 등, 여러 가지로 편리하게 사용할 수 있다. 하지만, 바이트 오더드 파티셔너는 카산드라(Cassandra)의 대표중 안티패턴 중 하나이다. 바이트 오더드 파티셔너를 사용할 경우 핫스팟(Hotspot)이 발생할 확률이 매우 높다.[7]

바이트 오더드 파티셔너를 사용하여 로우키(Row Key)문자 순서대로 각 노드 별로 데이터를 분산하게 된다면, 모든 노드에 데이터를 균일하게 분산하기 위해서는 데이터의 분산기준을 담당하는 로우키 자체가 모든 문자열에 대애허 균일하게 분포해야 한다. 하지만 현실은 그렇지 않다. 특정 문자로 밀집되어 있는 로우키 들을 저장하는 노드가 자연스럽게 핫스팟이 되어버린다. 노드를 늘렸더니 오히려 전혀 사용하지 않는 노드가 다수 생길 수도 있고, 노드를 줄였더니 더 심각한 핫스팟이 생겨버릴 수도 있기 때문이다. 이는 바이트 오더드 파티셔너의 경우 분산의 정도가 전적으로 로우키의 분포에 달려있기 때문이다. 이러한 이유로 디폴트는 엠쓰리피를 사용한다. 이것을 사용함으로 모든 데이터를 비교적 균일하게 모든 노드에 분산 할 수 있는 것이다. M3 해시 함수(Murmur3 hash function)를 사용할 때 단점도 존재한다. 문자열이 아닌 해시값을 기준으로 정렬하여 각 노드에 저장되므로, 로우키의 문자열로 정렬된 데이터가 필요할 경우엔 사용자는 모든 데이터를 가져온 다음에 애플리케이션 구조(Application Layer)에서 직접 데이터를 가공하여 정렬해야 한다. 가령 엄청난 양의 데이터가 분산되어 저장되어 있는데, 로우키를 기준으로 데이터를 패깅(paging)하는 등의 작업은 불가능한 일이다. 그 많은 데이터를 모두 가져와서 직접 정렬해야 최종적으로 사용자가 원하는 위치의 데이터 집합을 뽑아낼 수 있다.[7]

데이터 일관성과 복제

카산드라는 기본적으로 카산드라 쿼리 언어를 통해 쿼리 시점에 읽기와 쓰기에 따른 다양한 일관성 수준(Consistency Level)을 통해서 몇 개의 복제(Replication)를 통해 어느 정도 수준의 데이터 일관성을 확보할 것인지 선택 할 수 있다. 또한, 처음 키 스페이스(Key space)를 생성할 때 복제(Replication)의 배치 전략과 그 전략에 맞는 복제 개수, 위치 위치를 결정 할 수 있다. 그리고 이러한 기능을 지원하기 위해서 conf/cassandra.yaml의 endpoin_snitch 항목에 스니치(snitch)의 종류를 세팅하게 된다. 스니치는 데이터센터가 어떻게 구성되어있는지, 장비가 설치된 렉이 어떻게 나뉘어져 있는지에 대한 체계적인 분류(topology)를 카산드라에게 알려주기 위한 옵션이다. 카산드라에서 제공하는 스니치의 종류는 매우 다양하다. 스니치는 단순히 1개의 데이터 센터(Data Center)를 가정한 것도 있고, 다수의 데이터 센터에 다양한 랙(Rack) 배치까지 고려한 것도 있으며, 심지어 클라우드 스택(Cloud Stack)이나 구글 클라우드(Google Cloud)와 같은 클라우드(Cloud) 서비스에 특화된 스니치도 존재한다. 이러한 스니치를 바탕으로 카산드라는 사용자가 정의한 스키마에 따라서 어느 데이터 센터의 어느 Rack에다가 각각 몇 개의 복제 데이터(Replication Data)를 나누어 저장할 것인지 등을 결정하는 것이다. 그리고 이렇게 구성된 카산드라에 사용자가 데이터를 CRUD(Create Read Update Delete) 하고자 한다면, 사용자가 해당 쿼리와 함께 지정한 일관성 수준을 통하여 데이터를 처리하게 된다.[7]

각주[편집]

  1. 1.0 1.1 아파치 카산드라 위키백과 - https://ko.wikipedia.org/wiki/%EC%95%84%ED%8C%8C%EC%B9%98_%EC%B9%B4%EC%82%B0%EB%93%9C%EB%9D%BC
  2. 빅테이블과 다이나모의 장점을 흡수한 카산드라〉, 《한국데이터산업진흥원》
  3. 3.0 3.1 3.2 3.3 3.4 3.5 엄세진, 〈Apache Cassandra 톺아보기 1편〉, 《토스트밋업》, 2016-01-18
  4. 4.0 4.1 4.2 4.3 (Cassandra)카산드라?〉, 《블로거》, 2016-06-15
  5. 사무엘(samuelc), 〈MongoDB, Cassandra, HBase 간단 정리〉, 《네이버 블로그》, 2013-05-03
  6. Log logblsl, 〈(Cassandra)Table, Column, Partition Key Clustering Key〉, 《티스토리》, 2020-05-21
  7. 7.0 7.1 7.2 7.3 7.4 7.5 7.6 7.7 (Cassandra)카산드라 데이터 모델〉, 《블로거》, 2016-06-19
  8. 8.0 8.1 8.2 martin.k, 〈카산드라데이터모델〉, 《다음 블로그》, 2013-07-25

참고자료[편집]

같이 보기[편집]


  검수요청.png검수요청.png 이 카산드라 문서는 데이터에 관한 글로서 검토가 필요합니다. 위키 문서는 누구든지 자유롭게 편집할 수 있습니다. [편집]을 눌러 문서 내용을 검토·수정해 주세요.