반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 받은 트랙백

글 보관함


Getting Started with Apache Cassandra and Java (Part II)

  By Rebecca Mills, Junior Apache Cassandra Evangelist (@RebccaMills)



Requirements

이 강좌를 따라하시려면 Cassandra instance를 이미 가동한 상태여야 합니다. (작은 클러스터면 더 좋습니다.) Datastax Java Driver 도 인스톨 하세요. (refer to Part 1), 그리고 다음 10분 강좌를 마치시면 좋습니다.
http://www.PlanetCassandra.org/try-cassandra


Try it out

이 예제는 간단한 console application을 만드는 겁니다. Part 1 에서 이미 기본적인것은 다 완료 됐습니다. 이 글에서는 connection policies, prepared statements 그리고 query builder 등에 대해서 알아보겠습니다. 텍스트 에디터를 열어서 sinble main method 가 있는 이름이 GettingStartedTwo 인 클래스를 생성하세요.


public class GettingStartedTwo {

public static void main(String[] args) {

        Cluster cluster;
        Session session;
        ResultSet results;
        Row rows;

이제 cluster에 접속하고 session instance를 생성하겠습니다.

// Connect to the cluster and keyspace "demo"
Cluster cluster = Cluster.builder()
                  .addContactPoint("localhost")
                  .build();
Session session = cluster.connect("demo");


여기서 single instance 대신에 cluster 를 실행하겠습니다. 실패할 경우를 대비해서 적당한 장소에 safeguard를 넣겠습니다. 이 작업은 RetryPolicy 를 사용해서 할 겁니다. retry policy 는 시간이 초과되거나 node 접속이 가능하지 않을 때 반응할 수 있는 디폴트 behavior 가 가능하도록 합니다. DefaultRetryPolicy 를 사용하면 디폴트를 사용합니다.

    * read 시 여러번 반복했지만 데이터를 받지 못할 때

    * write 시 정해진 시간안에 batch statements에 의해 사용되는 log 를 writing 하는게 완료되지 않을 때

cluster = Cluster
    .builder()
    .addContactPoint("192.168.0.30")
    .withRetryPolicy(DefaultRetryPolicy.INSTANCE)
    .build();
session = cluster.connect("demo");

load balancing policy는 어떤 node 가 해당 쿼리에 대해 반응하고 작동할 것인가를 결정해 줍니다. client 는 어떤 node 에서도 read 와 write를 할 수 있습니다. 이것이 어떤 경우에는 효율적이지 않을 수 있습니다. 만약에 어떤 node 가 다른 node에서 가능한 read나 write를 하라는 요청을 받았다면 그 노드는 해당 요청에 대해 처리될 수 있도록 추가 작업이 필요합니다. 이런 경우를 다루기 위해 load balancing을 사용할 수 있습니다. TokenAwarePolicy 는 해당 요청이 primary key에 의해 지정된 data에 대해 해당 node로 가던가 아니면 요청을 적당한 노드로 복제하던가 하는 작업을 하게 될 겁니다. TokenAwarePolicy 를 사용할 때 DCAwareRoundRobinPolicy 를 사용하고 있는데요. 이는 그 요청이 local datacenter에서 수행될 수 있도록 관리하게 됩니다. 지금 현재 우리는 하나의 local cluster 만 가지고 있지만 그 다음 단계인 multi-datacenter 로 확장하게 될 경우 이러한 기능을 사용하는 것은 아주 바람직한 방법이라고 할 수 있습니다.

cluster = Cluster
        .builder()
        .addContactPoint("192.168.0.30")
        .withRetryPolicy(DefaultRetryPolicy.INSTANCE)
        .withLoadBalancingPolicy(
                         new TokenAwarePolicy(new DCAwareRoundRobinPolicy()))
        .build();
session = cluster.connect("demo");




이제 demo 키스페이스에 연결 됐습니다. users 테이블에 user를 입력해 봅시다. Part 1 에서 이미 다뤘던 내용입니다. 여기서는 Part 1과는 약간 다른 방법을 사용할 건데요. prepared statement를 사용할 겁니다. 이는 데이터베이스에 데이터를 넣고 뺄 때 좀 더 scure 하고 더 좋은 performance를 보여줄겁니다. Prepared statement는 cluster에 의해 한번만 parse 되어야 합니다. 그리고 나서 쿼리가 변수에 대입되고 그 변수를 이용해서 해당 쿼리 (statement)를 실행해서 cluster로부터 데이터를 읽고 쓰게 됩니다.


// Insert one record into the users table
        PreparedStatement statement = session.prepare(

        "INSERT INTO users" + "(lastname, age, city, email, firstname)"
                + "VALUES (?,?,?,?,?);");

        BoundStatement boundStatement = new BoundStatement(statement);

        session.execute(boundStatement.bind("Jones", 35, "Austin",
                "bob@example.com", "Bob"));


Java driver를 사용하면 쉽게 해당 user를 다시 받을 수 있습니다. Part 1에서는 CQL의 string representation을 사용했었습니다. 여기서는 같은 것을 Query Builder로 할 겁니다. 이 방법은 잠재적인 CQL injection attack에 대해 좀 더 secure 한 방법으로 그 위험성을 없앨수 있는 방법입니다.


// Use select to get the user we just entered
        Statement select = QueryBuilder.select().all().from("demo", "users")
                .where(eq("lastname", "Jones"));
        results = session.execute(select);
        for (Row row : results) {
            System.out.format("%s %d \n", row.getString("firstname"),
                    row.getInt("age"));
        }

이제 Bob의 생일이니까 나이를 한살 더 올리는 update를 실행하겠습니다.

// Update the same user with a new age
        Statement update = QueryBuilder.update("demo", "users")
                .with(QueryBuilder.set("age", 36))
                .where((QueryBuilder.eq("lastname", "Jones")));
                        session.execute(update);
// Select and show the change
        select = QueryBuilder.select().all().from("demo", "users")
                .where(eq("lastname", "Jones"));
        results = session.execute(select);
        for (Row row : results) {
            System.out.format("%s %d \n", row.getString("firstname"),
                    row.getInt("age"));


                    이제 테이블에서 Bob을 delete 합시다. 그리고 나서 users 테이블에 있는 남아있는 데이터를 모두 print 하겠습니다. Bob의 정보는 delete 됐으니까 더이상 볼 수 없을 겁니다. (이외에 다른 정보가 이전에 입력돼 있다면 그 정보는 보여질 겁니다.)

// Delete the user from the users table
           Statement delete = QueryBuilder.delete().from("users")
                .where(QueryBuilder.eq("lastname", "Jones"));
        results = session.execute(delete);
        // Show that the user is gone
           select = QueryBuilder.select().all().from("demo", "users");
        results = session.execute(select);
        for (Row row : results) {
            System.out.format("%s %d %s %s %s\n", row.getString("lastname"),
                    row.getInt("age"), row.getString("city"),
                    row.getString("email"), row.getString("firstname"));
        }

작업이 끝나면 반드시 connection을 끊어 주세요.

// Clean up the connection by closing it
cluster.close();
    }
}




CQL은 SQL 과 아주 유사합니다. 대부분의 SQL syntax가 CQL에서도 사용됩니다. 만역 관계형 데이터베이스에 대한 사전 지식이 있다면 데이터에 대한 쿼리를 이해하시기 쉬울 겁니다.

이제 Cassandra cluster에 연결하고 데이터베이스에 대해 쿼리를 실행시키면서 관리하는 방법을 배웠습니다. 이 글을 통해 Java Driver를 사용해서 Cassandra를 사용하는 것이 얼마나 쉬운일인지 이해하셨으면 합니다. 전체 console application 에 대한 샘플 코드는 이곳에서 받으실 수 있습니다.

반응형

Comment