使用Cassandra和CQL3,如何在单个请求中插入整个宽行?

时间:2013-08-29 22:50:02

标签: cassandra cql3 datastax-java-driver

我想在Cassandra 1.2.8中插入一行包含50,000列的行。在插入之前,我已准备好整个行的所有数据(在内存中):

+---------+------+------+------+------+-------+
|         | 0    | 1    | 2    | ...  | 49999 |
| row_id  +------+------+------+------+-------+
|         | text | text | text | ...  | text  |
+---------+------+------+------|------+-------+

列名是整数,允许切片进行分页。 列值是该特定索引处的值。

CQL3表定义:

create table results (
    row_id text,
    index int,
    value text,
    primary key (row_id, index)
) 
with compact storage;

由于我已经在内存中拥有row_id和所有50,000个名称/值对,我只想在单个请求/操作中向Cassandra插入一行,以便尽可能快。

我唯一能找到的就是执行以下50,000次:

INSERT INTO results (row_id, index, value) values (my_row_id, ?, ?);

第一个?是索引计数器(i),第二个?是要存储在i位置的文本值。

这需要很多时间。即使我们将上述INSERT放入批处理中,也需要花费很多时间。

我们需要完整的所有数据(完整的行),我认为很容易说“这里,Cassandra,将这些数据作为一行存储在一个请求中”,例如:

//EXAMPLE-BUT-INVALID CQL3 SYNTAX:
insert into results (row_id, (index,value)) values 
    ((0,text0), (1,text1), (2,text2), ..., (N,textN));

此示例无法通过当前的CQL3语法实现,但我希望它能说明所需的效果:所有内容都将作为单个查询插入。

是否可以在CQL3和DataStax Java驱动程序中执行此操作?如果没有,我想我将被迫使用Hector或Astyanax驱动程序和Thrift batch_insert操作?

4 个答案:

答案 0 :(得分:3)

可以使用变异多映射在Thrift API中使用batch_mutate方法完成多个INSERT / UPDATE。

Map<byte[], Map<String, List<Mutation>>> mutationMap = new HashMap<byte[], Map<String, List<Mutation>>>();

List<Mutation> mutationList = new ArrayList<Mutation>();

mutationList.add(mutation);
Map<String, List<Mutation>> m = new HashMap<String, List<Mutation>>();

m.put(columnFamily, mutationList);

mutationMap.put(key, m);
client.batch_mutate(mutationMap, ConsistencyLevel.ALL);

答案 1 :(得分:3)

编辑:在我发布有关Cassandra 1.2.9的问题后仅4天,Cassandra 2.0 final就被发布了。 2.0支持批量准备语句,其比要求用于C *&lt;的非批量CQL3快得多。 2.0。我们还没有对此进行测试。

当这个问题于4天前发布于2013年8月30日时,CQL3中的C *版本不可能低于2.0。它只能通过Thrift客户端,例如Astyanax的MutationBatch

根据Alex的建议,我创建了CASSANDRA-5959作为功能请求,但它被标记为CASSANDRA-4693的副本,据说解决了C * 2.0的问题。

答案 2 :(得分:2)

  1. CQL3 INSERT语句不支持多值元组。但我认为这可以成为CQL的一个有趣的补充,所以请submit a feature request

  2. DataStax Java驱动程序基于CQL,因此如果不支持该语句,它可以执行任何操作。

  3. 暂时如果您需要这个,最好的选择是使用基于Thrift的库( nb :我不太熟悉基于Thrift的API来确认这一点插入是可能的,但我认为应该)

答案 3 :(得分:0)

如果要进行多次插入,请在CQL3中使用Batch语句。

使用C * 2.0,它将更容易,更快,因为它们将批量启用预处理语句