読者です 読者をやめる 読者になる 読者になる

cassandraにscala REPLからアクセスする

セブンイレブンにいって買い物したらAKB48キャンペーンでコーヒーとお茶がもらえたので、今日が私のcassandra記念日。


ということで、cassandraにscala REPLからアクセスしてみます。


とりあえずインストールから。一応結構前に触ってたのですが、会社のPCで遊んでたときなので、自宅で環境つくるのは初めてだったり。そんな僕にもmacportsがありますので。

sudo port install cassandra

わーい一瞬だ。

で、cassandraのサーバーをあげます。

sudo cassandra -f

意味わかってないですが、-fをつけないとなぜかconnection refusedとか言われてはまりました。あとでちゃんと調べます。


ではscalaからつなぎます。

いちおう、scalaははいっている前提で。portのupdateがきてないぽいのでRCですが、scala-2.8じゃないと動かないのでそこだけ気をつけてください。

marblejenka:cassandra-scala marblejenka$ scala-2.8
Welcome to Scala version 2.8.0.RC7 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_20).
Type in expressions to have them evaluated.
Type :help for more information.

scala> :load jarloader.scala
Loading jarloader.scala...

〜中略

scala> import org.apache.cassandra.thrift._
import org.apache.cassandra.thrift._

scala> import org.apache.thrift._
import org.apache.thrift._

scala> import org.apache.thrift.protocol._
import org.apache.thrift.protocol._

scala> import org.apache.thrift.transport._
import org.apache.thrift.transport._


scala> val transport = new TSocket("localhost", 9160)
transport: org.apache.thrift.transport.TSocket = org.apache.thrift.transport.TSocket@2ccf0384

scala> val protocol = new TBinaryProtocol(transport)
protocol: org.apache.thrift.protocol.TBinaryProtocol = org.apache.thrift.protocol.TBinaryProtocol@2efe83e5


scala> transport open

scala> val client = new Cassandra.Client(protocol)
client: org.apache.cassandra.thrift.Cassandra.Client = org.apache.cassandra.thrift.Cassandra$Client@12dc60af


scala> val key = "sample1"
key: java.lang.String = sample1

scala> val colmunName = "hoge"
colmunName: java.lang.String = hoge

scala> val value = "sample value"
value: java.lang.String = sample value

scala> val timestamp = System.currentTimeMillis
timestamp: Long = 1279480449994

scala> val columnPath = new ColumnPath("Standard1")  
columnPath: org.apache.cassandra.thrift.ColumnPath = ColumnPath(column_family:Standard1)

scala> columnPath setColumn(colmunName.getBytes)
res1: org.apache.cassandra.thrift.ColumnPath = ColumnPath(column_family:Standard1, column:68 6F 67 65)


scala> client insert("Keyspace1", key, columnPath, value.getBytes, timestamp ,ConsistencyLevel.ONE)


scala> transport.flush

scala> transport.close

意味わかってないですが、つながりました。わーい。サンプルは、こちらを参考にしています。

insertしているので、中身が入っているか見てみます。残念なことに、scala(というかjava)からselect(get?)する方法がわかっていないので、cassandra-cliから見てみます。

marblejenka:~ marblejenka$ cassandra-cli --host localhost --port 9160
Connected to: "Test Cluster" on localhost/9160
Welcome to cassandra CLI.

Type 'help' or '?' for help. Type 'quit' or 'exit' to quit.

cassandra> get Keyspace1.Standard1['sample1']
=> (column=686f6765, value=sample value, timestamp=1279479901736)
Returned 1 results.
cassandra>

はいってるっぽい。わーい。


なんでこんなことをしているかというと、まえに触ったときに、

While a useful tool for education and simple tests, cassandra-cli is ultimately limted by the fact that column names and values are binary, (and eventually keys will be as well, see CASSANDRA-767).
The current approach when writing consists of encoding column names as UTF8, and passing the value as a byte[] of the String parsed from the command. When performing a read, the column names outputted are the result of the toString() method of the comparator (the result of which is not always meaningful), and values are again treated as raw strings. This is almost certainly broken anywhere that the CF comparator is not UTF8Type and values are anything but strings.

One possible approach would be to follow HBase's lead and simply allow binary values to be encoded as strings (see: http://wiki.apache.org/hadoop/Hbase/Shell).

https://issues.apache.org/jira/browse/CASSANDRA-912

のJIRAをちらみしていて、cassandraわからんからやっぱりよくわかってないのですが、それっぽいCLIが欲しいならscala REPL拡張すればいいじゃんとか思ったのです。


どういうユースケースでcassandra-cliがしょぼいのかはろくに使ってないのでわかってないですが、AKB48クラウド説の提唱者@ryu_kobayashiさんとこないだ飲んだときは、こんなのがあってもいいかなという僕の問いに割といい感じですよと言ってくれたので、もしかしたら便利なのかもしれません。


こんなものもつくってみたので、面白そうだったらいろいろ便利にしてみたいです。