Cassandra使ってみた

2012-03-21T00:00:00+00:00 Cassandra Java

現状は概念までは説明出来ないので、あくまでお触り程度な所をメモる

インストール

http://cassandra.apache.org からダウンロード。一応、この記事の検証環境として1.0.8のバージョンを使用。んでtar.gzなりを展開後適当なディレクトリに配置して、そのディレクトリをCASSANDRA_HOMEってな感じで.bashrcなりに設定する。まぁそこら辺はCassandraに入ってるReadmeとかに書いてあるので

起動とその他もろもろ

起動する前にログとデータファイルを格納するディレクトリを作っておく

mkdir -p /var/{log,lib}/cassandra

# ※各ディレクトリの所有者関係も設定する

まずサーバーを起動。

cassandra -f

で起動出来る。-fは-foregroundの略称っぽい、指定しなかった場合にはCassandraDaemonがバックグランド動作になる模様。で起動すると、サーバーが9160なポートを開放する。これはAPI通信を行う際に利用するThriftサーバーのポートな模様。詳しくはログを嫁ということにしときます

んでクライアントから

cassandra-cli -h localhost```


な感じでcassandra-cliを使って接続する。でデータモデルを理解しないといけないが今回は詳細をぶっ飛ばして、とりあえずこんな感じになるっぽい↓


<img src="/images/2012/03/20120601181629.jpg" />


まぁKeyspaceがあって、そこにColumn Familyがあって更にその中にKey(以下省略


とりあえずColumn Familyを作ってみる


Keyspaceを作成create keyspace Keyspace1;# 作成したKeyspaceを使用する

use Keyspace1;

Column Familyを作る

create column family Sample with comparator = UTF8Type and keyvalidationclass = UTF8Type and defaultvalidationclass = UTF8Type ```

まぁこんな感じで作る。で最後の所ですが、作ったColumn Familyをdescribeしてみると

ColumnFamily: Sample
  Key Validation Class: org.apache.cassandra.db.marshal.UTF8Type
  Default column value validator: org.apache.cassandra.db.marshal.UTF8Type
  Columns sorted by: org.apache.cassandra.db.marshal.UTF8Type
  Row cache size / save period in seconds / keys to save : 0.0/0/all
  Row Cache Provider: org.apache.cassandra.cache.ConcurrentLinkedHashCacheProvider
  Key cache size / save period in seconds: 200000.0/14400
  GC grace seconds: 864000
  Compaction min/max thresholds: 4/32
  Read repair chance: 1.0
  Replicate on write: true
  Bloom Filter FP chance: default
  Built indexes: []
  Compaction Strategy: org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy

な感じになる(自分の環境の場合は)。でオプションを指定せずに「create column family Sample」だけにすると

ColumnFamily: Sample
  Key Validation Class: org.apache.cassandra.db.marshal.BytesType
  Default column value validator: org.apache.cassandra.db.marshal.BytesType
  Columns sorted by: org.apache.cassandra.db.marshal.BytesType
  Row cache size / save period in seconds / keys to save : 0.0/0/all
  Row Cache Provider: org.apache.cassandra.cache.ConcurrentLinkedHashCacheProvider
  Key cache size / save period in seconds: 200000.0/14400
  GC grace seconds: 864000  Compaction min/max thresholds: 4/32  Read repair chance: 1.0  Replicate on write: true  Bloom Filter FP chance: default  Built indexes: []  Compaction Strategy: org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy

まぁ色々変わってくるようになる。そこら辺は「help create column family」で別途確認と。んでデータを突っ込んでみる

use Keyspace1;
set Sample[test1][name] = "hoge";

で突っ込んだので

use Keyspace1;
get Sample[test1];

# 出力 => (column=name, value=hoge, timestamp=省略)

まぁこんな感じ。んじゃついでにJava側から操作してみる。Maven使いたいのでとりあえずpom.xmlを書く

pom.xml

<?xml version="1.0" ?>
<project
    xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <groupId>省略</groupId>
    <artifactId>省略</artifactId>
    <version>省略</version>
    <name>省略</name>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.2.1</version>
                <configuration>
                    <mainClass>Client</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>org.apache.cassandra</groupId>
            <artifactId>cassandra-all</artifactId>
            <version>1.0.7</version>
        </dependency>
    </dependencies>
</project>

んじゃJava側のClientクラスを書く

Client.java

import java.nio.ByteBuffer;
import java.io.UnsupportedEncodingException;
import org.apache.cassandra.thrift.Cassandra;
import org.apache.cassandra.thrift.ColumnOrSuperColumn;
import org.apache.cassandra.thrift.ColumnPath;
import org.apache.cassandra.thrift.ConsistencyLevel;
import org.apache.cassandra.thrift.Column;
import org.apache.cassandra.thrift.InvalidRequestException;
import org.apache.cassandra.thrift.NotFoundException;
import org.apache.cassandra.thrift.UnavailableException;
import org.apache.cassandra.thrift.TimedOutException;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransportException;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.TException;

public class Client {

    private static final String KEYSPACE = "Keyspace1";
    private static final String COLUMN_FAMILY = "Sample";
    private static final String COLUMN_FAMILY_KEY = "test1";
    private static final String COLUMN_FAMILY_KEY_COLUMN = "name";

    public static void main(String[] args) {
        TTransport transport = new TFramedTransport(new TSocket("localhost", 9160));
        TProtocol proto = new TBinaryProtocol(transport);

        try {
            transport.open();

            Cassandra.Client client = new Cassandra.Client(proto);
            client.set_keyspace(KEYSPACE);

            ColumnPath path = new ColumnPath(COLUMN_FAMILY);
            path.setColumn(stringToBuffer(COLUMN_FAMILY_KEY_COLUMN));

            ColumnOrSuperColumn result = client.get(stringToBuffer(COLUMN_FAMILY_KEY), path, ConsistencyLevel.ONE);
            Column column = result.column;

            String columnName = bufferToString(column.name);
            String columnValue = bufferToString(column.value);
            String output = String.format("%s[%s][%s] = %s", COLUMN_FAMILY, COLUMN_FAMILY_KEY, columnName, columnValue);

            System.out.println(output);
        } catch (TTransportException e) {
            e.printStackTrace();
        } catch (InvalidRequestException e) {
            e.printStackTrace();
        } catch (TException e) {
            e.printStackTrace();
        } catch (NotFoundException e) {
            e.printStackTrace();
        } catch (UnavailableException e) {
            e.printStackTrace();
        } catch (TimedOutException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } finally {
            transport.close();
        }
    }

    public static ByteBuffer stringToBuffer(String str) throws UnsupportedEncodingException {
        return ByteBuffer.wrap(str.getBytes("UTF-8"));
    }

    public static String bufferToString(ByteBuffer buffer) throws UnsupportedEncodingException {
        byte[] b = new byte[buffer.remaining()];
        buffer.get(b);

        return new String(b, "UTF-8");
    }
}

(ByteBufferな変換あれこれはCassandraにByteBufferUtilっていうのがあるのでそれを使うべきかと思われる)

あとはmvn compileしたあとにmvn exec:javaで実行してみる。現時点で勉強しているのはここまでなので終了乙

Hadoop+Cassandra (1) - MapperでCassandra - (非常に適当に)Android ICS SpellCheckerServiceを使ってみる