使用Cassandra CQL API的一些小经验

时间:2022-05-25 04:51:21

因为项目考虑把Cassandra作为备选平台,就使用CQL API实现了一些封装接口。在开发过程中,总结出一些小经验,供初接触的菜鸟们参考,也望大牛们多多指教。

1 PreparedStatement提前一次性创建

这一点是Cassandra中的PreparedStatement与关系型数据库的不同处之一。如果每次都创建相同的PreparedStatement,会收到警告信息提示说这样影响性能,所以最好是对常用操作提前一次性创建好PreparedStatement,建议用static方法。例如:

private static PrepareStatement insertStmt = null;
...

public static PreparedStatement buildInsertStmt(Session session)
{
   if (insertStmt==null)
      insertStmt  = session.prepare("insert into yourtable(a, b, c) values (?, ?, ?)");
   return insertStmt;
}

2 关于BatchStatement的限制

BatchStatement是提高运行性能的首要选择,但有两个限制需要注意。其一是BatchStatemen只针对增删改而不包括查询,本人也是菜鸟就犯了这种错误。其二是BatchStatement对数据大小有限制,由配置参数batch_size_warn_threshold_in_kb(默认是5KB)和batch_size_fail_threshold_in_kb(默认是50KB)决定。使用时注意尽量不要超出限制,特别是第二个。

3 关于CQL 的where子句的限制

尽管CQL与SQL很相似,但两者还是有很大的差别,尤其是在Where子句的限制上。具体实在太多这里一言难尽,请参见官方文档(http://www.datastax.com/dev/blog/a-deep-look-to-the-cql-where-clause)。

在项目中,要使用的接口中有几个是用非主键的列作为删除条件,直接删除是肯定行不通的,变通方法:

  • 先用非主键的列作为查询条件查询出满足条件的主键结果集,再用主键结果集作条件进行删除操作;
  • 要使用非主键列进行查询,需要在非主键列上提前建索引(推荐),或使用ALLOW FILTERING选项扫描全部分区(不推荐)。

4 关于row.getByte()方法

当从Row中取列值时,CQL API提供了getLong(), getInt(), getString(), getByte()等多种方法,但对于getByte()本人没搞明白怎么用。因为Cassandra的列类型中貌似没有byte,只能用int代替,如此一来若用getByte()来获取该列的值会抛类型转换失败的Exception。为此,项目中也只能放弃getByte():

byte b = (byte) row.getInt("byte_col");