SlideShare une entreprise Scribd logo
1  sur  37
Apache Cassandra
   Apache Cassandra 是一套开源分布式数据库管理系统。它最初由 Facebook 开发,
用于储存特别大的数据。


主要特性:

  ● 分布式
  ● 于 column 的结构化
  ● 高伸展性


   Cassandra 是一个混合型的非关系的数据库,类似于 Google 的
BigTable 。Cassandra 的主要特点就是它不是一个数据库,而是由一堆数据库节点共同
构成的一个分布式网络服务,对 Cassandra 的一个写操作,会被复制到其它节点上去,
对 Cassandra 的读操作,也会被路由到某个节点上面去读取。对于一个 Cassandra 群
集来说,扩展性能是比较简单的事情,只管在群集里面添加节点就可以了。
   Cassandra 的主要功能比 Dynamo (分布式的 Key-Value 存 储系统)更丰富,但
支持度却不如文档存储 MongoDB (介于关系数据库和非关系数据库之间的开源产品,
是非关系数据库当中功能最丰富,最像关系数据库的。支持的数据结构非常松散,是类
似 json 的 bjson 格式,因此可以存储比较复杂的数据类型。)
    Cassandra 最初由 Facebook 开发,后转变成了开源项目。它是一个网络社交云计
算方面理想的数据库。以 Amazon 专有的完全分布式的 Dynamo 为基础,结合了
Google BigTable 基于列族( Column Family )的数据模型。P2P 去中心化的存储。很多
方面都可以称之为 Dynamo 2.0 。

  和其它数据库比较, Cassandra 有三个突出特点:
  ■ 模式灵活 :使用 Cassandra ,像文档存储,你不必提前解决记录中的字段。
你可以在系统运行时随意的添加或移除字段。这是一个惊人的效率提升,特别是在大型
部署上。
  ■ 真正的可扩展性 : Cassandra 是纯粹意义上的水平扩展。为给集群添加更多
容量,可以指向另一台计算机。你不必重启任何进程,改变应用查询,或手动迁移任何
数据。
  ■ 多数据中心识别 :你可以调整你的节点布局来避免某一个数据中心起火,一
个备用的数据中心将至少有每条记录的完全复制。
  一些使 Cassandra 提高竞争力的其它功能:
  ■ 范围查询 :如果你不喜欢全部的键值查询,则可以设置键的范围来查询。
  ■ 列表数据结构 :在混合模式可以将超级列添加到 5 维。   对于每个用户的索引,
这是非常方便的。
  ■ 分布式写操作 :有可以在任何地方任何时间集中读或写任何数据。     并且不会有
任何单点失败。
Cassandra 分布式节点服务器的简单部署


文章分类 :数据库
Cassandra 作为目前很热门的一个 NOSQL 型数据库,引起了很多的关注。 NOSQL 感兴趣
                                         对
的  我  ,  也  来  作  了  一   次  简     单   的  测  试  。
废 话 不 多 说 , 下 面 就 来 介 绍 下 Cassandra 多 节 点 的 部 署 。

部               署            要         求        :
1.                              JDK1.6
2. OS : linux ,我在 windows 上实验过,不知道为啥一直没通( 7000 端口上只有 windows
的       发   包       ,     双       方   不   互   相         通       信   )
3.                      cassandra                 0.6

OK,基本的东西都有了,进入到 cassandra 的目录,首先需要修改一些相关的文件路径:
1.    log4j.properties        文      件    输   出      路       径  修  改
2. storage-conf.xml    CommitLogDirectory 和 DataFileDirectory 路 径 修 改


接 着 进 行 分 布 式 节 点 的 配 置 , 还 是 修 改 torage-conf.xml :
1.       <ClusterName>Test Cluster</ClusterName>
   这个要求所有节点的名字都相同,如果不相同,则报类似 AName != BName 的错误

2.   <ColumnFamily   Name="Standard1"    CompareWith="BytesType"/>
  配置 ColumnFamily 的一些属性,其中 name 是所要使用的 ColumnFamily 名称,可以多
个,客户端做 CRUD 操作时需要指定。注意所有的节点配置都需要一样(我就曾因配置不
一   致      出       过  ClassCastException  的      异      常       )

3.             <ReplicationFactor>2</ReplicationFactor>
     配置数据需要复制的数量,复制的策略分 RackUnawareStrategy 和 RackAwareStrategy 两
种      方    式   (       策   略    没    细   看   不    再        描   述   )

4.                         <Seeds>
                   <Seed>10.10.13.220</Seed>
                  <Seed>10.10.13.181</Seed>
                  <Seed>10.10.13.232</Seed>
                           </Seeds>
     这个是所有分布式服务器节点的 IP 地址,如上面配置了 3 个 IP 即 3 个 Cassandra 节点

5.                    <ListenAddress>10.10.13.220</ListenAddress>
                      <ThriftAddress>10.10.13.220</ThriftAddress>
  本节点监听客户端数据和与其他服务器节点通信的 IP 地址,只能为本机 IP,且不能为
127.0.0.1 或 localhost , 否 则 与 其 他 服 务 器 不 能 建 立 正 确 交 互
  此处的 IP 地址也可以不填,即值为空,则所有的节点配置都一样,更方便部署。
搞定 storage-conf.xml !下面的工作就是将所有的 Cassandra 服务器节点依次启动,通过日
志就可以看到相关的节点连接上了,日志为:
Log4j 代码

    1. INFO 13:04:52,098 Node /10.10.13.232 is now part of the cluster




到这里,Cassandra 分布式节点服务器的搭建就完成了。使用官网提供的客户端代码进行测

试 ,发 现数据已经提交到服务 器并且在多个节点间进行复制了


在这里抱怨一下:之前由于没有足够的服务器,使用 windowsXP+solaris 双节点进行测试,
          。 后来加 入 linux 后,solaris+linux 的方式却能正常走通,配置也都
发现怎么也建立不起来 。
是       一       样                                    的       。
有 空 研 究 下 为 何 在 我 的                          windows 上 不 支 持 。 。 。 。


参                   考               地                  址                 :
http://cassandra.apache.org/




如何安装和配置 Cassandra


文章分类 :数据库


Cassandra 属于最近比较流行的一款 NoSQL 数据库,http://nosql-
database.org/中给 NoSQL 的定义如下:

下一代的数据库产品应该具备这几点:非关系型的,分布式的,开源的,可
以线性扩展的。这类数据库最初的目的在于提供现代网站可扩展的数据库解
决方案。 这个运动开始于 2009 年初,目前正在迅速的发展。这种类型的数据库具
有:自由的 schema,数据多处备份,简单的编程 API,数据的最终一致
性保证等等。所以我们将这种类型的数据库称为 NoSQL(不仅仅是 SQL,全称为
“not only sql”)。

下面我们一起来看看如果分别在 Windows 和 Linux 环境下安装和部署
Cassandra。
在 Windows 上单机运行 Cassandra


大多数人使用的 OS 都是 Windows,所以如果只是想简单地测试一下
Cassandra,我们可以直接在安装好 JDK1.6 的 Windows 系统上安装 Cassandra,
并进行简单的测试。


1 下载 Cassandra


去 http://cassandra.apache.org/下载即可。目前最新的 beta 版本是 0.6.0
b3,但是我们安装使用的最新的 Release 版本 0.5.1。


2 安装 Cassandra


将下载的压缩包解压,假设解压的位置是 D:apache-cassandra-0.5.1。


1 修改 conf 目录下的 log4j.properties 文件:


log4j.appender.R.File=D:apache-cassandra-0.5.1logs


2 修改 conf 目录下的 storage-conf.xml 文件:


<CommitLogDirectory>D:apache-
cassandra-0.5.1commitlog</CommitLogDirectory>
<DataFileDirectories>
    <DataFileDirectory>D:apache-
cassandra-0.5.1data</DataFileDirectory>
</DataFileDirectories>
<CalloutLocation>D:apache-cassandra-0.5.1callouts</CalloutLocation>

<StagingFileDirectory>D:apache-
cassandra-0.5.1staging</StagingFileDirectory>
3 设置系统的环境变量:


CASSANDRA_HOME=D:apache-cassandra-0.5.1


3 启动 Cassandra


运行 bin 目录下的 cassandra.bat。如果看到:INFO - Starting up server
gossip,那么恭喜你,Cassandra 已经在你的本机启动起来了。


4 使用命令行进行简单的测试


运行 bin 目录下的 cassandra-cli.bat。输入:connect localhost 9160,连接
成功后可以看到下面的提示。

cassandra> connect localhost 9160
line 1:18 missing SLASH at '9160'
Connected to localhost/9160

然后,我们可以参考 README.txt 文件中提供的范例进行测试:

cassandra> set Keyspace1.Standard1['jsmith']['first'] = 'John'
Value inserted.
cassandra> set Keyspace1.Standard1['jsmith']['last'] = 'Smith'
Value inserted.
cassandra> set Keyspace1.Standard1['jsmith']['age'] = '42'
Value inserted.
cassandra> get Keyspace1.Standard1['jsmith']
  (column=age, value=42; timestamp=1249930062801)
  (column=first, value=John; timestamp=1249930053103)
  (column=last, value=Smith; timestamp=1249930058345)
Returned 3 rows.
cassandra>

你也可以根据这篇文章《谈谈 Cassandra 的客户端》中的内容测试一下如何使用
Java 编写简单的程序和 Cassandra 交互。
在 Linux 上运行 Cassandra 集群


如果需要真正在生产环境中使用 Cassandra,我们需要搭建一个 Cassandra 集群,
这样才能真正发挥出它作为 NoSQL 数据所应该具备的特性。

在 Linux 部署 Cassandra 的步骤基本与 Windows 上部署的类似,我们需要在每
一台机器上安装 JDK1.6,然后下载 Cassandra,并修改 log4j.properties 和
storage-conf.xml 的配置文件和设置环境变量。不同的是,我们需要在
storage-conf.xml 文件中配置集群的信息:


1 配置集群


1 配置集群节点信息


<Seeds>
      <Seed>hadoop2</Seed>
      <Seed>hadoop3</Seed>
      <Seed>hadoop4</Seed>
      <Seed>hadoop5</Seed>
      <Seed>hadoop6</Seed>
      <Seed>hadoop7</Seed>
      <Seed>hadoop8</Seed>
      <Seed>hadoop9</Seed>
      <Seed>hadoop10</Seed>
  </Seeds>


2 配置集群节点之间交互的监听地址


直接留空即可:

<ListenAddress></ListenAddress>
3 配置 Thrift Server 监听的地址


直接留空即可:

<ThriftAddress></ThriftAddress>


4 配置集群的名称


每一个集群的名称都应该是不用的

<ClusterName>gpcuster.cnblogs.com</ClusterName>


5 开启节点自动加入集群的功能


<AutoBootstrap>true</AutoBootstrap>


6 配置数据的备份数


<ReplicationFactor>3</ReplicationFactor>


7 调节 Memory 和 Disk 的性能


需要根据实际的情况来配置,可以参考 Wiki。


2 运行 Cassandra


在每一台节点上,运行 bin/cassandra。如果看到:INFO - Starting up
server gossip,说明启动成功。
3 查看集群运行情况


当所有的节点都运行起来以后,我们可以通过 JMX 查看运行状况:




总结


在 Windows 环境和 Linux 环境下部署 Cassandra 基本都是类似的。只不过在
Linux 环境下 bin 目录中的脚本都能在 Linux 环境下运行,而 Windows 环境下只
有 2 个脚本可以运行。

谈谈 Cassandra 的客户端

最近试用了一段时间 Cassandra,将 Oracle 中的数据导入进来,遇到了问题然后解决问题,收获挺大。
在这个过程中,除了设计一个合理的数据模型,再就是使用 Cassandra API 进行交互了。


Cassandra 在设计的时候,就是支持 Thrift 的,这意味着我们可以使用多种语言开发。


对于 Cassandra 的开发本身而言,这是使用 Thrift 的好处:支持多语言。坏处也是显而易见的:Thrift
API 功能过于简单,不具备在生产环境使用的条件。


在 Cassandra Wiki 页面上,也有基于 Thrift API 开发的更加高级的 API,各个语言都有,具体信息可
以参考:http://wiki.apache.org/cassandra/ClientExamples。


这次只谈谈下面两类 Java 的客户端:


1 Thrift Java API


2 hector
Thrift Java API

这个是 Cassandra 自带的最简单的一类 API,这个文件在 apache-cassandra-0.5.1.jar 中包含了。可
以直接使用。我们也可以自己安装一个 Thrift,然后通过 cassandra.thrift 文件自动生成。


如果你要使用 Cassandra,那么我们必须要了解 Thrift API,毕竟所有的其他更加高级的 API 都是基于
这个来包装的。


提供的功能

插入数据

插入数据需要指定 keyspace,ColumnFamily, Column,Key,Value,timestamp 和数据同步级
别。(如何需要了 Cassandra 的解数据模型,可以参考《大话 Cassandra 数据模型》)


/**
 * Insert a Column consisting of (column_path.column, value, timestamp) at the given
column_path.column_family and optional
 * column_path.super_column. Note that column_path.column is here required, since a
SuperColumn cannot directly contain binary
 * values -- it can only contain sub-Columns.
 *
 * @param keyspace
 * @param key
 * @param column_path
 * @param value
 * @param timestamp
 * @param consistency_level
 */
public void insert(String keyspace, String key, ColumnPath column_path, byte[] value,
long timestamp, int consistency_level) throws InvalidRequestException,
UnavailableException, TimedOutException, TException;


/**
 * Insert Columns or SuperColumns across different Column Families for the same row
key. batch_mutation is a
 * map<string, list<ColumnOrSuperColumn>> -- a map which pairs column family names
with the relevant ColumnOrSuperColumn
 * objects to insert.
 *
 * @param keyspace
 * @param key
 * @param cfmap
* @param consistency_level
 */
public void batch_insert(String keyspace, String key,
Map<String,List<ColumnOrSuperColumn>> cfmap, int consistency_level) throws
InvalidRequestException, UnavailableException, TimedOutException, TException;



读取数据

获取一个查询条件精确的值。


/**
 * Get the Column or SuperColumn at the given column_path. If no value is present,
NotFoundException is thrown. (This is
 * the only method that can throw an exception under non-failure conditions.)
 *
 * @param keyspace
 * @param key
 * @param column_path
 * @param consistency_level
 */
public ColumnOrSuperColumn get(String keyspace, String key, ColumnPath column_path,
int consistency_level) throws InvalidRequestException, NotFoundException,
UnavailableException, TimedOutException, TException;


/**
 * Perform a get for column_path in parallel on the given list<string> keys. The
return value maps keys to the
 * ColumnOrSuperColumn found. If no value corresponding to a key is present, the key
will still be in the map, but both
 * the column and super_column references of the ColumnOrSuperColumn object it maps to
will be null.
 *
 * @param keyspace
 * @param keys
 * @param column_path
 * @param consistency_level
 */
public Map<String,ColumnOrSuperColumn> multiget(String keyspace, List<String> keys,
ColumnPath column_path, int consistency_level) throws InvalidRequestException,
UnavailableException, TimedOutException, TException;



获取某一个 keyspace,Key,ColumnFamily,SuperColumn(如果有的话需要指定)下面的相关数
据:只查询 Column 的 name 符合条件的相关数据(SlicePredicate)。
/**
 * Get the group of columns contained by column_parent (either a ColumnFamily name or
a ColumnFamily/SuperColumn name
 * pair) specified by the given SlicePredicate. If no matching values are found, an
empty list is returned.
 *
 * @param keyspace
 * @param key
 * @param column_parent
 * @param predicate
 * @param consistency_level
 */
public List<ColumnOrSuperColumn> get_slice(String keyspace, String key, ColumnParent
column_parent, SlicePredicate predicate, int consistency_level) throws
InvalidRequestException, UnavailableException, TimedOutException, TException;


/**
 * Performs a get_slice for column_parent and predicate for the given keys in
parallel.
 *
 * @param keyspace
 * @param keys
 * @param column_parent
 * @param predicate
 * @param consistency_level
 */
public Map<String,List<ColumnOrSuperColumn>> multiget_slice(String keyspace,
List<String> keys, ColumnParent column_parent, SlicePredicate predicate, int
consistency_level) throws InvalidRequestException, UnavailableException,
TimedOutException, TException;



查询 Key 的取值范围(使用这个功能需要使用 order-preserving partitioner)。


/**
 * @deprecated; use get_range_slice instead
 *
 * @param keyspace
 * @param column_family
 * @param start
 * @param finish
 * @param count
 * @param consistency_level
 */
public List<String> get_key_range(String keyspace, String column_family, String start,
String finish, int count, int consistency_level) throws InvalidRequestException,
UnavailableException, TimedOutException, TException;


/**
 * returns a subset of columns for a range of keys.
 *
 * @param keyspace
 * @param column_parent
 * @param predicate
 * @param start_key
 * @param finish_key
 * @param row_count
 * @param consistency_level
 */
public List<KeySlice> get_range_slice(String keyspace, ColumnParent column_parent,
SlicePredicate predicate, String start_key, String finish_key, int row_count, int
consistency_level) throws InvalidRequestException, UnavailableException,
TimedOutException, TException;



查询系统的信息。


/**
 * get property whose value is of type string.
 *
 * @param property
 */
public String get_string_property(String property) throws TException;


/**
 * get property whose value is list of strings.
 *
 * @param property
 */
public List<String> get_string_list_property(String property) throws TException;


/**
 * describe specified keyspace
 *
 * @param keyspace
 */
public Map<String,Map<String,String>> describe_keyspace(String keyspace) throws
NotFoundException, TException;
通过这些操作,我们可以了解到系统的信息。


其中一个比较有意思的查询信息是:token map,通过这个我们可以知道哪些 Cassandra Service 是可
以提供服务的。


删除数据

/**
 * Remove data from the row specified by key at the granularity specified by
column_path, and the given timestamp. Note
 * that all the values in column_path besides column_path.column_family are truly
optional: you can remove the entire
 * row by just specifying the ColumnFamily, or you can remove a SuperColumn or a
single Column by specifying those levels too.
 *
 * @param keyspace
 * @param key
 * @param column_path
 * @param timestamp
 * @param consistency_level
 */
public void remove(String keyspace, String key, ColumnPath column_path, long
timestamp, int consistency_level) throws InvalidRequestException,
UnavailableException, TimedOutException, TException;



这里需要注意的是,由于一致性的问题。这里的删除操作不会立即删除所有机器上的该数据,但是最终会
一致。


程序范例

import java.util.List;
import java.io.UnsupportedEncodingException;


import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.TException;
import org.apache.cassandra.service.*;


public class CClient
{
      public static void main(String[] args)
throws TException, InvalidRequestException, UnavailableException,
UnsupportedEncodingException, NotFoundException
   {
       TTransport tr = new TSocket("localhost", 9160);
       TProtocol proto = new TBinaryProtocol(tr);
       Cassandra.Client client = new Cassandra.Client(proto);
       tr.open();


       String key_user_id = "逖靖寒的世界";


       // insert data
       long timestamp = System.currentTimeMillis();
       client.insert("Keyspace1",
                      key_user_id,
                     new ColumnPath("Standard1", null, "网址".getBytes("UTF-8")),
                     "http://gpcuster.cnblogs.com".getBytes("UTF-8"),
                      timestamp,
                      ConsistencyLevel.ONE);
       client.insert("Keyspace1",
                      key_user_id,
                     new ColumnPath("Standard1", null, "作者".getBytes("UTF-8")),
                     "逖靖寒".getBytes("UTF-8"),
                      timestamp,
                      ConsistencyLevel.ONE);


       // read single column
       ColumnPath path = new ColumnPath("Standard1", null, "name".getBytes("UTF-8"));
       System.out.println(client.get("Keyspace1", key_user_id, path,
ConsistencyLevel.ONE));


       // read entire row
       SlicePredicate predicate = new SlicePredicate(null, new SliceRange(new
byte[0], new byte[0], false, 10));
       ColumnParent parent = new ColumnParent("Standard1", null);
       List<ColumnOrSuperColumn> results = client.get_slice("Keyspace1", key_user_id,
parent, predicate, ConsistencyLevel.ONE);
       for (ColumnOrSuperColumn result : results)
       {
            Column column = result.column;
            System.out.println(new String(column.name, "UTF-8") + " -> " + new
String(column.value, "UTF-8"));
       }


       tr.close();
}
}



优点与缺点

优点:简单高效


缺点:功能简单,无法提供连接池,错误处理等功能,不适合直接在生产环境使用。



Hector

Hector 是基于 Thrift Java API 包装的一个 Java 客户端,提供一个更加高级的一个抽象。


程序范例

package me.prettyprint.cassandra.service;


import static me.prettyprint.cassandra.utils.StringUtils.bytes;
import static me.prettyprint.cassandra.utils.StringUtils.string;


import org.apache.cassandra.service.Column;
import org.apache.cassandra.service.ColumnPath;


public class ExampleClient {


    public static void main(String[] args) throws IllegalStateException,
PoolExhaustedException,
         Exception {
     CassandraClientPool pool = CassandraClientPoolFactory.INSTANCE.get();
     CassandraClient client = pool.borrowClient("localhost", 9160);
     // A load balanced version would look like this:
     // CassandraClient client = pool.borrowClient(new String[] {"cas1:9160",
"cas2:9160", "cas3:9160"});


     try {
         Keyspace keyspace = client.getKeyspace("Keyspace1");
         ColumnPath columnPath = new ColumnPath("Standard1", null, bytes("网址"));


         // insert
         keyspace.insert("逖靖寒的世界", columnPath, bytes("http://gpcuster.cnblogs.com"));


         // read
         Column col = keyspace.getColumn("逖靖寒的世界", columnPath);
System.out.println("Read from cassandra: " + string(col.getValue()));


        } finally {
            // return client to pool. do it in a finally block to make sure it's executed
            pool.releaseClient(client);
        }
    }
}



优点

1 提供连接池。


2 提 供 错 误 处 理 : 当 操 作 失 败 的 时 候 , Hector 会 根 据 系 统 信 息 ( token map ) 自 动 连 接 另 一 个
Cassandra Service。


3 编程接口容易使用。


4 支持 JMX。


缺点

1 不支持多线程的环境。


2 keyspace 封装过多(数据校验和数据重新封装),如果进行大量的数据操作,这里的消耗需要考虑。


3 错误处理不够人性化:如果所有的 Cassandra Service 都非常繁忙,那么经过多次操作失败后,最终
的结果失败。



总结

Hector 已经是一个基本足够使用的 Java 客户端了,但是还是缺乏一些相关的功能,比如:


1 线程安全。


2 支持自动的多线程查询和插入,提高操作效率。


3 人性化的错误处理机制。


4 避免过多的封装。
Linux 下如何设置环境变量,今天总结了一下,发出来和大家分享一下,希望对大家的学

习有所帮助,不多说了,看具体怎么操作了...



1、总结背景




在 linux 系统下,下载并安装了应用程序,很有可能在键入它的名称时出现“command not

found”的提示内容。每次都到安装目标文件夹内,找到可执行文件来进行操作就太繁琐了。

这涉及到环境变量 PATH 的设置问题,而 PATH 的设置也是在 linux 下定制环境变量的一个

组成部分。案例基于 RedHat AS4 讲解环境变量定制的问题。




2、变量简介




Linux 是一个多用户的操作系统。每个用户登录系统后,都会有一个专用的运行环境。通常

每个用户默认的环境都是相同的,这个默认环境实际上就是一组环境变量的定义。用户可以

对自己的运行环境进行定制,其方法就是修改相应的系统环境变量。




3、定制环境变量




环境变量是和 Shell 紧密相关的,用户登录系统后就启动了一个 Shell。对于 Linux 来说一般

是 bash,但也可以重新设定或切换到其它的 Shell(使用 chsh 命令)。




根据发行版本的情况,bash 有两个基本的系统级配置文件:/etc/bashrc 和/etc/profile。这
些配置文件包含两组不同的变量:shell 变量和环境变量。前者只是在特定的 shell 中固定

(如 bash),后者在不同 shell 中固定。很明显,shell 变量是局部的,而环境变量是全局

的。环境变量是通过 Shell 命令来设置的,设置好的环境变量又可以被所有当前用户所运行

的程序所使用。对于 bash 这个 Shell 程序来说,可以通过变量名来访问相应的环境变量,

通过 export 来设置环境变量。




注:Linux 的环境变量名称一般使用大写字母




4、环境变量设置实例




1.使用命令 echo 显示环境变量




本例使用 echo 显示常见的变量 HOME




$ echo $HOME




/home/kevin




2.设置一个新的环境变量




$ export MYNAME=”my name is kevin”




$ echo $ MYNAME
my name is Kevin




3.修改已存在的环境变量




接上个示例




$ MYNAME=”change name to jack”




$ echo $MYNAME




change name to jack




4.使用 env 命令显示所有的环境变量




$ env




HOSTNAME=localhost.localdomain




SHELL=/bin/bash




TERM=xterm




HISTSIZE=1000
SSH_CLIENT=192.168.136.151 1740 22




QTDIR=/usr/lib/qt-3.1




SSH_TTY=/dev/pts/0




……




5.使用 set 命令显示所有本地定义的 Shell 变量




$ set




BASH=/bin/bash




BASH_ENV=/root/.bashrc




……




6.使用 unset 命令来清除环境变量




$ export TEMP_KEVIN=”kevin”   #增加一个环境变量 TEMP_KEVIN




$ env | grep TEMP_KEVIN       #查看环境变量 TEMP_KEVIN 是否生效(存在即生效)
TEMP_KEVIN=kevin #证明环境变量 TEMP_KEVIN 已经存在




$ unset TEMP_KEVIN          #删除环境变量 TEMP_KEVIN




$ env | grep TEMP_KEVIN      #查看环境变量 TEMP_KEVIN 是否被删除,没有输出显示,

证明 TEMP_KEVIN 被清除了。




7.使用 readonly 命令设置只读变量




注:如果使用了 readonly 命令的话,变量就不可以被修改或清除了。




$ export TEMP_KEVIN ="kevin"     #增加一个环境变量 TEMP_KEVIN




$ readonly TEMP_KEVIN             #将环境变量 TEMP_KEVIN 设为只读




$ env | grep TEMP_KEVIN        #查看环境变量 TEMP_KEVIN 是否生效




TEMP_KEVIN=kevin        #证明环境变量 TEMP_KEVIN 已经存在




$ unset TEMP_KEVIN        #会提示此变量只读不能被删除




-bash: unset: TEMP_KEVIN: cannot unset: readonly variable
$ TEMP_KEVIN ="tom"      #修改变量值为 tom 会提示此变量只读不能被修改




-bash: TEMP_KEVIN: readonly variable




8.通过修改环境变量定义文件来修改环境变量。




需要注意的是,一般情况下,仅修改普通用户环境变量配置文件,避免修改根用户的环境

定义文件,因为那样可能会造成潜在的危险。




$ cd ~                  #到用户根目录下




$ ls -a                 #查看所有文件,包含隐藏的文件




$ vi .bash_profile      #修改用户环境变量文件




例如:




编辑你的 PATH 声明,其格式为:




PATH=$PATH:<PATH 1>:<PATH 2>:<PATH 3>:------:<PATH N>




你可以自己加上指定的路径,中间用冒号隔开。
环境变量更改后,在用户下次登陆时生效。




如果想立刻生效,则可执行下面的语句:$source .bash_profile




需要注意的是,最好不要把当前路径”./”放到 PATH 里,这样可能会受到意想不到的攻击。




完成后,可以通过$ echo $PATH 查看当前的搜索路径。这样定制后,就可以避免频繁的启

动位于 shell 搜索的路径之外的程序了。




5、学习总结




1.Linux 的变量种类




按变量的生存周期来划分,Linux 变量可分为两类:




1.   永久的:需要修改配置文件,变量永久生效。




2.   临时的:使用 export 命令行声明即可,变量在关闭 shell 时失效。




2.设置变量的三种方法




1.   在/etc/profile 文件中添加变量【对所有用户生效(永久的)】
用 VI 在文件/etc/profile 文件中增加变量,该变量将会对 Linux 下所有用户有效,并且是“

永久的”。




例如:编辑/etc/profile 文件,添加 CLASSPATH 变量




# vi /etc/profile




export CLASSPATH=./Java_HOME/lib;$JAVA_HOME/jre/lib




注:修改文件后要想马上生效还要运行# source /etc/profile 不然只能在下次重进此用户时

生效。




2.   在用户目录下的.bash_profile 文件中增加变量【对单一用户生效(永久的)】




用 VI 在用户目录下的.bash_profile 文件中增加变量,改变量仅会对当前用户有效,并且是

“永久的”。




例如:编辑 guok 用户目录(/home/guok)下的.bash_profile




$ vi /home/guok/.bash.profile




添加如下内容:
export CLASSPATH=./JAVA_HOME/lib;$JAVA_HOME/jre/lib




注:修改文件后要想马上生效还要运行$ source /home/guok/.bash_profile 不然只能在下

次重进此用户时生效。




3.   直接运行 export 命令定义变量【只对当前 shell(BASH)有效(临时的)】




在 shell 的命令行下直接使用[export 变量名=变量值]定义变量,该变量只在当前的

shell(BASH)或其子 shell(BASH)下是有效的,shell 关闭了,变量也就失效了,再打

开新 shell 时就没有这个变量,需要使用的话还需要重新定义。




Cassandra


文章分类 :数据库




Cassandra

下载


http://www.apache.org/dyn/closer.cgi?path=/cassandra/0.5.1/apache-cassandra-0.5.1-bin.tar.gz

apache-cassandra-0.5.1 自 带 的 hector-0.5.0-7.jar 有 严 重 的 性 能 问 题 , 需 要 修 改 成
hector-0.5.1-9.jar
资源


http://cassandra.apache.org/
http://wiki.apache.org/cassandra/FrontPage




部署


http://kauu.net/2010/02/27/cassandra%E5%88%9D%E4%BD%93%E9%AA%8C/

192.168.2.79
/home/bmb/apache-cassandra-0.5.1




DataModal 设计


对同一行的所有列,可以定义根据列名的排序规则(即保存规则)。当保存
某个用户相对应的朋友的时候,可以用朋友的加入时间作为一个一个的列名,
列按照时间倒序拍。这样很容易获得用户最新的朋友。


测试,Keyspace1 的 Standard1 的列按照 BytesType 进行排序,不管按照什么 set

顺序,get_slice 都会获得,a,b,c 的顺序
<ColumnFamily CompareWith="BytesType" Name="Standard1" />
set Keyspace1.Standard1['jsmith']['c'] = 'c'
set Keyspace1.Standard1['jsmith']['a'] = 'a'
set Keyspace1.Standard1['jsmith']['b'] = 'b'
Super columns

Super columns are a great way to store one-to-many indexes to other records: make
the sub column names TimeUUIDs (or whatever you'd like to use to sort the index),
and have the values be the foreign key.

不如某个用户的好友,Sub column name 是好友加入时间,Sub column value 是

好友的 ID,可以作为外键关联好友的信息表。


复合 Key 可以等效 Super Columns,列名为时间


Alternatively, we could preface the status keys with the user key, which has less temporal locality.
If we used user_id:status_id as the status key, we could do range queries on the user fragment
to get tweets-by-user, avoiding the need for a user_timeline super column.


In column-orientation, the column names are the data


列名 TimeUUID,列值 JSON 格式,可以解决一些问题





http://blog.evanweaver.com/articles/2009/07/06/up-and-running-with-cassandra/
Twitter 怎样使用 Cassandra,Twitter 的 Data Model,Blog 的 Data Model
http://arin.me/blog/wtf-is-a-supercolumn-cassandra-data-model
Digg 提供的一个完整例子
http://wiki.apache.org/cassandra/DataModel
http://wiki.apache.org/cassandra/CassandraLimitations
http://www.hellodba.net/2010/02/cassandra.html
(中文翻译,有出入)介绍 Twitter 的 Data Modal,有借鉴意义




修改 Schema 定义, 2 次重启


https://issues.apache.org/jira/browse/CASSANDRA-44
动态创建 Column Falimy,在不重启服务器下


http://github.com/NZKoz/cassandra_object




启动单个节点的 Cluster


安装 JDK 6
 tar -zxvf cassandra-$VERSION.tgz
 cd cassandra-$VERSION
 sudo mkdir -p /var/log/cassandra
 sudo chown -R `whoami` /var/log/cassandra
 sudo mkdir -p /var/lib/cassandra
 sudo chown -R `whoami` /var/lib/cassandra
修改/bin/cassandra.in.sh 里面的启动端口(-Dcom.sun.management.jmxremote.port=8080)
  bin/cassandra -f



查看日志

  tail -f /var/log/cassandra/system.log



客户端连接


cd /home/bmb/apache-cassandra-0.5.1
bin/cassandra-cli --host 192.168.2.79 --port 9160

 cassandra> set Keyspace1.Standard1['jsmith']['first'] = 'John'
 Value inserted.
 cassandra> set Keyspace1.Standard1['jsmith']['last'] = 'Smith'
 Value inserted.
 cassandra> set Keyspace1.Standard1['jsmith']['age'] = '42'
 Value inserted.
 cassandra> get Keyspace1.Standard1['jsmith']
  (column=age, value=42; timestamp=1249930062801)
  (column=first, value=John; timestamp=1249930053103)
  (column=last, value=Smith; timestamp=1249930058345)
Returned 3 rows.
 cassandra>


Java 客户端



原始 Thrift


http://apache.freelamp.com/incubator/thrift/0.2.0-incubating/thrift-0.2.0-incubating.tar.gz
封装
http://github.com/charliem/OCM


手动编译 Java Thrift
cd D:7gPersonalResourcesArchitectureCassandrathrift-0.2.0libjava
ant



hector

http://prettyprint.me/2010/02/23/hector-a-java-cassandra-client/
http://github.com/rantav/hector/downloads



OCM

http://github.com/charliem/OCM/downloads




Git

下载 Git
http://kernel.org/pub/software/scm/git/git-1.7.0.3.tar.gz
安装
cd /home/bmb/apache-cassandra-0.5.1/git-1.7.0.3
./configure
make
make install
Git 客户端
http://msysgit.googlecode.com/files/msysGit-fullinstall-1.7.0.2-preview20100309.exe
D:7gPersonalResourcesArchitectureCassandramsysgitmsysgit git-cmd.bat
Check out OCM
git clone http://github.com/charliem/OCM.git


http://tortoisegit.googlecode.com/files/TortoiseGit-1.3.6.0-32bit.msi




集群配置


http://pan-java.javaeye.com/blog/604672

192.168.5.11
/u/iic/bmb/apache-cassandra-0.5.1
修改 conf 下面的文件
/var/log/cassandra 成/u/iic/bmb/apache-cassandra-0.5.1/log
/var/lib/cassandra 成/u/iic/bmb/apache-cassandra-0.5.1/log
修改 bin/cassandra 的 Java_home
export JAVA_HOME=/u/iic/bmb/jdk6



192.168.5.12 (目录配置同 5.11,都以 2.79 为 Seed)
注意:部署集群的时候,不能把 5.11 整个目录搬到 5.12 上,不然他们 Token 一样,会导致
Ring 路 5.11 和 5.12 重复。解决方法:删除 data 和 commit 目录。
还有所有的 IP 必须配置成绝对 IP,如果配 Localhost,会使 Ring 不完整

192.168.2.79
/home/bmb/apache-cassandra-0.5.1

  bin/cassandra -f
OCM 的使用


定义数据结构:
D:7gPersonalResourcesArchitectureCassandraClientOCM
CompilerOCMSpecSample.txt


通过 com.kissintellignetsystems.ocm.compiler.Compiler 类,提供以下的命令

行参数,生成 Java 对象:"OCMSpecSample.txt", "keyspace1", "Java",


          "mynamespace", "output/"

测试例子:
D:7gPersonalResourcesArchitectureCassandraClientOutput
LanguagesJavaTestHarness

CreatTest.java



get keyspace1.Users['charlie']
bin/cassandra-cli --host 192.168.2.79 --port 9160
bin/cassandra-cli --host 192.168.5.11 --port 9160
bin/cassandra-cli --host 192.168.5.12 --port 9160




查看集群的节点信息


bin/nodeprobe -host localhost -port 8090 ring




Hadoop & Cassandra


using Hadoop to Cassandra through Binary Memtable
http://github.com/lenn0x/Cassandra-Hadoop-
BMT/blob/master/src/java/org/digg/CassandraBulkLoader.java

http://blog.csdn.net/wdwbw/archive/2010/03/10/5366739.aspx
http://www.roadtofailure.com/2009/10/29/hbase-vs-cassandra-nosql-battle/




Cassandra 是一个开源的分布式数据库,结合了 Dynamo 的 Key/Value 与 Bigtable 的面向列的特点。


Cassandra 的特点如下:


1.灵活的 schema:不需要象数据库一样预先设计 schema,增加或者删除字段非常方便(on the
fly)。


2.支持 range 查询:可以对 Key 进行范围查询。


3.高可用,可扩展:单点故障不影响集群服务,可线性扩展。


我们可以将 Cassandra 的数据模型想象成一个四维或者五维的 Hash。



Column

Column 是 Cassandra 中最小的数据单元。它是一个 3 元的数据类型,包含:name,value 和
timestamp。


将一个 Column 用 JSON 的形式表现出来如下:


{   // 这是一个 column
    2:     name: "逖靖寒的世界",
    3:     value: "gpcuster@gmali.com",
    4:     timestamp: 123456789
    5: }

为了简单起见,我们可以忽略 timestamp。就把 column 想象成一个 name/value 即可。


注意,这里提到的 name 和 value 都是 byte[]类型的,长度不限。



SuperColumn

我们可以将 SuperColumn 想象成 Column 的数组,它包含一个 name,以及一系列相应的 Column。


将一个 SuperColumn 用 JSON 的形式表现如下:
1: {     // 这是一个 SuperColumn
  2:       name: "逖靖寒的世界",
  3:       // 包含一系列的 Columns
  4:       value: {
  5:            street: {name: "street", value: "1234 x street", timestamp: 123456789},
  6:            city: {name: "city", value: "san francisco", timestamp: 123456789},
  7:            zip: {name: "zip", value: "94107", timestamp: 123456789},
  8:       }
  9: }

Columns 和 SuperColumns 都是 name 与 value 的组合。最大的不同在于 Column 的 value 是一个
“string”,而 SuperColumn 的 value 是 Columns 的 Map。


还有一点需要注意的是:SuperColumn’本身是不包含 timestamp 的。



ColumnFamily

ColumnFamily 是一个包含了许多 Row 的结构,你可以将它想象成 RDBMS 中的 Table。


每一个 Row 都包含有 client 提供的 Key 以及和该 Key 关联的一系列 Column。


我们可以看看结构:


1: UserProfile = { // 这是一个 ColumnFamily
  2:       phatduckk: {     // 这是对应 ColumnFamily 的 key
  3:            // 这是 Key 下对应的 Column
  4:            username: "gpcuster",
  5:            email: "gpcuster@gmail.com",
  6:            phone: "6666"
  7:       }, // 第一个 row 结束
  8:       ieure: {   // 这是 ColumnFamily 的另一个 key
  9:            //这是另一个 Key 对应的 column
 10:            username: "pengguo",
 11:            email: "pengguo@live.com",
 12:            phone: "888"
 13:            age: "66"
 14:       },
 15: }

ColumnFamily 的类型可以为 Standard,也可以是 Super 类型。


我们刚刚看到的那个例子是一个 Standard 类型的 ColumnFamily。Standard 类型的 ColumnFamily 包
含了一系列的 Columns(不是 SuperColumn)。
Super 类型的 ColumnFamily 包含了一系列的 SuperColumn,但是并不能像 SuperColumn 那样包含
一系列 Standard ColumnFamily。


这是一个简单的例子:


1: AddressBook = { // 这是一个 Super 类型的 ColumnFamily
   2:     phatduckk: {     // key
   3:           friend1: {street: "8th street", zip: "90210", city: "Beverley Hills",
state: "CA"},
   4:           John: {street: "Howard street", zip: "94404", city: "FC", state: "CA"},
   5:           Kim: {street: "X street", zip: "87876", city: "Balls", state: "VA"},
   6:           Tod: {street: "Jerry street", zip: "54556", city: "Cartoon", state:
"CO"},
   7:           Bob: {street: "Q Blvd", zip: "24252", city: "Nowhere", state: "MN"},
   8:           ...
   9:     }, // row 结束
  10:     ieure: {       // key
  11:           joey: {street: "A ave", zip: "55485", city: "Hell", state: "NV"},
  12:           William: {street: "Armpit Dr", zip: "93301", city: "Bakersfield", state:
"CA"},
  13:     },
  14: }




Keyspace

Keyspace 是我们的数据最外层,你所有的 ColumnFamily 都属于某一个 Keyspace。一般来说,我们的
一个程序应用只会有一个 Keyspace。



简单测试

我们将 Cassandra 运行起来以后,启动命令行,执行如下操作:


cassandra> set Keyspace1.Standard1['jsmith']['first'] = 'John'
Value inserted.
cassandra> set Keyspace1.Standard1['jsmith']['last'] = 'Smith'
Value inserted.
cassandra> set Keyspace1.Standard1['jsmith']['age'] = '42'
Value inserted.


这个时候,Cassandra 中就已经有 3 条数据了。


其中插入数据的各个字段含义如下:
接下来,我们执行查询操作:


cassandra> get Keyspace1.Standard1['jsmith']
 (column=age, value=42; timestamp=1249930062801)
 (column=first, value=John; timestamp=1249930053103)
 (column=last, value=Smith; timestamp=1249930058345)
Returned 3 rows.


这样,我们就可以将之前插入的数据查询出来了。



排序

有一点需要明确,我们使用 Cassandra 的时候,数据在写入的时候就已经排好顺序了。


在某一个 Key 内的所有 Column 都是按照它的 Name 来排序的。我们可以在 storage-conf.xml 文件中
指定排序的类型。


目前 Cassandra 提供的排序类型有:BytesType, UTF8Type,LexicalUUIDType, TimeUUIDType,
AsciiType,和 LongType。


现在假设你的原始数据如下:


{name: 123, value: "hello there"},
{name: 832416, value: "kjjkbcjkcbbd"},
{name: 3, value: "101010101010"},
{name: 976, value: "kjjkbcjkcbbd"}


当我们 storage-conf.xml 文件中指定排序的类型为 LongType 时:


<!--
      ColumnFamily 在 storage-conf.xml 中定义
-->
<ColumnFamily CompareWith="LongType" Name="CF_NAME_HERE"/>


排序后的数据就是这样的:
{name: 3, value: "101010101010"},
{name: 123, value: "hello there"},
{name: 976, value: "kjjkbcjkcbbd"},
{name: 832416, value: "kjjkbcjkcbbd"}


如果我们指定排序的类型为 UTF8Type


<!--
         ColumnFamily 在 storage-conf.xml 中定义


-->
<ColumnFamily CompareWith="UTF8Type" Name="CF_NAME_HERE"/>


排序后的数据就是这样的:


{name: 123, value: "hello there"},
{name: 3, value: "101010101010"},
{name: 832416, value: "kjjkbcjkcbbd"},
{name: 976, value: "kjjkbcjkcbbd"}


大家可以看到,指定的排序类型不一样,排序的结果也是完全不同的。


对于 SuperColumn,我们有一个额外的排序维度,所以我们可以指定 CompareSubcolumnsWith 来
进行另一个维度的排序类型。


假设我们的原始数据如下:


{ // first SuperColumn from a Row
     name: "workAddress",
     // and the columns within it
     value: {
          street: {name: "street", value: "1234 x street"},
          city: {name: "city", value: "san francisco"},
          zip: {name: "zip", value: "94107"}
     }
},
{ // another SuperColumn from same Row
     name: "homeAddress",
     // and the columns within it
     value: {
          street: {name: "street", value: "1234 x street"},
          city: {name: "city", value: "san francisco"},
          zip: {name: "zip", value: "94107"}
}
}


然后我们定义 CompareSubcolumnsWith 和 CompareWith 的排序类型都是 UTF8Type,那么排序后
的结果为:


{
    // this one's first b/c when treated as UTF8 strings
    { // another SuperColumn from same Row
         // This Row comes first b/c "homeAddress" is before "workAddress"
         name: "homeAddress",
         // the columns within this SC are also sorted by their names too
         value: {
             // see, these are sorted by Column name too
             city: {name: "city", value: "san francisco"},
             street: {name: "street", value: "1234 x street"},
             zip: {name: "zip", value: "94107"}
         }
    },
    name: "workAddress",
    value: {
         // the columns within this SC are also sorted by their names too
         city: {name: "city", value: "san francisco"},
         street: {name: "street", value: "1234 x street"},
         zip: {name: "zip", value: "94107"}
    }
}


再额外提一句,Cassandra 的排序功能是允许我们自己实现的,只要你继承
org.apache.cassandra.db.marshal.IType 就可以了。



参考文档



WTF is a SuperColumn? An Intro to the Cassandra Data Model



DataModel

Contenu connexe

Tendances

【诗檀软件 郭兆伟-技术报告】跨国企业级Oracle数据库备份策略
【诗檀软件 郭兆伟-技术报告】跨国企业级Oracle数据库备份策略【诗檀软件 郭兆伟-技术报告】跨国企业级Oracle数据库备份策略
【诗檀软件 郭兆伟-技术报告】跨国企业级Oracle数据库备份策略maclean liu
 
dbdao.com 汪伟华 my-sql-replication复制高可用配置方案
dbdao.com 汪伟华 my-sql-replication复制高可用配置方案dbdao.com 汪伟华 my-sql-replication复制高可用配置方案
dbdao.com 汪伟华 my-sql-replication复制高可用配置方案maclean liu
 
PostgreSQL 9 Standby
PostgreSQL 9 StandbyPostgreSQL 9 Standby
PostgreSQL 9 StandbyMarch Liu
 
Oracle 資料庫檔案介紹
Oracle 資料庫檔案介紹Oracle 資料庫檔案介紹
Oracle 資料庫檔案介紹Chien Chung Shen
 
Jdbc4 0 规范技术预研
Jdbc4 0 规范技术预研Jdbc4 0 规范技术预研
Jdbc4 0 规范技术预研lorisjand
 
TomCat迁移步骤简述以及案例
TomCat迁移步骤简述以及案例TomCat迁移步骤简述以及案例
TomCat迁移步骤简述以及案例maclean liu
 
My sql 同步
My sql 同步My sql 同步
My sql 同步Yiwei Ma
 
MySQL源码分析.01.代码结构与基本流程
MySQL源码分析.01.代码结构与基本流程MySQL源码分析.01.代码结构与基本流程
MySQL源码分析.01.代码结构与基本流程Lixun Peng
 
无数据库日志文件恢复数据库方法两则
无数据库日志文件恢复数据库方法两则无数据库日志文件恢复数据库方法两则
无数据库日志文件恢复数据库方法两则wensheng wei
 
Mysql proxy cluster
Mysql proxy clusterMysql proxy cluster
Mysql proxy clusterYiwei Ma
 
7, OCP - configure database for backup and recovery
7, OCP - configure database for backup and recovery7, OCP - configure database for backup and recovery
7, OCP - configure database for backup and recoveryted-xu
 
内部MySQL培训.3.基本原理
内部MySQL培训.3.基本原理内部MySQL培训.3.基本原理
内部MySQL培训.3.基本原理Lixun Peng
 
MySQL 6.0 下的cluster + replicate - 20080220
MySQL 6.0 下的cluster + replicate - 20080220MySQL 6.0 下的cluster + replicate - 20080220
MySQL 6.0 下的cluster + replicate - 20080220Jinrong Ye
 
Oracle数据库升级前必要的准备工作
Oracle数据库升级前必要的准备工作Oracle数据库升级前必要的准备工作
Oracle数据库升级前必要的准备工作maclean liu
 
Mysql handlersocket
Mysql handlersocketMysql handlersocket
Mysql handlersocketpwesh
 
Oracle使用者安全設定
Oracle使用者安全設定Oracle使用者安全設定
Oracle使用者安全設定Chien Chung Shen
 
SQL Server 2000 高可用性群集构建
SQL Server 2000 高可用性群集构建SQL Server 2000 高可用性群集构建
SQL Server 2000 高可用性群集构建bigqiang zou
 
Maclean介绍oracle asm基础概念和原理
Maclean介绍oracle asm基础概念和原理Maclean介绍oracle asm基础概念和原理
Maclean介绍oracle asm基础概念和原理maclean liu
 

Tendances (20)

【诗檀软件 郭兆伟-技术报告】跨国企业级Oracle数据库备份策略
【诗檀软件 郭兆伟-技术报告】跨国企业级Oracle数据库备份策略【诗檀软件 郭兆伟-技术报告】跨国企业级Oracle数据库备份策略
【诗檀软件 郭兆伟-技术报告】跨国企业级Oracle数据库备份策略
 
dbdao.com 汪伟华 my-sql-replication复制高可用配置方案
dbdao.com 汪伟华 my-sql-replication复制高可用配置方案dbdao.com 汪伟华 my-sql-replication复制高可用配置方案
dbdao.com 汪伟华 my-sql-replication复制高可用配置方案
 
PostgreSQL 9 Standby
PostgreSQL 9 StandbyPostgreSQL 9 Standby
PostgreSQL 9 Standby
 
Oracle 資料庫檔案介紹
Oracle 資料庫檔案介紹Oracle 資料庫檔案介紹
Oracle 資料庫檔案介紹
 
Jdbc4 0 规范技术预研
Jdbc4 0 规范技术预研Jdbc4 0 规范技术预研
Jdbc4 0 规范技术预研
 
Mysql集群
Mysql集群Mysql集群
Mysql集群
 
TomCat迁移步骤简述以及案例
TomCat迁移步骤简述以及案例TomCat迁移步骤简述以及案例
TomCat迁移步骤简述以及案例
 
My sql 同步
My sql 同步My sql 同步
My sql 同步
 
MySQL源码分析.01.代码结构与基本流程
MySQL源码分析.01.代码结构与基本流程MySQL源码分析.01.代码结构与基本流程
MySQL源码分析.01.代码结构与基本流程
 
无数据库日志文件恢复数据库方法两则
无数据库日志文件恢复数据库方法两则无数据库日志文件恢复数据库方法两则
无数据库日志文件恢复数据库方法两则
 
Mysql proxy cluster
Mysql proxy clusterMysql proxy cluster
Mysql proxy cluster
 
7, OCP - configure database for backup and recovery
7, OCP - configure database for backup and recovery7, OCP - configure database for backup and recovery
7, OCP - configure database for backup and recovery
 
内部MySQL培训.3.基本原理
内部MySQL培训.3.基本原理内部MySQL培训.3.基本原理
内部MySQL培训.3.基本原理
 
MySQL 6.0 下的cluster + replicate - 20080220
MySQL 6.0 下的cluster + replicate - 20080220MySQL 6.0 下的cluster + replicate - 20080220
MySQL 6.0 下的cluster + replicate - 20080220
 
Oracle数据库升级前必要的准备工作
Oracle数据库升级前必要的准备工作Oracle数据库升级前必要的准备工作
Oracle数据库升级前必要的准备工作
 
Oracle SGA 介紹
Oracle SGA 介紹Oracle SGA 介紹
Oracle SGA 介紹
 
Mysql handlersocket
Mysql handlersocketMysql handlersocket
Mysql handlersocket
 
Oracle使用者安全設定
Oracle使用者安全設定Oracle使用者安全設定
Oracle使用者安全設定
 
SQL Server 2000 高可用性群集构建
SQL Server 2000 高可用性群集构建SQL Server 2000 高可用性群集构建
SQL Server 2000 高可用性群集构建
 
Maclean介绍oracle asm基础概念和原理
Maclean介绍oracle asm基础概念和原理Maclean介绍oracle asm基础概念和原理
Maclean介绍oracle asm基础概念和原理
 

Similaire à Cassandra的初步使用及一些简单的操作

Cassandra简介.ppt
Cassandra简介.pptCassandra简介.ppt
Cassandra简介.pptjames tong
 
深入学习Mongo db
深入学习Mongo db深入学习Mongo db
深入学习Mongo dbLucien Li
 
为10g rac cluster添加节点
为10g rac cluster添加节点为10g rac cluster添加节点
为10g rac cluster添加节点maclean liu
 
lwdba – 開放原始碼的輕量級資料庫存取程式庫
lwdba – 開放原始碼的輕量級資料庫存取程式庫lwdba – 開放原始碼的輕量級資料庫存取程式庫
lwdba – 開放原始碼的輕量級資料庫存取程式庫建興 王
 
Azure Data Lake 簡介
Azure Data Lake 簡介Azure Data Lake 簡介
Azure Data Lake 簡介Herman Wu
 
J2ee经典学习笔记
J2ee经典学习笔记J2ee经典学习笔记
J2ee经典学习笔记yiditushe
 
第一讲 My sql初步
第一讲 My sql初步第一讲 My sql初步
第一讲 My sql初步hjl888666
 
用JAX-RS和Jersey完成RESTful Web Services
用JAX-RS和Jersey完成RESTful Web Services用JAX-RS和Jersey完成RESTful Web Services
用JAX-RS和Jersey完成RESTful Web Servicesjavatwo2011
 
Cassandra
CassandraCassandra
CassandraFEG
 
Row Set初步学习V1.1
Row Set初步学习V1.1Row Set初步学习V1.1
Row Set初步学习V1.1Zianed Hou
 
Jkcn MySQLDB 架构
Jkcn MySQLDB 架构Jkcn MySQLDB 架构
Jkcn MySQLDB 架构Louis liu
 
Ria的强力后盾:rest+海量存储
Ria的强力后盾:rest+海量存储 Ria的强力后盾:rest+海量存储
Ria的强力后盾:rest+海量存储 zhen chen
 
山頂洞人日記 - 回歸到最純樸的開發
山頂洞人日記 -  回歸到最純樸的開發山頂洞人日記 -  回歸到最純樸的開發
山頂洞人日記 - 回歸到最純樸的開發koji lin
 
AWS Lambda Multi-Cloud Practices
AWS Lambda Multi-Cloud PracticesAWS Lambda Multi-Cloud Practices
AWS Lambda Multi-Cloud Practices康志強 大人
 
Docker+mesos安装最佳实践
Docker+mesos安装最佳实践Docker+mesos安装最佳实践
Docker+mesos安装最佳实践3908282
 
Kid171 chap03 traditional Chinese Version
Kid171 chap03 traditional Chinese VersionKid171 chap03 traditional Chinese Version
Kid171 chap03 traditional Chinese VersionFrank S.C. Tseng
 
Hadoop学习总结
Hadoop学习总结Hadoop学习总结
Hadoop学习总结ordinary2012
 
Jdbc中驱动加载的过程分析(下)
Jdbc中驱动加载的过程分析(下)Jdbc中驱动加载的过程分析(下)
Jdbc中驱动加载的过程分析(下)yiditushe
 

Similaire à Cassandra的初步使用及一些简单的操作 (20)

Cassandra简介.ppt
Cassandra简介.pptCassandra简介.ppt
Cassandra简介.ppt
 
Why use MySQL
Why use MySQLWhy use MySQL
Why use MySQL
 
深入学习Mongo db
深入学习Mongo db深入学习Mongo db
深入学习Mongo db
 
为10g rac cluster添加节点
为10g rac cluster添加节点为10g rac cluster添加节点
为10g rac cluster添加节点
 
lwdba – 開放原始碼的輕量級資料庫存取程式庫
lwdba – 開放原始碼的輕量級資料庫存取程式庫lwdba – 開放原始碼的輕量級資料庫存取程式庫
lwdba – 開放原始碼的輕量級資料庫存取程式庫
 
Azure Data Lake 簡介
Azure Data Lake 簡介Azure Data Lake 簡介
Azure Data Lake 簡介
 
J2ee经典学习笔记
J2ee经典学习笔记J2ee经典学习笔记
J2ee经典学习笔记
 
第一讲 My sql初步
第一讲 My sql初步第一讲 My sql初步
第一讲 My sql初步
 
Exodus2 大局观
Exodus2 大局观Exodus2 大局观
Exodus2 大局观
 
用JAX-RS和Jersey完成RESTful Web Services
用JAX-RS和Jersey完成RESTful Web Services用JAX-RS和Jersey完成RESTful Web Services
用JAX-RS和Jersey完成RESTful Web Services
 
Cassandra
CassandraCassandra
Cassandra
 
Row Set初步学习V1.1
Row Set初步学习V1.1Row Set初步学习V1.1
Row Set初步学习V1.1
 
Jkcn MySQLDB 架构
Jkcn MySQLDB 架构Jkcn MySQLDB 架构
Jkcn MySQLDB 架构
 
Ria的强力后盾:rest+海量存储
Ria的强力后盾:rest+海量存储 Ria的强力后盾:rest+海量存储
Ria的强力后盾:rest+海量存储
 
山頂洞人日記 - 回歸到最純樸的開發
山頂洞人日記 -  回歸到最純樸的開發山頂洞人日記 -  回歸到最純樸的開發
山頂洞人日記 - 回歸到最純樸的開發
 
AWS Lambda Multi-Cloud Practices
AWS Lambda Multi-Cloud PracticesAWS Lambda Multi-Cloud Practices
AWS Lambda Multi-Cloud Practices
 
Docker+mesos安装最佳实践
Docker+mesos安装最佳实践Docker+mesos安装最佳实践
Docker+mesos安装最佳实践
 
Kid171 chap03 traditional Chinese Version
Kid171 chap03 traditional Chinese VersionKid171 chap03 traditional Chinese Version
Kid171 chap03 traditional Chinese Version
 
Hadoop学习总结
Hadoop学习总结Hadoop学习总结
Hadoop学习总结
 
Jdbc中驱动加载的过程分析(下)
Jdbc中驱动加载的过程分析(下)Jdbc中驱动加载的过程分析(下)
Jdbc中驱动加载的过程分析(下)
 

Cassandra的初步使用及一些简单的操作

  • 1. Apache Cassandra    Apache Cassandra 是一套开源分布式数据库管理系统。它最初由 Facebook 开发, 用于储存特别大的数据。 主要特性:   ● 分布式   ● 于 column 的结构化 ● 高伸展性    Cassandra 是一个混合型的非关系的数据库,类似于 Google 的 BigTable 。Cassandra 的主要特点就是它不是一个数据库,而是由一堆数据库节点共同 构成的一个分布式网络服务,对 Cassandra 的一个写操作,会被复制到其它节点上去, 对 Cassandra 的读操作,也会被路由到某个节点上面去读取。对于一个 Cassandra 群 集来说,扩展性能是比较简单的事情,只管在群集里面添加节点就可以了。    Cassandra 的主要功能比 Dynamo (分布式的 Key-Value 存 储系统)更丰富,但 支持度却不如文档存储 MongoDB (介于关系数据库和非关系数据库之间的开源产品, 是非关系数据库当中功能最丰富,最像关系数据库的。支持的数据结构非常松散,是类 似 json 的 bjson 格式,因此可以存储比较复杂的数据类型。) Cassandra 最初由 Facebook 开发,后转变成了开源项目。它是一个网络社交云计 算方面理想的数据库。以 Amazon 专有的完全分布式的 Dynamo 为基础,结合了 Google BigTable 基于列族( Column Family )的数据模型。P2P 去中心化的存储。很多 方面都可以称之为 Dynamo 2.0 。   和其它数据库比较, Cassandra 有三个突出特点:   ■ 模式灵活 :使用 Cassandra ,像文档存储,你不必提前解决记录中的字段。 你可以在系统运行时随意的添加或移除字段。这是一个惊人的效率提升,特别是在大型 部署上。   ■ 真正的可扩展性 : Cassandra 是纯粹意义上的水平扩展。为给集群添加更多 容量,可以指向另一台计算机。你不必重启任何进程,改变应用查询,或手动迁移任何 数据。   ■ 多数据中心识别 :你可以调整你的节点布局来避免某一个数据中心起火,一 个备用的数据中心将至少有每条记录的完全复制。   一些使 Cassandra 提高竞争力的其它功能:   ■ 范围查询 :如果你不喜欢全部的键值查询,则可以设置键的范围来查询。   ■ 列表数据结构 :在混合模式可以将超级列添加到 5 维。 对于每个用户的索引, 这是非常方便的。   ■ 分布式写操作 :有可以在任何地方任何时间集中读或写任何数据。 并且不会有 任何单点失败。
  • 2. Cassandra 分布式节点服务器的简单部署 文章分类 :数据库 Cassandra 作为目前很热门的一个 NOSQL 型数据库,引起了很多的关注。 NOSQL 感兴趣 对 的 我 , 也 来 作 了 一 次 简 单 的 测 试 。 废 话 不 多 说 , 下 面 就 来 介 绍 下 Cassandra 多 节 点 的 部 署 。 部 署 要 求 : 1. JDK1.6 2. OS : linux ,我在 windows 上实验过,不知道为啥一直没通( 7000 端口上只有 windows 的 发 包 , 双 方 不 互 相 通 信 ) 3. cassandra 0.6 OK,基本的东西都有了,进入到 cassandra 的目录,首先需要修改一些相关的文件路径: 1. log4j.properties 文 件 输 出 路 径 修 改 2. storage-conf.xml CommitLogDirectory 和 DataFileDirectory 路 径 修 改 接 着 进 行 分 布 式 节 点 的 配 置 , 还 是 修 改 torage-conf.xml : 1. <ClusterName>Test Cluster</ClusterName> 这个要求所有节点的名字都相同,如果不相同,则报类似 AName != BName 的错误 2. <ColumnFamily Name="Standard1" CompareWith="BytesType"/> 配置 ColumnFamily 的一些属性,其中 name 是所要使用的 ColumnFamily 名称,可以多 个,客户端做 CRUD 操作时需要指定。注意所有的节点配置都需要一样(我就曾因配置不 一 致 出 过 ClassCastException 的 异 常 ) 3. <ReplicationFactor>2</ReplicationFactor> 配置数据需要复制的数量,复制的策略分 RackUnawareStrategy 和 RackAwareStrategy 两 种 方 式 ( 策 略 没 细 看 不 再 描 述 ) 4. <Seeds> <Seed>10.10.13.220</Seed> <Seed>10.10.13.181</Seed> <Seed>10.10.13.232</Seed> </Seeds> 这个是所有分布式服务器节点的 IP 地址,如上面配置了 3 个 IP 即 3 个 Cassandra 节点 5. <ListenAddress>10.10.13.220</ListenAddress> <ThriftAddress>10.10.13.220</ThriftAddress> 本节点监听客户端数据和与其他服务器节点通信的 IP 地址,只能为本机 IP,且不能为 127.0.0.1 或 localhost , 否 则 与 其 他 服 务 器 不 能 建 立 正 确 交 互 此处的 IP 地址也可以不填,即值为空,则所有的节点配置都一样,更方便部署。
  • 3. 搞定 storage-conf.xml !下面的工作就是将所有的 Cassandra 服务器节点依次启动,通过日 志就可以看到相关的节点连接上了,日志为: Log4j 代码 1. INFO 13:04:52,098 Node /10.10.13.232 is now part of the cluster 到这里,Cassandra 分布式节点服务器的搭建就完成了。使用官网提供的客户端代码进行测 试 ,发 现数据已经提交到服务 器并且在多个节点间进行复制了 在这里抱怨一下:之前由于没有足够的服务器,使用 windowsXP+solaris 双节点进行测试, 。 后来加 入 linux 后,solaris+linux 的方式却能正常走通,配置也都 发现怎么也建立不起来 。 是 一 样 的 。 有 空 研 究 下 为 何 在 我 的 windows 上 不 支 持 。 。 。 。 参 考 地 址 : http://cassandra.apache.org/ 如何安装和配置 Cassandra 文章分类 :数据库 Cassandra 属于最近比较流行的一款 NoSQL 数据库,http://nosql- database.org/中给 NoSQL 的定义如下: 下一代的数据库产品应该具备这几点:非关系型的,分布式的,开源的,可 以线性扩展的。这类数据库最初的目的在于提供现代网站可扩展的数据库解 决方案。 这个运动开始于 2009 年初,目前正在迅速的发展。这种类型的数据库具 有:自由的 schema,数据多处备份,简单的编程 API,数据的最终一致 性保证等等。所以我们将这种类型的数据库称为 NoSQL(不仅仅是 SQL,全称为 “not only sql”)。 下面我们一起来看看如果分别在 Windows 和 Linux 环境下安装和部署 Cassandra。
  • 4. 在 Windows 上单机运行 Cassandra 大多数人使用的 OS 都是 Windows,所以如果只是想简单地测试一下 Cassandra,我们可以直接在安装好 JDK1.6 的 Windows 系统上安装 Cassandra, 并进行简单的测试。 1 下载 Cassandra 去 http://cassandra.apache.org/下载即可。目前最新的 beta 版本是 0.6.0 b3,但是我们安装使用的最新的 Release 版本 0.5.1。 2 安装 Cassandra 将下载的压缩包解压,假设解压的位置是 D:apache-cassandra-0.5.1。 1 修改 conf 目录下的 log4j.properties 文件: log4j.appender.R.File=D:apache-cassandra-0.5.1logs 2 修改 conf 目录下的 storage-conf.xml 文件: <CommitLogDirectory>D:apache- cassandra-0.5.1commitlog</CommitLogDirectory> <DataFileDirectories> <DataFileDirectory>D:apache- cassandra-0.5.1data</DataFileDirectory> </DataFileDirectories> <CalloutLocation>D:apache-cassandra-0.5.1callouts</CalloutLocation> <StagingFileDirectory>D:apache- cassandra-0.5.1staging</StagingFileDirectory>
  • 5. 3 设置系统的环境变量: CASSANDRA_HOME=D:apache-cassandra-0.5.1 3 启动 Cassandra 运行 bin 目录下的 cassandra.bat。如果看到:INFO - Starting up server gossip,那么恭喜你,Cassandra 已经在你的本机启动起来了。 4 使用命令行进行简单的测试 运行 bin 目录下的 cassandra-cli.bat。输入:connect localhost 9160,连接 成功后可以看到下面的提示。 cassandra> connect localhost 9160 line 1:18 missing SLASH at '9160' Connected to localhost/9160 然后,我们可以参考 README.txt 文件中提供的范例进行测试: cassandra> set Keyspace1.Standard1['jsmith']['first'] = 'John' Value inserted. cassandra> set Keyspace1.Standard1['jsmith']['last'] = 'Smith' Value inserted. cassandra> set Keyspace1.Standard1['jsmith']['age'] = '42' Value inserted. cassandra> get Keyspace1.Standard1['jsmith'] (column=age, value=42; timestamp=1249930062801) (column=first, value=John; timestamp=1249930053103) (column=last, value=Smith; timestamp=1249930058345) Returned 3 rows. cassandra> 你也可以根据这篇文章《谈谈 Cassandra 的客户端》中的内容测试一下如何使用 Java 编写简单的程序和 Cassandra 交互。
  • 6. 在 Linux 上运行 Cassandra 集群 如果需要真正在生产环境中使用 Cassandra,我们需要搭建一个 Cassandra 集群, 这样才能真正发挥出它作为 NoSQL 数据所应该具备的特性。 在 Linux 部署 Cassandra 的步骤基本与 Windows 上部署的类似,我们需要在每 一台机器上安装 JDK1.6,然后下载 Cassandra,并修改 log4j.properties 和 storage-conf.xml 的配置文件和设置环境变量。不同的是,我们需要在 storage-conf.xml 文件中配置集群的信息: 1 配置集群 1 配置集群节点信息 <Seeds> <Seed>hadoop2</Seed> <Seed>hadoop3</Seed> <Seed>hadoop4</Seed> <Seed>hadoop5</Seed> <Seed>hadoop6</Seed> <Seed>hadoop7</Seed> <Seed>hadoop8</Seed> <Seed>hadoop9</Seed> <Seed>hadoop10</Seed> </Seeds> 2 配置集群节点之间交互的监听地址 直接留空即可: <ListenAddress></ListenAddress>
  • 7. 3 配置 Thrift Server 监听的地址 直接留空即可: <ThriftAddress></ThriftAddress> 4 配置集群的名称 每一个集群的名称都应该是不用的 <ClusterName>gpcuster.cnblogs.com</ClusterName> 5 开启节点自动加入集群的功能 <AutoBootstrap>true</AutoBootstrap> 6 配置数据的备份数 <ReplicationFactor>3</ReplicationFactor> 7 调节 Memory 和 Disk 的性能 需要根据实际的情况来配置,可以参考 Wiki。 2 运行 Cassandra 在每一台节点上,运行 bin/cassandra。如果看到:INFO - Starting up server gossip,说明启动成功。
  • 8. 3 查看集群运行情况 当所有的节点都运行起来以后,我们可以通过 JMX 查看运行状况: 总结 在 Windows 环境和 Linux 环境下部署 Cassandra 基本都是类似的。只不过在 Linux 环境下 bin 目录中的脚本都能在 Linux 环境下运行,而 Windows 环境下只 有 2 个脚本可以运行。 谈谈 Cassandra 的客户端 最近试用了一段时间 Cassandra,将 Oracle 中的数据导入进来,遇到了问题然后解决问题,收获挺大。 在这个过程中,除了设计一个合理的数据模型,再就是使用 Cassandra API 进行交互了。 Cassandra 在设计的时候,就是支持 Thrift 的,这意味着我们可以使用多种语言开发。 对于 Cassandra 的开发本身而言,这是使用 Thrift 的好处:支持多语言。坏处也是显而易见的:Thrift API 功能过于简单,不具备在生产环境使用的条件。 在 Cassandra Wiki 页面上,也有基于 Thrift API 开发的更加高级的 API,各个语言都有,具体信息可 以参考:http://wiki.apache.org/cassandra/ClientExamples。 这次只谈谈下面两类 Java 的客户端: 1 Thrift Java API 2 hector
  • 9. Thrift Java API 这个是 Cassandra 自带的最简单的一类 API,这个文件在 apache-cassandra-0.5.1.jar 中包含了。可 以直接使用。我们也可以自己安装一个 Thrift,然后通过 cassandra.thrift 文件自动生成。 如果你要使用 Cassandra,那么我们必须要了解 Thrift API,毕竟所有的其他更加高级的 API 都是基于 这个来包装的。 提供的功能 插入数据 插入数据需要指定 keyspace,ColumnFamily, Column,Key,Value,timestamp 和数据同步级 别。(如何需要了 Cassandra 的解数据模型,可以参考《大话 Cassandra 数据模型》) /** * Insert a Column consisting of (column_path.column, value, timestamp) at the given column_path.column_family and optional * column_path.super_column. Note that column_path.column is here required, since a SuperColumn cannot directly contain binary * values -- it can only contain sub-Columns. * * @param keyspace * @param key * @param column_path * @param value * @param timestamp * @param consistency_level */ public void insert(String keyspace, String key, ColumnPath column_path, byte[] value, long timestamp, int consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, TException; /** * Insert Columns or SuperColumns across different Column Families for the same row key. batch_mutation is a * map<string, list<ColumnOrSuperColumn>> -- a map which pairs column family names with the relevant ColumnOrSuperColumn * objects to insert. * * @param keyspace * @param key * @param cfmap
  • 10. * @param consistency_level */ public void batch_insert(String keyspace, String key, Map<String,List<ColumnOrSuperColumn>> cfmap, int consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, TException; 读取数据 获取一个查询条件精确的值。 /** * Get the Column or SuperColumn at the given column_path. If no value is present, NotFoundException is thrown. (This is * the only method that can throw an exception under non-failure conditions.) * * @param keyspace * @param key * @param column_path * @param consistency_level */ public ColumnOrSuperColumn get(String keyspace, String key, ColumnPath column_path, int consistency_level) throws InvalidRequestException, NotFoundException, UnavailableException, TimedOutException, TException; /** * Perform a get for column_path in parallel on the given list<string> keys. The return value maps keys to the * ColumnOrSuperColumn found. If no value corresponding to a key is present, the key will still be in the map, but both * the column and super_column references of the ColumnOrSuperColumn object it maps to will be null. * * @param keyspace * @param keys * @param column_path * @param consistency_level */ public Map<String,ColumnOrSuperColumn> multiget(String keyspace, List<String> keys, ColumnPath column_path, int consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, TException; 获取某一个 keyspace,Key,ColumnFamily,SuperColumn(如果有的话需要指定)下面的相关数 据:只查询 Column 的 name 符合条件的相关数据(SlicePredicate)。
  • 11. /** * Get the group of columns contained by column_parent (either a ColumnFamily name or a ColumnFamily/SuperColumn name * pair) specified by the given SlicePredicate. If no matching values are found, an empty list is returned. * * @param keyspace * @param key * @param column_parent * @param predicate * @param consistency_level */ public List<ColumnOrSuperColumn> get_slice(String keyspace, String key, ColumnParent column_parent, SlicePredicate predicate, int consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, TException; /** * Performs a get_slice for column_parent and predicate for the given keys in parallel. * * @param keyspace * @param keys * @param column_parent * @param predicate * @param consistency_level */ public Map<String,List<ColumnOrSuperColumn>> multiget_slice(String keyspace, List<String> keys, ColumnParent column_parent, SlicePredicate predicate, int consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, TException; 查询 Key 的取值范围(使用这个功能需要使用 order-preserving partitioner)。 /** * @deprecated; use get_range_slice instead * * @param keyspace * @param column_family * @param start * @param finish * @param count * @param consistency_level */
  • 12. public List<String> get_key_range(String keyspace, String column_family, String start, String finish, int count, int consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, TException; /** * returns a subset of columns for a range of keys. * * @param keyspace * @param column_parent * @param predicate * @param start_key * @param finish_key * @param row_count * @param consistency_level */ public List<KeySlice> get_range_slice(String keyspace, ColumnParent column_parent, SlicePredicate predicate, String start_key, String finish_key, int row_count, int consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, TException; 查询系统的信息。 /** * get property whose value is of type string. * * @param property */ public String get_string_property(String property) throws TException; /** * get property whose value is list of strings. * * @param property */ public List<String> get_string_list_property(String property) throws TException; /** * describe specified keyspace * * @param keyspace */ public Map<String,Map<String,String>> describe_keyspace(String keyspace) throws NotFoundException, TException;
  • 13. 通过这些操作,我们可以了解到系统的信息。 其中一个比较有意思的查询信息是:token map,通过这个我们可以知道哪些 Cassandra Service 是可 以提供服务的。 删除数据 /** * Remove data from the row specified by key at the granularity specified by column_path, and the given timestamp. Note * that all the values in column_path besides column_path.column_family are truly optional: you can remove the entire * row by just specifying the ColumnFamily, or you can remove a SuperColumn or a single Column by specifying those levels too. * * @param keyspace * @param key * @param column_path * @param timestamp * @param consistency_level */ public void remove(String keyspace, String key, ColumnPath column_path, long timestamp, int consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, TException; 这里需要注意的是,由于一致性的问题。这里的删除操作不会立即删除所有机器上的该数据,但是最终会 一致。 程序范例 import java.util.List; import java.io.UnsupportedEncodingException; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TSocket; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.TException; import org.apache.cassandra.service.*; public class CClient { public static void main(String[] args)
  • 14. throws TException, InvalidRequestException, UnavailableException, UnsupportedEncodingException, NotFoundException { TTransport tr = new TSocket("localhost", 9160); TProtocol proto = new TBinaryProtocol(tr); Cassandra.Client client = new Cassandra.Client(proto); tr.open(); String key_user_id = "逖靖寒的世界"; // insert data long timestamp = System.currentTimeMillis(); client.insert("Keyspace1", key_user_id, new ColumnPath("Standard1", null, "网址".getBytes("UTF-8")), "http://gpcuster.cnblogs.com".getBytes("UTF-8"), timestamp, ConsistencyLevel.ONE); client.insert("Keyspace1", key_user_id, new ColumnPath("Standard1", null, "作者".getBytes("UTF-8")), "逖靖寒".getBytes("UTF-8"), timestamp, ConsistencyLevel.ONE); // read single column ColumnPath path = new ColumnPath("Standard1", null, "name".getBytes("UTF-8")); System.out.println(client.get("Keyspace1", key_user_id, path, ConsistencyLevel.ONE)); // read entire row SlicePredicate predicate = new SlicePredicate(null, new SliceRange(new byte[0], new byte[0], false, 10)); ColumnParent parent = new ColumnParent("Standard1", null); List<ColumnOrSuperColumn> results = client.get_slice("Keyspace1", key_user_id, parent, predicate, ConsistencyLevel.ONE); for (ColumnOrSuperColumn result : results) { Column column = result.column; System.out.println(new String(column.name, "UTF-8") + " -> " + new String(column.value, "UTF-8")); } tr.close();
  • 15. } } 优点与缺点 优点:简单高效 缺点:功能简单,无法提供连接池,错误处理等功能,不适合直接在生产环境使用。 Hector Hector 是基于 Thrift Java API 包装的一个 Java 客户端,提供一个更加高级的一个抽象。 程序范例 package me.prettyprint.cassandra.service; import static me.prettyprint.cassandra.utils.StringUtils.bytes; import static me.prettyprint.cassandra.utils.StringUtils.string; import org.apache.cassandra.service.Column; import org.apache.cassandra.service.ColumnPath; public class ExampleClient { public static void main(String[] args) throws IllegalStateException, PoolExhaustedException, Exception { CassandraClientPool pool = CassandraClientPoolFactory.INSTANCE.get(); CassandraClient client = pool.borrowClient("localhost", 9160); // A load balanced version would look like this: // CassandraClient client = pool.borrowClient(new String[] {"cas1:9160", "cas2:9160", "cas3:9160"}); try { Keyspace keyspace = client.getKeyspace("Keyspace1"); ColumnPath columnPath = new ColumnPath("Standard1", null, bytes("网址")); // insert keyspace.insert("逖靖寒的世界", columnPath, bytes("http://gpcuster.cnblogs.com")); // read Column col = keyspace.getColumn("逖靖寒的世界", columnPath);
  • 16. System.out.println("Read from cassandra: " + string(col.getValue())); } finally { // return client to pool. do it in a finally block to make sure it's executed pool.releaseClient(client); } } } 优点 1 提供连接池。 2 提 供 错 误 处 理 : 当 操 作 失 败 的 时 候 , Hector 会 根 据 系 统 信 息 ( token map ) 自 动 连 接 另 一 个 Cassandra Service。 3 编程接口容易使用。 4 支持 JMX。 缺点 1 不支持多线程的环境。 2 keyspace 封装过多(数据校验和数据重新封装),如果进行大量的数据操作,这里的消耗需要考虑。 3 错误处理不够人性化:如果所有的 Cassandra Service 都非常繁忙,那么经过多次操作失败后,最终 的结果失败。 总结 Hector 已经是一个基本足够使用的 Java 客户端了,但是还是缺乏一些相关的功能,比如: 1 线程安全。 2 支持自动的多线程查询和插入,提高操作效率。 3 人性化的错误处理机制。 4 避免过多的封装。
  • 17. Linux 下如何设置环境变量,今天总结了一下,发出来和大家分享一下,希望对大家的学 习有所帮助,不多说了,看具体怎么操作了... 1、总结背景 在 linux 系统下,下载并安装了应用程序,很有可能在键入它的名称时出现“command not found”的提示内容。每次都到安装目标文件夹内,找到可执行文件来进行操作就太繁琐了。 这涉及到环境变量 PATH 的设置问题,而 PATH 的设置也是在 linux 下定制环境变量的一个 组成部分。案例基于 RedHat AS4 讲解环境变量定制的问题。 2、变量简介 Linux 是一个多用户的操作系统。每个用户登录系统后,都会有一个专用的运行环境。通常 每个用户默认的环境都是相同的,这个默认环境实际上就是一组环境变量的定义。用户可以 对自己的运行环境进行定制,其方法就是修改相应的系统环境变量。 3、定制环境变量 环境变量是和 Shell 紧密相关的,用户登录系统后就启动了一个 Shell。对于 Linux 来说一般 是 bash,但也可以重新设定或切换到其它的 Shell(使用 chsh 命令)。 根据发行版本的情况,bash 有两个基本的系统级配置文件:/etc/bashrc 和/etc/profile。这
  • 18. 些配置文件包含两组不同的变量:shell 变量和环境变量。前者只是在特定的 shell 中固定 (如 bash),后者在不同 shell 中固定。很明显,shell 变量是局部的,而环境变量是全局 的。环境变量是通过 Shell 命令来设置的,设置好的环境变量又可以被所有当前用户所运行 的程序所使用。对于 bash 这个 Shell 程序来说,可以通过变量名来访问相应的环境变量, 通过 export 来设置环境变量。 注:Linux 的环境变量名称一般使用大写字母 4、环境变量设置实例 1.使用命令 echo 显示环境变量 本例使用 echo 显示常见的变量 HOME $ echo $HOME /home/kevin 2.设置一个新的环境变量 $ export MYNAME=”my name is kevin” $ echo $ MYNAME
  • 19. my name is Kevin 3.修改已存在的环境变量 接上个示例 $ MYNAME=”change name to jack” $ echo $MYNAME change name to jack 4.使用 env 命令显示所有的环境变量 $ env HOSTNAME=localhost.localdomain SHELL=/bin/bash TERM=xterm HISTSIZE=1000
  • 20. SSH_CLIENT=192.168.136.151 1740 22 QTDIR=/usr/lib/qt-3.1 SSH_TTY=/dev/pts/0 …… 5.使用 set 命令显示所有本地定义的 Shell 变量 $ set BASH=/bin/bash BASH_ENV=/root/.bashrc …… 6.使用 unset 命令来清除环境变量 $ export TEMP_KEVIN=”kevin” #增加一个环境变量 TEMP_KEVIN $ env | grep TEMP_KEVIN #查看环境变量 TEMP_KEVIN 是否生效(存在即生效)
  • 21. TEMP_KEVIN=kevin #证明环境变量 TEMP_KEVIN 已经存在 $ unset TEMP_KEVIN #删除环境变量 TEMP_KEVIN $ env | grep TEMP_KEVIN #查看环境变量 TEMP_KEVIN 是否被删除,没有输出显示, 证明 TEMP_KEVIN 被清除了。 7.使用 readonly 命令设置只读变量 注:如果使用了 readonly 命令的话,变量就不可以被修改或清除了。 $ export TEMP_KEVIN ="kevin" #增加一个环境变量 TEMP_KEVIN $ readonly TEMP_KEVIN #将环境变量 TEMP_KEVIN 设为只读 $ env | grep TEMP_KEVIN #查看环境变量 TEMP_KEVIN 是否生效 TEMP_KEVIN=kevin #证明环境变量 TEMP_KEVIN 已经存在 $ unset TEMP_KEVIN #会提示此变量只读不能被删除 -bash: unset: TEMP_KEVIN: cannot unset: readonly variable
  • 22. $ TEMP_KEVIN ="tom" #修改变量值为 tom 会提示此变量只读不能被修改 -bash: TEMP_KEVIN: readonly variable 8.通过修改环境变量定义文件来修改环境变量。 需要注意的是,一般情况下,仅修改普通用户环境变量配置文件,避免修改根用户的环境 定义文件,因为那样可能会造成潜在的危险。 $ cd ~ #到用户根目录下 $ ls -a #查看所有文件,包含隐藏的文件 $ vi .bash_profile #修改用户环境变量文件 例如: 编辑你的 PATH 声明,其格式为: PATH=$PATH:<PATH 1>:<PATH 2>:<PATH 3>:------:<PATH N> 你可以自己加上指定的路径,中间用冒号隔开。
  • 23. 环境变量更改后,在用户下次登陆时生效。 如果想立刻生效,则可执行下面的语句:$source .bash_profile 需要注意的是,最好不要把当前路径”./”放到 PATH 里,这样可能会受到意想不到的攻击。 完成后,可以通过$ echo $PATH 查看当前的搜索路径。这样定制后,就可以避免频繁的启 动位于 shell 搜索的路径之外的程序了。 5、学习总结 1.Linux 的变量种类 按变量的生存周期来划分,Linux 变量可分为两类: 1. 永久的:需要修改配置文件,变量永久生效。 2. 临时的:使用 export 命令行声明即可,变量在关闭 shell 时失效。 2.设置变量的三种方法 1. 在/etc/profile 文件中添加变量【对所有用户生效(永久的)】
  • 24. 用 VI 在文件/etc/profile 文件中增加变量,该变量将会对 Linux 下所有用户有效,并且是“ 永久的”。 例如:编辑/etc/profile 文件,添加 CLASSPATH 变量 # vi /etc/profile export CLASSPATH=./Java_HOME/lib;$JAVA_HOME/jre/lib 注:修改文件后要想马上生效还要运行# source /etc/profile 不然只能在下次重进此用户时 生效。 2. 在用户目录下的.bash_profile 文件中增加变量【对单一用户生效(永久的)】 用 VI 在用户目录下的.bash_profile 文件中增加变量,改变量仅会对当前用户有效,并且是 “永久的”。 例如:编辑 guok 用户目录(/home/guok)下的.bash_profile $ vi /home/guok/.bash.profile 添加如下内容:
  • 25. export CLASSPATH=./JAVA_HOME/lib;$JAVA_HOME/jre/lib 注:修改文件后要想马上生效还要运行$ source /home/guok/.bash_profile 不然只能在下 次重进此用户时生效。 3. 直接运行 export 命令定义变量【只对当前 shell(BASH)有效(临时的)】 在 shell 的命令行下直接使用[export 变量名=变量值]定义变量,该变量只在当前的 shell(BASH)或其子 shell(BASH)下是有效的,shell 关闭了,变量也就失效了,再打 开新 shell 时就没有这个变量,需要使用的话还需要重新定义。 Cassandra 文章分类 :数据库 Cassandra 下载 http://www.apache.org/dyn/closer.cgi?path=/cassandra/0.5.1/apache-cassandra-0.5.1-bin.tar.gz apache-cassandra-0.5.1 自 带 的 hector-0.5.0-7.jar 有 严 重 的 性 能 问 题 , 需 要 修 改 成 hector-0.5.1-9.jar
  • 26. 资源 http://cassandra.apache.org/ http://wiki.apache.org/cassandra/FrontPage 部署 http://kauu.net/2010/02/27/cassandra%E5%88%9D%E4%BD%93%E9%AA%8C/ 192.168.2.79 /home/bmb/apache-cassandra-0.5.1 DataModal 设计 对同一行的所有列,可以定义根据列名的排序规则(即保存规则)。当保存 某个用户相对应的朋友的时候,可以用朋友的加入时间作为一个一个的列名, 列按照时间倒序拍。这样很容易获得用户最新的朋友。 测试,Keyspace1 的 Standard1 的列按照 BytesType 进行排序,不管按照什么 set 顺序,get_slice 都会获得,a,b,c 的顺序 <ColumnFamily CompareWith="BytesType" Name="Standard1" /> set Keyspace1.Standard1['jsmith']['c'] = 'c' set Keyspace1.Standard1['jsmith']['a'] = 'a' set Keyspace1.Standard1['jsmith']['b'] = 'b'
  • 27. Super columns Super columns are a great way to store one-to-many indexes to other records: make the sub column names TimeUUIDs (or whatever you'd like to use to sort the index), and have the values be the foreign key. 不如某个用户的好友,Sub column name 是好友加入时间,Sub column value 是 好友的 ID,可以作为外键关联好友的信息表。 复合 Key 可以等效 Super Columns,列名为时间 Alternatively, we could preface the status keys with the user key, which has less temporal locality. If we used user_id:status_id as the status key, we could do range queries on the user fragment to get tweets-by-user, avoiding the need for a user_timeline super column. In column-orientation, the column names are the data 列名 TimeUUID,列值 JSON 格式,可以解决一些问题  http://blog.evanweaver.com/articles/2009/07/06/up-and-running-with-cassandra/ Twitter 怎样使用 Cassandra,Twitter 的 Data Model,Blog 的 Data Model http://arin.me/blog/wtf-is-a-supercolumn-cassandra-data-model Digg 提供的一个完整例子 http://wiki.apache.org/cassandra/DataModel http://wiki.apache.org/cassandra/CassandraLimitations http://www.hellodba.net/2010/02/cassandra.html (中文翻译,有出入)介绍 Twitter 的 Data Modal,有借鉴意义 修改 Schema 定义, 2 次重启 https://issues.apache.org/jira/browse/CASSANDRA-44
  • 28. 动态创建 Column Falimy,在不重启服务器下 http://github.com/NZKoz/cassandra_object 启动单个节点的 Cluster 安装 JDK 6 tar -zxvf cassandra-$VERSION.tgz cd cassandra-$VERSION sudo mkdir -p /var/log/cassandra sudo chown -R `whoami` /var/log/cassandra sudo mkdir -p /var/lib/cassandra sudo chown -R `whoami` /var/lib/cassandra 修改/bin/cassandra.in.sh 里面的启动端口(-Dcom.sun.management.jmxremote.port=8080) bin/cassandra -f 查看日志 tail -f /var/log/cassandra/system.log 客户端连接 cd /home/bmb/apache-cassandra-0.5.1 bin/cassandra-cli --host 192.168.2.79 --port 9160 cassandra> set Keyspace1.Standard1['jsmith']['first'] = 'John' Value inserted. cassandra> set Keyspace1.Standard1['jsmith']['last'] = 'Smith' Value inserted. cassandra> set Keyspace1.Standard1['jsmith']['age'] = '42' Value inserted. cassandra> get Keyspace1.Standard1['jsmith'] (column=age, value=42; timestamp=1249930062801) (column=first, value=John; timestamp=1249930053103) (column=last, value=Smith; timestamp=1249930058345)
  • 29. Returned 3 rows. cassandra> Java 客户端 原始 Thrift http://apache.freelamp.com/incubator/thrift/0.2.0-incubating/thrift-0.2.0-incubating.tar.gz 封装 http://github.com/charliem/OCM 手动编译 Java Thrift cd D:7gPersonalResourcesArchitectureCassandrathrift-0.2.0libjava ant hector http://prettyprint.me/2010/02/23/hector-a-java-cassandra-client/ http://github.com/rantav/hector/downloads OCM http://github.com/charliem/OCM/downloads Git 下载 Git http://kernel.org/pub/software/scm/git/git-1.7.0.3.tar.gz 安装 cd /home/bmb/apache-cassandra-0.5.1/git-1.7.0.3 ./configure make make install
  • 30. Git 客户端 http://msysgit.googlecode.com/files/msysGit-fullinstall-1.7.0.2-preview20100309.exe D:7gPersonalResourcesArchitectureCassandramsysgitmsysgit git-cmd.bat Check out OCM git clone http://github.com/charliem/OCM.git http://tortoisegit.googlecode.com/files/TortoiseGit-1.3.6.0-32bit.msi 集群配置 http://pan-java.javaeye.com/blog/604672 192.168.5.11 /u/iic/bmb/apache-cassandra-0.5.1 修改 conf 下面的文件 /var/log/cassandra 成/u/iic/bmb/apache-cassandra-0.5.1/log /var/lib/cassandra 成/u/iic/bmb/apache-cassandra-0.5.1/log 修改 bin/cassandra 的 Java_home export JAVA_HOME=/u/iic/bmb/jdk6 192.168.5.12 (目录配置同 5.11,都以 2.79 为 Seed) 注意:部署集群的时候,不能把 5.11 整个目录搬到 5.12 上,不然他们 Token 一样,会导致 Ring 路 5.11 和 5.12 重复。解决方法:删除 data 和 commit 目录。 还有所有的 IP 必须配置成绝对 IP,如果配 Localhost,会使 Ring 不完整 192.168.2.79 /home/bmb/apache-cassandra-0.5.1 bin/cassandra -f
  • 31. OCM 的使用 定义数据结构: D:7gPersonalResourcesArchitectureCassandraClientOCM CompilerOCMSpecSample.txt 通过 com.kissintellignetsystems.ocm.compiler.Compiler 类,提供以下的命令 行参数,生成 Java 对象:"OCMSpecSample.txt", "keyspace1", "Java", "mynamespace", "output/" 测试例子: D:7gPersonalResourcesArchitectureCassandraClientOutput LanguagesJavaTestHarness CreatTest.java get keyspace1.Users['charlie'] bin/cassandra-cli --host 192.168.2.79 --port 9160 bin/cassandra-cli --host 192.168.5.11 --port 9160 bin/cassandra-cli --host 192.168.5.12 --port 9160 查看集群的节点信息 bin/nodeprobe -host localhost -port 8090 ring Hadoop & Cassandra using Hadoop to Cassandra through Binary Memtable http://github.com/lenn0x/Cassandra-Hadoop-
  • 32. BMT/blob/master/src/java/org/digg/CassandraBulkLoader.java http://blog.csdn.net/wdwbw/archive/2010/03/10/5366739.aspx http://www.roadtofailure.com/2009/10/29/hbase-vs-cassandra-nosql-battle/ Cassandra 是一个开源的分布式数据库,结合了 Dynamo 的 Key/Value 与 Bigtable 的面向列的特点。 Cassandra 的特点如下: 1.灵活的 schema:不需要象数据库一样预先设计 schema,增加或者删除字段非常方便(on the fly)。 2.支持 range 查询:可以对 Key 进行范围查询。 3.高可用,可扩展:单点故障不影响集群服务,可线性扩展。 我们可以将 Cassandra 的数据模型想象成一个四维或者五维的 Hash。 Column Column 是 Cassandra 中最小的数据单元。它是一个 3 元的数据类型,包含:name,value 和 timestamp。 将一个 Column 用 JSON 的形式表现出来如下: { // 这是一个 column 2: name: "逖靖寒的世界", 3: value: "gpcuster@gmali.com", 4: timestamp: 123456789 5: } 为了简单起见,我们可以忽略 timestamp。就把 column 想象成一个 name/value 即可。 注意,这里提到的 name 和 value 都是 byte[]类型的,长度不限。 SuperColumn 我们可以将 SuperColumn 想象成 Column 的数组,它包含一个 name,以及一系列相应的 Column。 将一个 SuperColumn 用 JSON 的形式表现如下:
  • 33. 1: { // 这是一个 SuperColumn 2: name: "逖靖寒的世界", 3: // 包含一系列的 Columns 4: value: { 5: street: {name: "street", value: "1234 x street", timestamp: 123456789}, 6: city: {name: "city", value: "san francisco", timestamp: 123456789}, 7: zip: {name: "zip", value: "94107", timestamp: 123456789}, 8: } 9: } Columns 和 SuperColumns 都是 name 与 value 的组合。最大的不同在于 Column 的 value 是一个 “string”,而 SuperColumn 的 value 是 Columns 的 Map。 还有一点需要注意的是:SuperColumn’本身是不包含 timestamp 的。 ColumnFamily ColumnFamily 是一个包含了许多 Row 的结构,你可以将它想象成 RDBMS 中的 Table。 每一个 Row 都包含有 client 提供的 Key 以及和该 Key 关联的一系列 Column。 我们可以看看结构: 1: UserProfile = { // 这是一个 ColumnFamily 2: phatduckk: { // 这是对应 ColumnFamily 的 key 3: // 这是 Key 下对应的 Column 4: username: "gpcuster", 5: email: "gpcuster@gmail.com", 6: phone: "6666" 7: }, // 第一个 row 结束 8: ieure: { // 这是 ColumnFamily 的另一个 key 9: //这是另一个 Key 对应的 column 10: username: "pengguo", 11: email: "pengguo@live.com", 12: phone: "888" 13: age: "66" 14: }, 15: } ColumnFamily 的类型可以为 Standard,也可以是 Super 类型。 我们刚刚看到的那个例子是一个 Standard 类型的 ColumnFamily。Standard 类型的 ColumnFamily 包 含了一系列的 Columns(不是 SuperColumn)。
  • 34. Super 类型的 ColumnFamily 包含了一系列的 SuperColumn,但是并不能像 SuperColumn 那样包含 一系列 Standard ColumnFamily。 这是一个简单的例子: 1: AddressBook = { // 这是一个 Super 类型的 ColumnFamily 2: phatduckk: { // key 3: friend1: {street: "8th street", zip: "90210", city: "Beverley Hills", state: "CA"}, 4: John: {street: "Howard street", zip: "94404", city: "FC", state: "CA"}, 5: Kim: {street: "X street", zip: "87876", city: "Balls", state: "VA"}, 6: Tod: {street: "Jerry street", zip: "54556", city: "Cartoon", state: "CO"}, 7: Bob: {street: "Q Blvd", zip: "24252", city: "Nowhere", state: "MN"}, 8: ... 9: }, // row 结束 10: ieure: { // key 11: joey: {street: "A ave", zip: "55485", city: "Hell", state: "NV"}, 12: William: {street: "Armpit Dr", zip: "93301", city: "Bakersfield", state: "CA"}, 13: }, 14: } Keyspace Keyspace 是我们的数据最外层,你所有的 ColumnFamily 都属于某一个 Keyspace。一般来说,我们的 一个程序应用只会有一个 Keyspace。 简单测试 我们将 Cassandra 运行起来以后,启动命令行,执行如下操作: cassandra> set Keyspace1.Standard1['jsmith']['first'] = 'John' Value inserted. cassandra> set Keyspace1.Standard1['jsmith']['last'] = 'Smith' Value inserted. cassandra> set Keyspace1.Standard1['jsmith']['age'] = '42' Value inserted. 这个时候,Cassandra 中就已经有 3 条数据了。 其中插入数据的各个字段含义如下:
  • 35. 接下来,我们执行查询操作: cassandra> get Keyspace1.Standard1['jsmith'] (column=age, value=42; timestamp=1249930062801) (column=first, value=John; timestamp=1249930053103) (column=last, value=Smith; timestamp=1249930058345) Returned 3 rows. 这样,我们就可以将之前插入的数据查询出来了。 排序 有一点需要明确,我们使用 Cassandra 的时候,数据在写入的时候就已经排好顺序了。 在某一个 Key 内的所有 Column 都是按照它的 Name 来排序的。我们可以在 storage-conf.xml 文件中 指定排序的类型。 目前 Cassandra 提供的排序类型有:BytesType, UTF8Type,LexicalUUIDType, TimeUUIDType, AsciiType,和 LongType。 现在假设你的原始数据如下: {name: 123, value: "hello there"}, {name: 832416, value: "kjjkbcjkcbbd"}, {name: 3, value: "101010101010"}, {name: 976, value: "kjjkbcjkcbbd"} 当我们 storage-conf.xml 文件中指定排序的类型为 LongType 时: <!-- ColumnFamily 在 storage-conf.xml 中定义 --> <ColumnFamily CompareWith="LongType" Name="CF_NAME_HERE"/> 排序后的数据就是这样的:
  • 36. {name: 3, value: "101010101010"}, {name: 123, value: "hello there"}, {name: 976, value: "kjjkbcjkcbbd"}, {name: 832416, value: "kjjkbcjkcbbd"} 如果我们指定排序的类型为 UTF8Type <!-- ColumnFamily 在 storage-conf.xml 中定义 --> <ColumnFamily CompareWith="UTF8Type" Name="CF_NAME_HERE"/> 排序后的数据就是这样的: {name: 123, value: "hello there"}, {name: 3, value: "101010101010"}, {name: 832416, value: "kjjkbcjkcbbd"}, {name: 976, value: "kjjkbcjkcbbd"} 大家可以看到,指定的排序类型不一样,排序的结果也是完全不同的。 对于 SuperColumn,我们有一个额外的排序维度,所以我们可以指定 CompareSubcolumnsWith 来 进行另一个维度的排序类型。 假设我们的原始数据如下: { // first SuperColumn from a Row name: "workAddress", // and the columns within it value: { street: {name: "street", value: "1234 x street"}, city: {name: "city", value: "san francisco"}, zip: {name: "zip", value: "94107"} } }, { // another SuperColumn from same Row name: "homeAddress", // and the columns within it value: { street: {name: "street", value: "1234 x street"}, city: {name: "city", value: "san francisco"}, zip: {name: "zip", value: "94107"}
  • 37. } } 然后我们定义 CompareSubcolumnsWith 和 CompareWith 的排序类型都是 UTF8Type,那么排序后 的结果为: { // this one's first b/c when treated as UTF8 strings { // another SuperColumn from same Row // This Row comes first b/c "homeAddress" is before "workAddress" name: "homeAddress", // the columns within this SC are also sorted by their names too value: { // see, these are sorted by Column name too city: {name: "city", value: "san francisco"}, street: {name: "street", value: "1234 x street"}, zip: {name: "zip", value: "94107"} } }, name: "workAddress", value: { // the columns within this SC are also sorted by their names too city: {name: "city", value: "san francisco"}, street: {name: "street", value: "1234 x street"}, zip: {name: "zip", value: "94107"} } } 再额外提一句,Cassandra 的排序功能是允许我们自己实现的,只要你继承 org.apache.cassandra.db.marshal.IType 就可以了。 参考文档 WTF is a SuperColumn? An Intro to the Cassandra Data Model DataModel