さくらでcassandra Javaからアクセスしてみる



javaからcassandraにアクセスしてみて、データ操作を試してみる。

必要なjarを準備する

 apache-cassandra-0.6.8-bin.tar.gzから必要なjarを抜き出しクラスパスに含める。

 apache-cassandra-0.6.8.jar
 libthrift-r917130.jar
 log4j-1.2.14.jar
 (slf4jも必要っぽいですが、Eclipseで既にクラスパスに通しているので
  省いています。)

 

thriftを利用してアクセスしてみる

Cassandraの実装(クライアントとの通信)は、Thrift(スリフト)をベースに作られているっぽいです。
Thriftは、RPCフレームワークです。

java からCassandraにアクセスするには、下記の形で、接続することができます。

 import org.apache.cassandra.thrift.Cassandra;
 import org.apache.cassandra.thrift.ColumnPath;
 import org.apache.cassandra.thrift.ConsistencyLevel;
 import org.apache.thrift.protocol.TBinaryProtocol;
 import org.apache.thrift.protocol.TProtocol;
 import org.apache.thrift.transport.TSocket;
 import org.apache.thrift.transport.TTransport;
 
 // Thrift を使用して Cassandra に接続
 TTransport port = new TSocket("localhost", 9160);
 TProtocol protocol = new TBinaryProtocol(port);
 Cassandra.Client client = new Cassandra.Client(protocol);
 port.open();
 
 // クラスタ名の表示
 System.out.printf("Cluster name : [%s]\n", client.describe_cluster_name());
 
 // バージョンの表示
 System.out.printf("Version : [%s]\n", client.describe_version());
 
 // 接続中クラスタの全キースペースを取得
 for (String keyspace : client.describe_keyspaces()) {
  // キースペース名の表示
  System.out.printf("Keyspace : [%s]\n", keyspace);
  
  // キースペース内の全 Column Family の取得
  for (Map.Entry<String, Map<String, String>> entry : client.describe_keyspace(keyspace).entrySet()) {
  
  System.out.printf("\tColumn Family : [%s]\n", entry.getKey());
  for (Map.Entry<String, String> innerEntry : entry.getValue().entrySet()) {
   System.out.printf("\t\t[%s]:[%s]\n", innerEntry.getKey(), innerEntry.getValue());
  }
  System.out.println(" -- ");
 }

javaからcassandraのデータを読み込んでみる。

コマンドラインから、手始めに読み込みの為のサンプルデータを設定しておく。

cassandra-cliを利用して、データを登録します。

 $ cassandra-cli
 cassandra> connect localhost/9160
 Connected to: "Test Cluster" on localhost/9160
 cassandra> set Keyspace1.Standard2['michibatajessica']['first'] = 'Michibata'
 cassandra> set Keyspace1.Standard2['michibatajessica']['last'] = 'Jessica'
 cassandra> set Keyspace1.Standard2['michibatajessica']['age'] = '25'

 念のため、登録されているか確認
 cassandra> get Keyspace1.Standard2['michibatajessica']
 => (column=last, value=Jessica, timestamp=1291945890096000)
 => (column=first, value=Michibata, timestamp=1291945890083000)
 => (column=age, value=25, timestamp=1291945890915000)
 Returned 3 results.

データを読み込む実装

 // デフォルトで用意されている Keyspace と Column Family を使用する
 String keySpace = "Keyspace1";
 String columnFamily = "Standard2";
 
 // REAME.txt のサンプルで登録した key と column を取得する
 String key = "michibatajessica";
 String columnName = "first";
 
 // ColumnPath の作成
 ColumnPath columnPath = new ColumnPath(columnFamily);
 System.out.printf("columnPath %s", columnPath);
 System.out.println(" ");
 columnPath.setColumn(columnName.getBytes("UTF8"));
 //columnPath.setColumn("first1".getBytes("UTF8"));
 
 // 値の取得
 Column column = client.get(keySpace, key, columnPath, ConsistencyLevel.ONE).getColumn();

 System.out.printf("カラム名:[%s] 値:[%s] タイムスタンプ:[%s]",
          new String(column.name, "UTF8"),
          new String(column.value, "UTF8"),
          new Date(column.timestamp));
 System.out.println(" ");

こんな感じでデータが表示できる。

カラム名:[first] 値:[Michibata] タイムスタンプ:[Wed Feb 19 19:21:23 JST 42910] 

javaからcassandraにデータを書き込んでみる。

新規にデータを作成してみます。

 // デフォルトで用意されている Keyspace と Column Family を使用する
 String keySpace = "Keyspace1";
 String columnFamily = "Standard1";
 
 // README.txt で使用されているサンプルの key に適当な column と value を追加する
 String key = "jsmith";
 String columnName = "foo1";
 String value = "bar";
           
 // ColumnPath の作成
 ColumnPath columnPath = new ColumnPath(columnFamily);
 columnPath.setColumn(columnName.getBytes("UTF8"));
 
 // レコードを挿入
 client.insert(keySpace, 
        key, 
        columnPath, 
        value.getBytes("UTF8"), 
        System.currentTimeMillis(), 
        ConsistencyLevel.ONE);

javaからcassandraのデータを削除してみる。

削除したデータを削除してみます。

 // デフォルトで用意されている Keyspace と Column Family を使用する
 String keySpace = "Keyspace1";
 String columnFamily = "Standard1";
 
 String key = "jsmith";
 String columnName = "foo";
          
 // ColumnPath の作成(この場合 Standard1.jsmith
 ColumnPath columnPath = new ColumnPath(columnFamily);
 columnPath.setColumn(columnName.getBytes("UTF8"));
 
 // レコードを削除
 client.remove(keySpace, 
        key, 
        columnPath, 
        System.currentTimeMillis(), 
        ConsistencyLevel.ONE);

基本的な操作を試してみました。

おまけ

メモリ使用状況をアップしておきます。
(freeコマンドの内容です。)

total used free shared buffers cached
Mem: 510532 494792 15740 0 24972 36248
buffers/cache: 433572 76960
Swap: 2048276 326152 1722124

では!