요즘 화두가 되고 있는 NoSQL 제품중에서 유명한 Cassandra 를 한번 사용해 보기 위해 관련 자료를 찾았으나 다 이전 버전에 관한 내용만 있더군요. 어렵사리 0.7.x에서 동작하는 예제를 만들어 보았습니다. 저는 0.7.2 버전을 사용하였습니다.
Cassandra에 대한 설명은 : 다른 사이트나 http://blog.naver.com/PostView.nhn?blogId=naverdev&logNo=120116325495&redirect=Dlog&widgetTypeCall=true 를 참고해주세요. 단 예제는 제외!!
본격적으로 삽질을 해보니 이전버전에 비하여 XML 설정에서 YAML 기반 설정으로 바뀌었고 API의 사용법이 바뀌었습니다.
코딩에 앞서 몇 가지 라이브러리를 클래스 패스에 추가해야 합니다. 모두 cassandra의 lib 디렉토리에 있습니다.
apache-cassandra-0.7.2.jar
libthrift-0.5.jar
log4j-1.2.16.jar
slf4j-api-1.6.1.jar
slf4j-log4j12-1.6.1.jar
아래는 예제 소스입니다.
import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; import org.apache.cassandra.thrift.Cassandra; import org.apache.cassandra.thrift.Column; import org.apache.cassandra.thrift.ColumnOrSuperColumn; import org.apache.cassandra.thrift.ColumnParent; import org.apache.cassandra.thrift.ColumnPath; import org.apache.cassandra.thrift.ConsistencyLevel; import org.apache.cassandra.thrift.InvalidRequestException; import org.apache.cassandra.thrift.NotFoundException; import org.apache.cassandra.thrift.TimedOutException; import org.apache.cassandra.thrift.UnavailableException; import org.apache.thrift.TException; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.transport.TFramedTransport; import org.apache.thrift.transport.TSocket; import org.apache.thrift.transport.TTransport; public class CassandraTest { private TTransport framedTransport; private Cassandra.Client client; private String keyspace = "ggungs"; private String columnFamily = "friend"; // Cassandra에 연결 후 Client 저장 private void open() throws InvalidRequestException, TException { this.framedTransport = new TFramedTransport(new TSocket("localhost", 9160)); TProtocol framedProtocol = new TBinaryProtocol(framedTransport); this.client = new Cassandra.Client(framedProtocol); framedTransport.open(); client.set_keyspace(keyspace); } private void close() { framedTransport.close(); } public void insert() throws InvalidRequestException, UnavailableException, TimedOutException, TException, NotFoundException { byte[] Key = getUTF8("김동동"); long timestamp = System.currentTimeMillis(); ColumnParent cp = new ColumnParent(columnFamily); Column c1 = new Column(ByteBuffer.wrap(getUTF8("주소")), ByteBuffer.wrap(getUTF8("서울")), timestamp); Column c2 = new Column(ByteBuffer.wrap(getUTF8("핸드폰")), ByteBuffer.wrap(getUTF8("010-0000-0000")), timestamp); client.insert(ByteBuffer.wrap(Key), cp, c1, ConsistencyLevel.ONE); client.insert(ByteBuffer.wrap(Key), cp, c2, ConsistencyLevel.ONE); } public void get() throws InvalidRequestException, UnavailableException, TimedOutException, TException, NotFoundException { byte[] userIDKey = getUTF8("김동동"); ColumnPath cPath = new ColumnPath(columnFamily); cPath.setColumn(ByteBuffer.wrap(getUTF8("주소"))); ColumnOrSuperColumn cos = client.get(ByteBuffer.wrap(userIDKey), cPath, ConsistencyLevel.ONE); Column col=cos.column; System.out.println("Name : " + getString(col.getName())); System.out.println("Value : " + getString(col.getValue())); } private byte[] getUTF8(String s) { try { return s.getBytes("utf-8"); } catch (UnsupportedEncodingException e) { return null; } } private String getString(byte[] b) { try { return new String(b, "utf-8"); } catch (UnsupportedEncodingException e) { return null; } } public static void main(String[] args) { try { CassandraTest ct = new CassandraTest(); ct.open(); ct.insert(); ct.get(); ct.close(); } catch(Exception e) { e.printStackTrace(); } } }
이렇게 하고 나면 아마 keyspace가 존재하지 않는다는 예외가 발생합니다. keyspace를 만들지 않았기 때문인데요. cassandra-cli를 실행하여 keyspace 및 column family를 생성하면 됩니다.
connect localhost/9160;
create keyspace ggungs;
use ggungs;
create column family friend;
로컬호스트에 연결하여 ggungs keyspace를 생성하고 생성한 keyspace를 이용합니다. 그리고 friend라는 column family를 생성하는 것입니다.
이렇게 keyspace와 column family를 생성하고 나면 예외없이 주소에 대한 값이 출력될 것입니다.
cli에서는 어떻게 보일까요? list 명령어로 확인하면 아래와 같이 내용이 나옵니다.
첫번째 컬럼은 주소, 두번째 컬럼은 핸드폰에 대한 내용이겠군요!!