본문 바로가기
SQL/NoSQL

[데이터베이스/DB] NoSQL이란? (3-2) : 카산드라(Cassandra) DB의 구조 및 CQL 사용법

by newstellar 2021. 9. 25.
반응형

 

 

[데이터베이스/DB] NoSQL이란? (3-1) : Cassandra/카산드라

[데이터베이스 DB] NoSQL이란? (2-3) : HBase 사용법 (feat. Hive & Impala) 2021.09.02 - [SQL/NoSQL] - [데이터베이스 DB] NoSQL이란? (2-2) : HBase 사용법(Shell, command) [데이터베이스 DB] NoSQL이란? (2-2..

newstellar.tistory.com

 

 

[데이터베이스 DB] NoSQL이란? (2-1) : HBase의 개념/특징/아키텍처

2021.09.01 - [SQL/NoSQL] - NoSQL이란? (1) : 개념 및 사용 목적, RDBMS와의 차이점 [데이터베이스 DB] NoSQL이란? (1) : 개념 및 사용 목적, RDBMS와의 차이점 학습목표 1. 빅데이터 처리를 위한 Hadoop 플랫폼..

newstellar.tistory.com

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 역할을 수행합니다.


 

  • Cassandra Cluster

    • Ring 형태로 각 노드에 데이터를 분산 저장합니다.

    • 분산 기준은 Partition Key

    • 데이터 hash 값을 기준으로 분산됩니다.

 

 

  • Write / Read data flow

    • Coordinator node
      - 클라이언트 요청을 처리합니다.

      - 어떤 node이든 Coordinator node가 될 수 있습니다.

      D가 Client Node가 되어 request를 핸들링하고 있습니다.



    • 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는 여러 노드에 접속하여 백그라운드에 남아 있는 모든 복제본을 체크한 뒤, 일치하지 않는 복제본에 대해 업데이트를 합니다.

 

 

  • Delete Data

    • Tombstone
      - 삭제된 Column을 나타내는 row의 marker 역할

      - 표시된 Column들은 바로 삭제되지 않고, 시간이 지나 SSTable들이 compaction 진행될 때 사용합니다.
      (장애 발생 후에 다시 복구하는 Node에 의해 Side-effect가 발생하기도 합니다.)



    • Compaction
      - SSTable을 병합/정렬하여 새로운 SSTable을 생성합니다.

      - 필요한 검색 Query 횟수를 줄여 공간을 확보하고 성능을 향상시킬 수 있습니다.

      - Key 병합, Column 병합, tombstone 삭제, 새로운 index 등

 


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 키워드는 대소문자를 구분하지 않습니다.


  • 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​

 

  • 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

 

 


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
반응형

댓글