cassandra 2.0 - cql 체험기

nosql 2013. 10. 25. 19:40


1. cassandra keyspace 생성 방법 변경

cassandra 2.0 의 cqlsh에서..

cassandra 1.x 과 같은 방식으로 keyspace를 만들면 다음과 같은 에러가 발생된다.


http://www.datastax.com/docs/1.1/references/cql/CREATE_KEYSPACE

http://wiki.apache.org/cassandra/CassandraCli


cqlsh> CREATE KEYSPACE test2

   ...   WITH strategy_class = NetworkTopologyStrategy

   ...   AND strategy_options:DC1 = 3 AND durable_writes=false;

Bad Request: line 3:22 mismatched input ':' expecting '='


cqlsh> CREATE KEYSPACE test2;

Bad Request: line 2:0 mismatched input ';' expecting K_WITH


cassandra 2.0에서 새롭게 keyspace 생성방법이 바뀌었다.


CREATE KEYSPACE testKeySpace  WITH replication = { 'class': 'SimpleStrategy',  'replication_factor' : 3 };


2. conditional schema도 추가되었다. 


cqlsh> CREATE KEYSPACE IF NOT EXISTS testKeySpace  WITH replication = { 'class': 'SimpleStrategy',  'replication_factor' : 3 };


cqlsh> DROP KEYSPACE IF EXISTS testKeySpace;


cqlsh) drop table if exists cf;




DML에도 추가 가능했다. 


cqlsh:testkeyspace1> insert into tableName (empId, age) values (1,10);

cqlsh:testkeyspace1>  insert into tableName (empId, age) values (2,11) if not exists;


 [applied]

-----------

      True



cqlsh:testkeyspace1> update tableName set age=33 where empId=2;

cqlsh:testkeyspace1> update tableName set age=44 where empId=2 if age=33;


 [applied]

-----------

      True


cqlsh:testkeyspace1> select * from tableName where empId=2;


 empid | age

-------+-----

     244


(1 rows)



drop table에서는 if를 쓸 수 없다.



cqlsh:testkeyspace1> drop table tableName if empId=2;

Bad Request: line 1:21 no viable alternative at input 'if'

cqlsh:testkeyspace1> drop table tableName;




***** (고민거리) *********************

## 1

But, 버그인지는 잘 모르겠으나,  local에 실행한 cassandra에서 keyspace with replication_factor=3 생성시에 if not exist 때문에 영향을 미칠 수 있다. replication_factor를 잘 정의한 다음에 conditional schema를 써야 한다. 



cqlsh:testkeyspace> insert into tableName (empId, age) values (1,10);

cqlsh:testkeyspace> insert into tableName (empId, age) values (2,11) if not exists;

Unable to complete request: one or more nodes were unavailable.






## 2

if 와 where 절이 동시에 사용되는 경우에 항상 완벽히 동작되지 않는다. cql에서는 if와 where절을 비교한다. 이럴 때는 약간 애매한 문법이다..


cqlsh:testkeyspace1> update tableName set age=33 where empId=2 if empId=2;

Bad Request: PRIMARY KEY part empid found in SET part


그리고, where절 대신 if문은 존재할 수 없다. 


cqlsh:testkeyspace1> update tableName set age=44 if age=44;

Bad Request: line 1:28 mismatched input 'if' expecting K_WHERE





3. alter table.. drop


cassandra 1.0/1.1 에서는 column family table의 일부 column을 drop할 수 없었으나, 2.0에서는 가능하다. 


cqlsh:testkeyspace> create table tableName( empId int PRIMARY KEY, age int, address text);

cqlsh:testkeyspace> alter table tableName drop address;

cqlsh:testkeyspace> 



4. trigger 사용

그동안 성능때문에 DB의 trigger를 사용하지 않는 한국의 관습(?)이 있다. 좋아보여도 대용량에서 Trigger의 성능은 테스트해봐야할듯..


http://www.datastax.com/dev/blog/cql-in-cassandra-2-0

https://git-wip-us.apache.org/repos/asf?p=cassandra.git;a=blob_plain;f=examples/triggers/src/org/apache/cassandra/triggers/InvertedIndex.java;hb=HEAD


Trigger를 사용해보려면 ITrigger를 상속받은 자바 클래스( org.apache.cassandra.triggers.InvertedIndex)를 하나 만들어 jar로 만든후 conf/trigger 밑에 복사해 두어야 한다. 


/apache-cassandra-2.0.1/conf/triggers$ ls -al

total 8

drwxr-xr-x@  3 knight  wheel  102  9 20 19:26 ./

drwxr-xr-x@ 13 knight  wheel  442  9 20 19:26 ../

-rw-r--r--@  1 knight  wheel   61  9 20 19:26 README.txt


README.txt 안에 "Place triggers to be loaded in this directory, as jar files." 라는 설명이 들어가 있다.


trigger를 아래와 create/drop가능하다. 

create tigger myTrigger on tableName using 'org.apache.cassandra.triggers.InvertedIndex'

drop trigger myTrigger on tableName



5. secondary index 사용 

1.x때는 primary key에 column family를 추가하여 secondary index를 사용했다. 


 create table tableName( empId int, age int, address text, primary key(empId, age));


2.0부터는 create index를 사용할 수 있다. 


cqlsh:testkeyspace1>  create table tableName( empId int PRIMARY KEY, age int, address text);

cqlsh:testkeyspace1> create index on tableName(age);



6. select .. as 사용 가능 

cqlsh:testkeyspace1>  insert into tableName (empId, age) values (1,10);

cqlsh:testkeyspace1> select * from tableName;


 empid | address | age

-------+---------+-----

     1 |    null10


(1 rows)


cqlsh:testkeyspace1> select empId as emp_id, age as age_data  from tableName;


 emp_id | age_data

--------+----------

      1 |       10


(1 rows)





7. cql문에서 limit과 ttl 사용 가능


cqlsh:testkeyspace1> select * from tableName limit 1;


 empid | address | age

-------+---------+-----

     1 |    null10


(1 rows)


cqlsh:testkeyspace1> update tableName using ttl 1 set age=20 where empid=1;

cqlsh:testkeyspace1> select * from tableName;


(0 rows)




Posted by '김용환'
,