深入浅出cassandra 2 第一个可以运行的例子
在上一篇文章中,我们成功的建立了一个可以cassandra的实例,同时也让它成功的运行起来,下面的工作就是让我们来简单的操作一下这个
号称分布式的号称第二代的数据库系统。
本文主要关注两个部分,
1. 怎么写一个最简单cassandra的sample
2. 怎么去分析这个最简单的sample背后隐含的含义
步骤一:
1. 首先我们创建一个工程,然后将cassandra/lib目录下的包,导入到我们的工程中。
2. 非常重要的一点
编程接口Thrift的配置
使用下面的命令,获取Thrift的压缩包
wget -O thrift.tgz http://gitweb.thrift-rpc.org/?p=thrift.git;a=snapshot;h=HEAD;sf=tgz
如果使用Java语言,可以在解压Thrift后,到安装目录下的/lib/java目录,使用ant编译得到libthrift.jar
注意:
编译Java的jar时,需要用到ant,版本需要在1.7.1及以上,不然在编译时提示"not support nested 'typedef' element"的异常
而且在ant操作时,不能仅仅只拿出lib/java这个文件,须要在整个thrift这个大工程下ant
步骤二:
创建一个类,内容如下:
Java代码 :
package com.taobao.zhujiadun.basic; 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 org.apache.cassandra.thrift.InvalidRequestException; import org.apache.cassandra.thrift.NotFoundException; import org.apache.cassandra.thrift.TimedOutException; import org.apache.cassandra.thrift.UnavailableException; import org.apache.thrift.TException; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.transport.TSocket; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TTransportException; public class SampleOne { static Cassandra.Client cassandraClient; static TTransport socket; private static void init() throws TTransportException { // String server = "192.168.1.129"; String server = "localhost"; int port = 9160; /* 首先指定cassandra server的地址 */ socket = new TSocket(server, port); System.out.println(" connected to " + server + ":" + port + "."); /* 指定通信协议为二进制流协议 */ TBinaryProtocol binaryProtocol = new TBinaryProtocol(socket, false, false); cassandraClient = new Cassandra.Client(binaryProtocol); /* 建立通信连接 */ socket.open(); } public static void main(String[] args) throws TException, TimedOutException, InvalidRequestException, UnavailableException, NotFoundException { /* 初始化连接 */ init(); /* 选择需要操作的Keyspaces, 可以理解成数据库的表 */ String keyspace= "Keyspace1"; String row = "employee"; /* 创建一个Table Name */ String tableName = "Standard2"; /* 插入一条记录 */ insertOrUpdate(keyspace,tableName,row,"name","happy birthday!",System.currentTimeMillis()); /* 删除一条记录 */ //delete(keyspace,tableName,row,"name",System.currentTimeMillis()); /* 获取一条记录 (由于插入和删除是同一条记录,有可能会检索不到哦!请大家主意!*/ Column column = getByColumn(keyspace,tableName,row,"name", System.currentTimeMillis()); System.out.println("read row " + row); System.out.println("column name " + ":" + new String(column.name)); System.out.println("column value" + ":" + new String(column.value)); System.out.println("column timestamp" + ":" + (column.timestamp)); close(); } /** * 插入记录 */ public static void insertOrUpdate(String tableSpace,String tableName, String rowParam,String ColumnName,String ColumnValue,long timeStamp) throws TException, TimedOutException, InvalidRequestException, UnavailableException, NotFoundException{ /* 选择需要操作的Keyspaces, 存放数据表所在的空间位置 */ String keyspace= tableSpace; /* 数据所在的行标 */ String row = rowParam; /* 创建一个column path */ ColumnPath col = new ColumnPath(tableName); col.setColumn(ColumnName.getBytes()); /* 执行插入操作,指定keysapce, row, col, 和数据内容, 后面两个参数一个是timestamp, 另外一个是consistency_level * timestamp是用来做数据一致性保证的, 而consistency_level是用来控制数据分布的策略,前者的理论依据是bigtable, 后者的理论依据是dynamo */ cassandraClient.insert(keyspace, row, col,"i don't know".getBytes(), System.currentTimeMillis(), ConsistencyLevel.ONE); } /** * 删除记录 */ public static void delete(String tableSpace,String tableName, String rowParam,String ColumnName,long timeStamp) throws TException, TimedOutException, InvalidRequestException, UnavailableException, NotFoundException{ /* 选择需要操作的Keyspaces, 存放数据表所在的空间位置 */ String keyspace= tableSpace; /* 数据所在的行标 */ String row = rowParam; /* 创建一个column path */ ColumnPath col = new ColumnPath(tableName); col.setColumn(ColumnName.getBytes()); /* 执行删除操作,指定keysapce, row, col, 后面两个参数一个是timestamp, 另外一个是consistency_level * timestamp是用来做数据一致性保证的, 而consistency_level是用来控制数据分布的策略,前者的理论依据是bigtable, 后者的理论依据是dynamo */ cassandraClient.remove(keyspace, row, col, System.currentTimeMillis(), ConsistencyLevel.ONE); } /** * 获取数据 */ public static Column getByColumn(String tableSpace,String tableName, String rowParam,String ColumnName,long timeStamp) throws TException, TimedOutException, InvalidRequestException, UnavailableException, NotFoundException{ /* 选择需要操作的Keyspaces, 存放数据表所在的空间位置 */ String keyspace= tableSpace; /* 数据所在的行标 */ String row = rowParam; /* 创建一个column path */ ColumnPath col = new ColumnPath(tableName); col.setColumn(ColumnName.getBytes()); /* 执行查询操作,指定keysapce, row, col, timestamp * timestamp是用来做数据一致性保证的, 而consistency_level是用来控制数据分布的策略,前者的理论依据是bigtable, 后者的理论依据是dynamo */ Column column = cassandraClient.get(keyspace, row, col, ConsistencyLevel.ONE).column; return column; } /** * 关闭当前的远程访问连接 */ public static void close() { socket.close(); } }
为了比较好的理解这些名词解释,我们先看看cassandra的数据模型:
Cassandra 的数据模型的基本概念:
keyspace:
用于存放 ColumnFamily 的容器,相当于关系数据库中的 Schema 或 database,
ColumnFamily :
用于存放 Column 的容器,类似关系数据库中的 table 的概念。
SuperColumn :
它是一个特列殊的 Column, 它的 Value 值可以包函多个 Column
{ // 这是一个SuperColumn name: "李明杰", // 包含一系列的Columns value: { street: {name: "street", value: "1234 x street", timestamp: 123456789}, city: {name: "city", value: "san francisco", timestamp: 123456789}, zip: {name: "zip", value: "94107", timestamp: 123456789}, } }
Columns:
Cassandra 的最基本单位。由 name , value , timestamp 组成
cassandra的数据模型主要就是由上述几种模型构建而成的,很简单吧,的确是这样,最大的好处就是读写数据的API非常简单.
1. 首先我们来说说keyspace是个什么玩意
打开storage-conf.xml,找到<Keyspaces>这个xml节点,我们可以看到一段对keyspace的说明, 如下:
ColumnFamily在cassandra中概念最接近关系型数据库中的表。而keyspace则是一堆ColumnFamily的集合。如果说ColumnFamily是表,那么我们可以将keyspace称之库
我们来看一段简单的配置。
Java代码
<Keyspaces> <Keyspace Name="Keyspace1"> <ColumnFamily CompareWith="BytesType" Name="Standard1"/> <ColumnFamily CompareWith="UTF8Type" Name="Standard2"/> <ColumnFamily CompareWith="TimeUUIDType" Name="StandardByUUID1"/> <ColumnFamily ColumnType="Super" CompareWith="UTF8Type" CompareSubcolumnsWith="UTF8Type" Name="Super1" Comment="A column family with supercolumns, whose column and subcolumn names are UTF8 strings"/> </Keyspace> <Keyspace Name="ahuaxuan"> <ColumnFamily CompareWith="BytesType" Name="test1"/> <ColumnFamily CompareWith="UTF8Type" Name="test2"/> <ColumnFamily ColumnType="Super" CompareWith="UTF8Type" CompareSubcolumnsWith="UTF8Type" Name="Super1" Comment="A column family with supercolumns, whose column and subcolumn names are UTF8 strings"/> </Keyspace> </Keyspaces>
这段配置表示我们的cassandra中有多个keyspace, 而每个keyspace下又有多个ColumnFamily.