6

我想在 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 驱动程序和 Thriftbatch_insert操作?

4

4 回答 4

3

编辑:在我发布有关 Cassandra 1.2.9 的问题仅 4 天后,Cassandra 2.0 最终版就发布了。2.0 支持批处理准备语句,这应该比 C* < 2.0 需要使用的非批处理 CQL3 快得多。我们尚未对此进行测试以确定。

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

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

于 2013-08-30T18:31:57.017 回答
3

通过使用变异多映射,可以使用 Thrift API 中的 batch_mutate 方法完成多个插入/更新。

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);
于 2013-08-30T12:51:26.573 回答
2
  1. CQL3INSERT语句不支持多值元组。但我认为这可以为 CQL 带来有趣的补充,因此请提交功能请求

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

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

于 2013-08-30T06:45:05.927 回答
0

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

使用 C* 2.0,它会更容易和更快,因为它们将启用批量准备好的语句

于 2013-08-31T19:26:39.853 回答