월별 글 목록: 2010년 11월월

Cassandra.Client 풀링하기..

Cassandra.Client는 org.apache.cassandra.thrift 패키지의 클래스이고, 결국, Client는 Cassandra의 Inner 클래스가 됩니다..그리고, 위 패키지는 Thrift라는 데이타 serialize/deserialize 라이브러리(Google Protocol Buffers랑 비슷)를 통해서 전송될 데이타를 만들고, 전송된 데이타를 처리하고 있겠죵.. Cassandra의 언어별 클라이언트 라이브러리는 http://wiki.apache.org/cassandra/ClientOptions 페이지에 자세히 기술이 되어 있습니다.. 클라이언트 라이브러리들은 보통 Cassandra 서버에 붙는 Connection에 대한 풀링을 제공하는데, Connection 풀링은 org.apache.cassandra.thrift 패키지의 Cassandra.Client를 풀링해서 구현 할 수 있습니다. 
아래 코드는 Cassandra.Client의 풀링을 통한 Cassandra 서버의 연결에 대한 풀링기능을 제공하고 있습니다..^^

* CassandraClientArrayFactory.java



package net.sjava.cassandra.test;


import java.util.Random;
import java.util.concurrent.ConcurrentLinkedQueue;


import org.apache.cassandra.thrift.Cassandra;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;


/**
 * Cassandra.Client 풀링 클래스
 *
 * @author mcsong@gmail.com
 * @since 2010/11/30
 *
 */
public class CassandraClientArrayFactory {
 /**
  * host array
  */
 private static String[] hosts = “127.0.0.1,127.0.0.1”.split(“,”) ;
 /**
  * port
  */
 private static int port = 9160;
 /**
  * pooing count
  */
 private static int count = 10;
 
 //
 private static ConcurrentLinkedQueue<Cassandra.Client> clients = new  ConcurrentLinkedQueue<Cassandra.Client>();
 
 /**
  * Cassandra.Client를 생성한다.
  * @return
  * @throws Exception
  */
 private static Cassandra.Client createCassandraClient() throws Exception {
  int index = new Random().nextInt(hosts.length);
  TTransport socket = new TSocket(hosts[index], port);
  socket.open();
  return new Cassandra.Client(new TBinaryProtocol(socket, false, false));
 }


 /**
  * Cassandra.Client를 풀에서 가져온다.
  * @return
  * @throws Exception
  */
 public static Cassandra.Client poll() throws Exception {
  if (!clients.isEmpty() && clients.peek() != null)
   return clients.poll();
  
  return createCassandraClient();
 }
 
 /**
  * Cassandra.Client를 풀에 넣는다.
  * @param client
  * @throws Exception
  */
 public static void push(Cassandra.Client client) throws Exception {
  System.out.println(“channel size : ” + clients.size());
  if (clients.size() >= count) {
   client = null; // garbage
   return;
  }
  
  clients.offer(client);
 }
}




* CassandraClientArrayFactoryTest.java 



package net.sjava.cassandra.test;


import org.apache.cassandra.thrift.Cassandra;
import org.apache.cassandra.thrift.Column;
import org.apache.cassandra.thrift.ColumnPath;
import org.apache.cassandra.thrift.ConsistencyLevel;


import static net.sjava.cassandra.test.CassandraClientArrayFactory.poll;
import static net.sjava.cassandra.test.CassandraClientArrayFactory.push;


public class CassandraClientArrayFactoryTest {


 public static void main(String[] args) {
  
  String keyspace = “Keyspace1”;
  String columnFamily = “Standard2”;
  String key = “key1”;
  long timestamp = System.currentTimeMillis();
  
  Cassandra.Client client = null;
  
  try {
   client = poll();   
   for(int i=0; i < 15; i++)
    push(client);
     
   String value =”bbbbbbbbbbbbbbbbbbbbbbbbbbbbb”;
   ColumnPath cPath = new ColumnPath(columnFamily);
   cPath.setColumn(“name”.getBytes(“utf-8”));
   client.insert(keyspace, key, cPath, value.getBytes(“utf-8”), timestamp, ConsistencyLevel.ONE);
   Column col = client.get(keyspace, key, cPath, ConsistencyLevel.ONE).getColumn();
   System.out.println(“Column name: ” + new String(col.name, “utf-8”)); 
   System.out.println(“Column value: ” + new String(col.value, “utf-8”)); 
  
   value =”ccccccccccccccccccccccccccccccccccccccc”;
   long time2 = System.currentTimeMillis();
   client.insert(keyspace, key, cPath, value.getBytes(“utf-8”), time2, ConsistencyLevel.ONE);
   Column col2 = client.get(keyspace, key, cPath, ConsistencyLevel.ONE).getColumn();
   System.out.println(“Column2 name: ” + new String(col2.name, “utf-8”)); 
   System.out.println(“Column2 value: ” + new String(col2.value, “utf-8”)); 
  } catch(Exception e) {
   e.printStackTrace();
  } finally {
   if(client != null)
    try {
     push(client);
    } catch (Exception e) {
     e.printStackTrace();
    }
  }
 }


}


Cassandra simple insert/get 하기..

Client 객체는 기본적으로, 카산드라 클라이언트(Cassandra.Client) 생성 예제를 같이 사용하고 있습니다.
가장 기초적인 1개의 Column에 데이타 insert/get 하는 예제입니다..

package net.sjava.cassandra.test;import org.apache.cassandra.thrift.Column;
import org.apache.cassandra.thrift.ColumnPath;
import org.apache.cassandra.thrift.ConsistencyLevel;

public class CassandraTest {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub

CassandraClientFactory factory = CassandraClientFactory.getInstance();
String keyspace = “Keyspace1”;
String columnFamily = “Standard2”;
String key = “key1″;
long timestamp = System.currentTimeMillis();

String value =”aaaaaaaaaaaaaaaaaaa_bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb”;
try {
ColumnPath cPath = new ColumnPath(columnFamily);
cPath.setColumn(“name”.getBytes(“utf-8”));
factory.getClient().insert(keyspace, key, cPath, value.getBytes(“utf-8”), timestamp, ConsistencyLevel.ONE);
Column col = factory.getClient().get(keyspace, key, cPath, ConsistencyLevel.ONE).getColumn();
System.out.println(“Column name: ” + new String(col.name, “utf-8”));
System.out.println(“Column value: ” + new String(col.value, “utf-8″));

value =”aaaaaaaaaa”;

long time2 = System.currentTimeMillis();
factory.getClient().insert(keyspace, key, cPath, value.getBytes(“utf-8”), time2, ConsistencyLevel.ONE);
Column col2 = factory.getClient().get(keyspace, key, cPath, ConsistencyLevel.ONE).getColumn();
System.out.println(“Column2 name: ” + new String(col2.name, “utf-8”));
System.out.println(“Column2 value: ” + new String(col2.value, “utf-8”));
} catch(Exception e) {
e.printStackTrace();
}
}
}

 

관계를 좀 더 쉽게 풀어내는 방법 : Activity Stream ????

눈 앞으로 다가온 물리적 웹의 시대에서 Physical Web, Object, Activity 등의 새로운 개념을 읽고, 포스팅 하신분께 요청해서 정보도 받고 해서, 좀 더 자세히 Activity Stream이라는 것에 대해서 살펴 보았습니다.. 포스팅 하신분께 감사드립니다..

포스팅 하신 분의 도움을 받아서, 제가 파악한 내용은, http://activitystrea.ms/ 이 Object의 Activity에 대한 정의, 그 정의를 바탕으로 한 관계에 대한 포맷에 대한 표준(?)을 제시하고 있더군요.. ^^.

결국, 데이타를 synd하는 포맷을 정의하고, 포맷된 데이타를 통해서 Object간의 관계를 알 수 있을 거 같습니다. 물론, 위치 정보 까지도요… 지금 하는 프로젝트(소셜 합니다..ㅋㅋ)에 써먹기에 참 좋은데 말이죠…

여튼, 기존의 관계가 들어있지 않았던 많은 데이타들이, 관계, 위치등을 기반으로하는 포맷으로 변환이 되서 유저들간의 관계를 좀 더 쉽게 풀어 내기를 기대해 봅니다..

ant를 이용해서, lib 폴더의 denendency jar file을 manifest의 class-path에 손쉽게 추가하기…

자바로 프로젝트를 하다보면, 몇개의 라이브러리는 기본적으로 사용을 합니다.
좀 큰 프로젝트를 하다보면, 적게는 10개이상의 라이브러리를 사용할 텐데요.. 빌드를 하면서 의존 라이브러리를 일일히 manifest 파일에 기입을 해 주기는 매우 불편한 일이 되겠죠..
하지만, lib 폴더의 jar파일을 동적으로 로딩해서 jar로 배포할 때 넣어주면, 위 불편함이 순식간에 가시겠죵??ㅋㅋ

사용방법은 아래처럼 사용하면 됩니다.

<attribute name=”Class-Path” value=”lib/ conf/ ${lib-manifest-path}” />

아래 코드를 build.xml에 넣으시면 됩니다.

    <target name=”gen-manifest” description=”Generate CLASSPATH to use in manifest”>
        <pathconvert dirsep=’${file.separator}’ property=”full-lib-dir”>
            <path>
                 <pathelement path=”lib”/>
            </path>
        </pathconvert>

        <echo>full-lib-dir: ${full-lib-dir}</echo>

        <pathconvert pathsep=” ” dirsep=”/” property=”manifest-path”>
            <path>
                <fileset dir=”lib” includes=”*”/>
            </path>
            <map from=”${full-lib-dir}${file.separator}” to=””/>
        </pathconvert>

        <echo>manifest-path: ${manifest-path}</echo>
       
        <pathconvert pathsep=” ” dirsep=”/” property=”lib-manifest-path”>
            <path>
                <fileset dir=”lib” includes=”*”/>
            </path>
            <map from=”${full-lib-dir}${file.separator}” to=”lib/”/>
        </pathconvert>

        <echo>lib-manifest-path: ${lib-manifest-path}</echo>
    </target>

위 코드는 아래 링크에서 가져왔습니다. 너무 감사드립니다.. ^^

Ant: construct manifest classpath 

json java 라이브러리 google-gson의 기본 캐릭터셋은 utf-8 이군요..

웹에 데이타를 전송해 주기 위해서, 데이타를 캐시하고 있는 서버에서 데이타를 json 포맷으로 가지고 있습니다.
라이브러리는 google-gson을 사용합니다..  json simple이나 jacson json processor에 비해서 속도는 뒤 떨어지지만, library의 사용성(?), 편리함(?) 때문에 사용을 하고 있습니다.. 데이타 저장을 위해서 json 포맷이다 보니, character set에 따라 크기, 즉 메모리나 데이타의 전송량이 달라지기 때문에, utf-8로 인코딩을 하고 byte[]의 길이를 체크해 보니.. 사이즈가 똑 같네요.. ^^;;
흠.. 소스 뒤져보니, utf-8로 인코딩을 하네요.. ㅋㅋ

http://code.google.com/p/google-gson/
http://google-gson.googlecode.com/svn/tags/1.5/docs/javadocs/index.html
http://sites.google.com/site/gson/gson-user-guide