MySQL迁移到Cassandra技巧:放弃SQL思想

本文主要介绍Apache Cassandra的入门级用法。学习NoSQL最重要的就是要忘记常规原理和关系型数据库的结构。关系型数据库被设计为由常规数据组成,并且没有重复数据。因此,NoSQL数据库的一个主要改变是需要思考或设计查询,并按需创建一个不变的结构。

  许多网页、书籍与论文都在讨论什么是Cassandra、Hazelcast、Hadoop、MemcacheDB和MongoDB等等,但没有一个讨论如何将关系型数据库中的数据转换为这些NoSQL数据中的一种。

  本文对Turmeric SOA Monitoring与Turmeric SOA Rate Limiting两个模块的数据进行转换,使用关系数据库MySQL,并且对一些NoSQL数据库进行了为期一周的阅读与分析后,决定使用Cassandra。

  从关系表到Keyspaces

  (注:keyspace是Cassandra 中最顶层的命名空间。)

  现在要考虑的问题是如何转换它们,可按以下方法进行:

  根据敏捷开发的相关经验,如果某事件很难或很复杂,最好将其分成多个部分,因为毕竟与MMF(Minimal Marketable Feature,最小市场化功能)之间还有一定的差距。步骤如下:

  步骤1:将关系数据库中的表转移到Cassandra列族(Column Families)中

  步骤2:创建新的列族使所有数据无需进行JOIN等操作。

  步骤3:根据搜索器与查询方法的需要扩展列族。通常情况下一个搜索器或一个查询方法使用一个列族。

  步骤4:根据之前的步骤修改Creators与Updater函数。不要担心保存重复数据,只要记住一点:只需考虑数据查询,忘记以前关系型数据库相关的法则。

  步骤5:判断,如果没有完成,继续做步骤3与步骤4。

  Cassandra DAO

  在上面步骤中,最难的是第一步。不过不用担心,本文为数据转移开发了一个通用的Cassandra DAO(实际上是使用的Java泛型)。由于本例来源于实际项目,你可能发现它是作为TurmericSOA的子模块,不过根据Apache许可,用户可以在自己Maven依赖文件中使用它们。

<dependency>
<groupId>org.ebayopensource.turmeric.utils</groupId>
<artifactId>turmeric-utils-cassandra</artifactId>
<version>1.2.0.0-SNAPSHOT</version>
<type>jar</type>
</dependency>
  特性

  · 100%Java代码

  · 可以作为嵌入式Cassandra服务使用,也可以作为外部Cassandra服务使用

  · 使用Hector库作为Java Cassandra客户端

  · 动态创建列族(Column Family)

  · 关键字类型与数据类型在运行时使用泛型创建

  · 支持主要的CRUD方法:

boolean containsKey(KeyType key);

void delete(KeyType key);

T find(KeyType key);

Map> findItems(final List keys, final Long rangeFrom, final Long rangeTo);

Set findItems(final List keys, final String rangeFrom, final String rangeTo);

Set getKeys();

void save(KeyType key, T model);
  主要的类

  该功能包包含以下包和类:

  1. org.ebayopensource.turmeric.utils.cassandra.service

  · CassandraManager: 根据yaml配置文件初始化静态EmbeddedCassandraService实例

  2. org.ebayopensource.turmeric.utils.cassandra.hector

  · HectorManager: 管理keyspace与列族的创建与读取,使用Hector API。

  · HectorHelper: 包含一些基于Java Reflection与Java Generics的实用方法。IE: 从在cassandra keyspaces中作为列名的POJO中检索字段名。

  3. org.ebayopensource.turmeric.utils.cassandra.dao

  · AbstractColumnFamilyDao: 如其名称,是每个dao都要扩展的基类,利用Dector Api定义并实现了基本的DAO操作。

 

  配置文件

  · log4j.properties: Log4j属性文件

  · cassandra.yaml: 存储配置文件。更多信息可参考storage configuration setup。

  以下为配置文件的目录结构:

META-INF/
         security/
                  config/
                         cassandra/
                                   cassandra.properties
  属性文件的一个示例:

cassandra-cluster-name=TurmericCluster
cassandra-host-ip=127.0.0.1
cassandra-rpc-port=9160
cassandra-my-keyspace=My-keyspace

#column families
cassandra-foo-column-family=foo
cassandra-bar-column-family=bar
  使用方法

  假定关系数据库MySQL中有一个名为Foo的表。则:

  1. 创建BaseDao接口

public interface BaseDao {
          public void delete(String key);
          public Set getKeys();
          public boolean  containsKey(String key);
          public void save(String key, FooPojoClass  fooPojo);
          public FooPojoClass find(String key);
}
  2. 创建FooDao接口

public interface FooDao extends BaseDao  {
}
  3. 创建FooDao implementation

  public class FooDaoImpl extends AbstractColumnFamilyDao

  implements FooDao {

  public FooDaoImpl(final String clusterName, final String host, final String keySpace, final String cf, final Class kTypeClass) {

  super(clusterName, host, keySpace, kTypeClass, FooPojo.class, cf);

  }

  }
  自定义的代码

//initiates an embedded Cassandra Service
CassandraManager.initialize();

//creates our Foo Column Family
FooDao fooDao = new FooDaoImpl("myCluster", "127.0.0.1", "myKeyspace",
                "myColumnFamilyName", String.class);
  至此,已经成功将一个关系表转换为一个Cassandra列族!

  用户可以参考UT类来查看它们具体是如何实现的。
 

你可能感兴趣的:(开发,技巧,设计,如何,关系数据库)