3

我是 Cassandra 的新手,我需要它来完成一项快速而小型的临时工作。但是,我遇到了一个问题。我有一个使用下面的 CQL 创建的列族:

创建表 dummy_file_test
(
 dtPtn INT,
 pxID 整数,
 startTm INT,
 endTm INT,
 patID BIGINT,
 电子文件 BLOB,
 主键(dtPtn,pxID,startTm)
);

我编写了以下方法将数据插入表中。

public static void insertDataKey(HashMap nameValuePair, String colFamily) {
    try {
        Cluster cluster = HFactory.getOrCreateCluster(clusterName, hostPort);
        Keyspace keyspace = HFactory.createKeyspace(CASSANDRA_DUMMY_KEY_SPACE, cluster);


        Integer dtPtn = (Integer)nameValuePair.get("dtPtn");
        Integer pxID = (Integer)nameValuePair.get("pxID");
        Integer startTm = (Integer)nameValuePair.get("startTm");
        Integer endTm = (Integer)nameValuePair.get("endTm");
        Long patID = (Long)nameValuePair.get("patID");
        byte[] efile = (byte[])nameValuePair.get("efile");


        HColumn<String, Integer> column1 = HFactory.createColumn("dtPtn", dtPtn, new StringSerializer(), IntegerSerializer.get());
        HColumn<String, Integer> column2 = HFactory.createColumn("pxID", pxID, new StringSerializer(), IntegerSerializer.get());
        HColumn<String, Integer> column3 = HFactory.createColumn("startTm", startTm, new StringSerializer(), IntegerSerializer.get());
        HColumn<String, Integer> column4 = HFactory.createColumn("endTm", endTm, new StringSerializer(), IntegerSerializer.get());
        HColumn<String, Long> column5 = HFactory.createColumn("patID", patID, new StringSerializer(), LongSerializer.get());
        HColumn<String, byte[]> column6 = HFactory.createColumn("efile", efile, new StringSerializer(), BytesArraySerializer.get());


        Composite rowKey = new Composite();
        rowKey.addComponent("dtPtn", StringSerializer.get());
        rowKey.addComponent(dtPtn, IntegerSerializer.get());

        rowKey.addComponent("pxID", StringSerializer.get());
        rowKey.addComponent(pxID, IntegerSerializer.get());

        rowKey.addComponent("startTm", StringSerializer.get());
        rowKey.addComponent(startTm, IntegerSerializer.get());


        Mutator<Composite> mutator = HFactory.createMutator(keyspace, CompositeSerializer.get());
        mutator.addInsertion(rowKey, colFamily, column1);
        mutator.addInsertion(rowKey, colFamily, column2);
        mutator.addInsertion(rowKey, colFamily, column3);
        mutator.addInsertion(rowKey, colFamily, column4);
        mutator.addInsertion(rowKey, colFamily, column5);
        mutator.addInsertion(rowKey, colFamily, column6);

        mutator.execute();
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

但是,当我运行代码时,我得到

InvalidRequestException(为什么:预期 4 或 0 字节 int (21))

我对 Hector API 很困惑,找不到任何我可以完全依赖的完整教程/材料。解决上述问题的任何建议都会有很大帮助。

提前致谢。

ps:我在 Cassandra 1.2

4

1 回答 1

4

如果您在 CQL 中创建模式,您可能最好也通过 CQL 访问您的数据。但是您仍然可以通过 Thrift 界面访问它。

当您指定在 CQL 中使用复合主键时,第一个键是分区键,它成为行键。其他键是列组合的一部分。

因此,对于您的示例,如果您这样做了

insert into dummy_file_test (dtPtn, pxID, startTm, endTm, patID, efile) values (1, 2, 3, 4, 5, 0x06);

然后在 cassandra-cli 中列出:

[default@ks] list dummy_file_test; 
RowKey: 1
=> (column=2:3:, value=, timestamp=1366620262555000)
=> (column=2:3:efile, value=06, timestamp=1366620262555000)
=> (column=2:3:endtm, value=00000004, timestamp=1366620262555000)
=> (column=2:3:patid, value=0000000000000005, timestamp=1366620262555000)

您会看到行键只是对应于 dtPtn 的整数 1。主键中的其他列已作为列名的前缀。

如果要使用 Hector 插入其中,则需要使用 dtPtn 作为行键,然后使用 pxID:startTm:col_name 的复合列键作为列。

您还可以告诉 Cassandra 使您的分区键成为列的组合。为此,您需要在主键子句中使用额外的括号:

CREATE TABLE dummy_file_test
(
 dtPtn          INT,
 pxID           INT,
 startTm        INT,
 endTm          INT,
 patID          BIGINT,
 efile          BLOB,
 PRIMARY KEY((dtPtn, pxID, startTm))
);

现在您的行键是 dtPtn、pxID、startTm 的组合:

[default@ks] list dummy_file_test;
RowKey: 1:2:3
=> (column=, value=, timestamp=1366620916952000)
=> (column=efile, value=06, timestamp=1366620916952000)
=> (column=endtm, value=00000004, timestamp=1366620916952000)
=> (column=patid, value=0000000000000005, timestamp=1366620916952000)

请注意,列名不会出现在行键组合中,因此您不需要添加它们。您的代码应该是:

Composite rowKey = new Composite();
rowKey.addComponent(dtPtn, IntegerSerializer.get());
rowKey.addComponent(pxID, IntegerSerializer.get());
rowKey.addComponent(startTm, IntegerSerializer.get());
于 2013-04-22T09:00:54.137 回答