반응형
Cassandra와 더불어 HBase에 대해 궁금하다면 이전에 작성한 포스트를 참고하시기 바랍니다!
학습목표
1. Cassandra DB가 무엇인지, 그 특징과 적용 분야를 설명할 수 있습니다.
2. Cassandra의 기본 구조 및 Read/Write 수행 메커니즘을 알게 됩니다.
NoSQL이란? (3-2) : 카산드라(Cassandra) DB의 구조 및 아키텍쳐
1. Cassandra 구조
- Cassandra 데이터 모델
- Keyspace -> Table -> Row -> column name : column value
- Keyspace는 data container 역할을 수행합니다.
- Keyspace -> Table -> Row -> column name : column value
- Cassandra Cluster
- Ring 형태로 각 노드에 데이터를 분산 저장합니다.
- 분산 기준은 Partition Key
- 데이터 hash 값을 기준으로 분산됩니다.
- Ring 형태로 각 노드에 데이터를 분산 저장합니다.
- Write / Read data flow
- Coordinator node
- 클라이언트 요청을 처리합니다.
- 어떤 node이든 Coordinator node가 될 수 있습니다.
- Write Path
- 디스크에 있는 Commit log에 추가하고, memTable에 저장합니다.
- memTable이 full 상태가 되면, I/O을 통해 SSTable에 flush합니다.
- flush 후에는 commit log에 있는 데이터가 삭제됩니다.
- SSTable은 Primary index(데이터 파일에서 row keys와 행 시작 위치 리스트)와 Bloom filter(성능을 향상하기 위한 Primary index의 하위 집합)를 포함합니다.
- Read Path
- Node에 읽기 연산이 요청되면, 관련된 SSTable 및 unflushed memTables에서 병합합니다.
- 병합된 값은 write-through row Cache에 저장됩니다.
- Read Repair : Coordinator는 여러 노드에 접속하여 백그라운드에 남아 있는 모든 복제본을 체크한 뒤, 일치하지 않는 복제본에 대해 업데이트를 합니다.
- Coordinator node
- Delete Data
- Tombstone
- 삭제된 Column을 나타내는 row의 marker 역할
- 표시된 Column들은 바로 삭제되지 않고, 시간이 지나 SSTable들이 compaction 진행될 때 사용합니다.
(장애 발생 후에 다시 복구하는 Node에 의해 Side-effect가 발생하기도 합니다.) - Compaction
- SSTable을 병합/정렬하여 새로운 SSTable을 생성합니다.
- 필요한 검색 Query 횟수를 줄여 공간을 확보하고 성능을 향상시킬 수 있습니다.
- Key 병합, Column 병합, tombstone 삭제, 새로운 index 등
- Tombstone
2. CQL (Cassandra Query Language)
- CQL 개념
- SQL과 유사한 방식으로 CQL shell (cqlsh)를 사용하여 CRUD 연산을 수행합니다. 다양한 데이터 타입을 지원하는데, 그 중에서 가장 일반적인 type은 Built-in type, 그리고 Collection, User-defined type 이렇게 세 가지 타입만 기억하면 충분합니다.
- CQL의 keyspace는 SQL의 database와 비슷한 개념입니다.
// 키스페이스(Keyspace) 생성 CREATE KEYSPACE [ IF NOT EXISTS ] keyspace_name WITH options // 키스페이스 옵션 변경 ALTER KEYSPACE keyspace_name WITH options // 키스페이스 삭제 DROP KEYSPACE [ IF EXISTS ] keyspace_name
- static
- Table의 Column에 static 옵션을 정의하면, 마지막에 입력된 같은 파티션의 row의 영향을 받아 기존 row의 static Column 값도 변경됩니다.
cqlsh $ describe ktable; CREATE TABLE ks test.ktable ( k1 int, k2 int, k3 int, k4 text, s text static, PRIMARY KEY (k1, k2, k3, k4) ); insert into ktable (k1, k2, k3, k4, s) values (1,1,1,'value1','value1'); insert into ktable (k1, k2, k3, k4, s) values (2,2,2,'value2','value2'); insert into ktable (k1, k2, k3, k4, s) values (3,3,3,'value3','value3'); insert into ktable (k1, k2, k3, k4, s) values (3,4,4,'value4','value4'); select * from ktable;
k1 k2 k3 k4 s 1 1 1 value1 value1 2 2 2 value2 value2 3 3 3 value3 value4 3 4 4 value4 value4 - Batch
- 여러 insert, update, delete 명령을 수행할 수 있습니다.
(batch 수행 전)
k1 k2 k3 k4 s 3 3 3 value3 value3 2 2 2 value2 value2 4 5 5 value5 value5 1 1 7 value7 value7 4 4 4 value4 value4
begin batch insert into ktable2 (k1, k2, k3, k4, s) values (5,5,8,'value8','value8'); update ktable2 set s='newe value on batch' where k1=4 and k2=4; delete s from ktable2 where k1=4 and k2=5; insert into ktable2 (k1, k2, k3, k4, s) values (8,8,9,'value9','value9'); insert into ktable2 (k1, k2, k3, k4, s) values (8,8,10,'value10','value8'); apply batch;
(batch 수행 후)
k1 k2 k3 k4 s 3 3 3 value3 value3 5 5 8 value8 value8 2 2 2 value2 value2 8 8 9 value9 value9 8 8 10 value10 value9 4 5 5 value5 null 1 1 7 value7 value7 4 4 4 value4 new value on batch - 주석
- 해당 라인만 주석으로 만들고 싶다면 -- 또는 // 기호를 사용하면 됩니다.
- 멀티 라인을 주석처리하고 싶을다면 /* ... */ 기호를 사용하면 됩니다. - Identifier
- 큰 따옴표(" ")로 임의의 문자를 묶어 정의한 인용 식별자입니다.
- Identifier를 사용하여 keyspace, Table, Column 및 기타 Object를 식별할 수 있습니다.
- SELECT, With 키워드는 대소문자를 구분하지 않습니다.
- SQL과 유사한 방식으로 CQL shell (cqlsh)를 사용하여 CRUD 연산을 수행합니다. 다양한 데이터 타입을 지원하는데, 그 중에서 가장 일반적인 type은 Built-in type, 그리고 Collection, User-defined type 이렇게 세 가지 타입만 기억하면 충분합니다.
- Data Type
- Built-in data type
Data Type 저장 데이터 설명 Boolean True, False T/F 둘 중 하나만 선택 가능 Blob Binary large objects 16진수로 표기 ASCII 65(A), 97(a) 등 US-ASCII 문자열 Bigint -2^32 ~ 2^32 정수 (64비트) Counter 1, 2, 3, ... 증감 카운터 (64비트 정수) Timestamp 2020-01-03 01:02:00+0000 millisecond +0000(GMT) Double -2^32 ~ 2^32 실수 (64비트) Int -2^16 ~ 2^16 정수 Varchar string UTF8 encoded 문자열 - Collection data type
- Map : 정렬된 key-value 쌍의 집합(Collection)
Create table ucol1 ( id integer PRIMARY KEY, name varchar, items map<text, text> ); Insert into ucol1 (id, name, items) values(1, 'Marcel Ko', {'color' : 'blue', 'movie' : 'star wars'}); Update ucol1 set items = {'color' : 'green'} where id = 1; Update ucol1 set items['fruit'] = 'apple' where id = 1;
- Set : 하나 이상의 비중복 정렬된 요소들의 집합
Create table img1 ( id integer PRIMARY KEY, title varchar, tags set<text> ); Insert into img1 (id, title, tags) values(1, 'Dog', {'black', 'pet', 'smile'}); Update img1 set tags = {'white', 'pet', 'cute'} where id = 1; Update img1 set tags = tags + {'gray', 'small'} where id = 1; Update img1 set tags = tags - {'small'} where id = 1;
- List : 하나 이상의 중복과 순서를 허용하는 요소들의 집합 (최근에는 Map과 Set을 주로 사용) - User-defined data type (UDT)
- Create -> Alter -> Drop -> Describe 순서
- Create
create_type_statement ::= CREATE TYPE [ IF NOT EXISTS ] udt_name '(' field_definition ( ',' field_definition )* ')' field_definition ::= identifier cql_type
- Alter
alter_type_statement ::= ALTER TYPE udt_name alter_type_modification alter_type_modification ::= ADD field_definition | RENAME identifier TO identifier ( identifier TO identifier )*
- Drop
drop_type_statement ::= DROP TYPE [ IF EXISTS ] udt_name
- Describe
describe_type_statement ::= DESCRIBE TYPE udt_name
- 예제
Create type phone ( c_code smailint, number text, ) Create type address_book ( name text, city text, phones map<text, phone> ) Alter type address_book name city to new_city
- Built-in data type
- CQL KEY
- Partition Key
- 데이터를 분산 저장하기 위한 unique key로서 테이블을 구성할 때 반드시 1개 이상 지정해야 합니다. (여러 개 지정도 가능합니다.)
- 단일 Column 값 = row key
- 복합 Column 값(value:value) ":"로 조합 = row key - Cluster Key
- Row에 속한 Column을 정렬하기 위한 키 - Primary Key
- 테이블에서의 Row를 각자 unique하게 결정해주는 Column 또는 Column group
- Partition key + Cluster key
ex) PK(a,b,c) => a / bc
ex) PK((a,b),c) => a:b / c - Composite(Compound) Key
- 2개 이상의 CQL Column으로 구성된 Primary key
- Partition Key
3. Exercise
- Info2, Info3 데이터를 출력하는 select문 (파티션당 1행만 검색)
select * from user_info2 per partition limit 1; select * from user_info3 per partition limit 1;
- Info3에서 KOR/JPN에 포함되는 사람을 검색
select f_name, l_name from user_info3 where country in ('KOR', 'JPN');
- Info3의 전체 레코드 수와 num의 합/최소값/평균
select count(id) as count, sum(num) as sum, min(num) as min, avg(num) as avg from user_info3;
- 한국인이고, number가 30보다 큰 레코드를 검색
// allow filtering 안 적으면 성능 상의 문제로 에러가 뜸. select * from user_info3 where country='KOR' and num>30 allow filtering;
- KOR에 있는 s값을 'value8'로 수정하고, 30초 후에 null값으로 작성 (TTL 사용)
update user_info3 using ttl 30 set s='value8' where country='KOR';
- id=3의 f_name을 Scitt -> scott으로 수정
insert into user_info3 (id, l_name, f_name, country, birth, gender, s, num) values(3,'jeong','scott','USA','1967','M','value3',32);
- 나라가 USA인 s 컬럼을 삭제 (s는 static)
delete s from user_info3 where country='USA';
- 나라가 USA인 l_name 컬럼을 삭제 (l_name은 not static)
// 아래 query 는 에러 발생 delete l_name from user_info3 where country='USA';
참고자료
- https://www.kdata.or.kr/info/info_04_view.html?field=&keyword=&type=techreport&page=38&dbnum=176031&mode=detail&type=techreport
- https://en.wikipedia.org/wiki/Apache_Cassandra
- https://www.syncfusion.com/succinctly-free-ebooks/cassandra/introduction
반응형
'SQL > NoSQL' 카테고리의 다른 글
[데이터베이스/DB] NoSQL이란? (4-1) : mongoDB의 개념 및 구조, NoSQL간 차이점 (0) | 2021.10.27 |
---|---|
[데이터베이스/DB] NoSQL이란? (3-1) : 카산드라(Cassandra) 개념 및 장단점 (0) | 2021.09.15 |
[데이터베이스 DB] NoSQL이란? (2-3) : HBase 사용법 (feat. Hive & Impala) (0) | 2021.09.03 |
[데이터베이스 DB] NoSQL이란? (2-2) : HBase 사용법(Shell, command) (0) | 2021.09.02 |
[데이터베이스 DB] NoSQL이란? (2-1) : HBase의 개념/특징/아키텍처 (0) | 2021.09.01 |
댓글