【问题标题】:Get rows using first component of composite key using hector client in Cassandra使用 Cassandra 中的 hector 客户端使用复合键的第一个组件获取行
【发布时间】:2013-10-22 20:08:57
【问题描述】:

我在rowkey中使用复合数据类型,列族如下

create column family CompositeTest
with comparator = 'UTF8Type'
and key_validation_class = 'CompositeType(UTF8Type,UTF8Type)'
and default_validation_class = 'UTF8Type';

该列族的样本数据如下,

RowKey: s2:2222222
=> (column=param1, value=value1
=> (column=param2, value=value2
=> (column=param3, value=value3
-------------------
RowKey: s2:3333333
=> (column=param1, value=value1
=> (column=param2, value=value2
=> (column=param3, value=value3
-------------------
RowKey: s2:1111111
=> (column=param1, value=value1
=> (column=param2, value=value2
=> (column=param3, value=value3
-------------------
RowKey: s1:3333333
=> (column=param1, value=value1
=> (column=param2, value=value2
=> (column=param3, value=value3
-------------------
RowKey: s1:2222222
=> (column=param1, value=value1
=> (column=param2, value=value2
=> (column=param3, value=value3
-------------------
RowKey: s1:1111111
=> (column=param1, value=value1
=> (column=param2, value=value2
=> (column=param3, value=value3

我想获取行键的第一个组件是“s1”的所有行。是否可以使用 Hector 客户端?如果不是,那么可能由哪个 cassandra 客户端?

我尝试过使用以下代码,但它不起作用,

Composite start = new Composite();
        start.addComponent(0, "s1", ComponentEquality.EQUAL);

        Composite end = new Composite();
        end.addComponent(0, "s1", ComponentEquality.GREATER_THAN_EQUAL);

        RangeSlicesQuery<Composite, String, String> rangeSlicesQuery = HFactory.createRangeSlicesQuery(keyspace, new CompositeSerializer(), StringSerializer.get(),  StringSerializer.get()); 
        rangeSlicesQuery.setKeys(start, end);
        rangeSlicesQuery.setRange("param1", "param3", false, 100);
        rangeSlicesQuery.setColumnFamily("CompositeTest");
        rangeSlicesQuery.setRowCount(11);
        QueryResult<OrderedRows<Composite, String, String>>  queryResult = rangeSlicesQuery.execute();

        Rows<Composite, String, String> rows = queryResult.get();
        Iterator<Row<Composite, String, String>> rowsIterator = rows.iterator();

提前谢谢...

【问题讨论】:

  • Hector 客户端和 Astyanax 客户端都可以这样做。
  • 如果可能的话,你能告诉我如何使用 Hector 吗?

标签: java jakarta-ee cassandra hector


【解决方案1】:

这在 Cassandra 中使用任何客户端都是不可能的。虽然行键对您(应用程序开发人员)显示为复合对象,但在 Cassandra 本身中,行键是一个单一的字节数组,作为单个原子值存储在 Cassandra 的 SSTable 中。

意思是,你只能用整个键查询一行,而不仅仅是一个键的一部分。否则,您必须扫描整个列族,直到找到匹配项 - 这将非常昂贵。

话虽如此,如果您确实需要能够仅使用行键的一部分来查询列族中的行,那么我强烈建议为这些键部分创建单独的索引列族。这将允许您使用标准键/列查找来查找原始数据列族中符合您的条件的所有行。

【讨论】:

    【解决方案2】:

    问题是您试图对行键执行切片。 如果您在 Cassandra 中使用随机分区器(例如 RandomPartitioner 或 Murmur3Partitioner),则根本不可能。如果您使用的是顺序保留分区器,则可能(但我从未尝试过)。在您的情况下,应该是一个不存在不幸的 CompositeKeyPartitioner,因此您应该自己编写它。然后,您还应该根据您的数据计算正确的令牌来配置集群。 如您所见,这不是最简单的方法。

    但是,如果您只是将复合值放在列名而不是键中,您也可以这样做。 你可以这样定义你的CF:

    create column family CompositeTest
       with comparator = 'CompositeType(UTF8Type,UTF8Type)'
       and key_validation_class = 'UTF8Type'
       and default_validation_class = 'UTF8Type';
    

    并像这样存储数据:

    RowKey: s2
    => (column=2222222:param1, value=value1
    => (column=2222222:param2, value=value2
    => (column=2222222:param3, value=value3
    => (column=3333333:param1, value=value1
    => (column=3333333:param2, value=value2
    => (column=3333333:param3, value=value3
    => (column=1111111:param1, value=value1
    => (column=1111111:param2, value=value2
    => (column=1111111:param3, value=value3
    -------------------
    RowKey: s1:
    => (column=3333333:param1, value=value1
    => (column=3333333:param2, value=value2
    => (column=3333333:param3, value=value3
    => (column=2222222:param1, value=value1
    => (column=2222222:param2, value=value2
    => (column=2222222:param3, value=value3
    => (column=1111111:param1, value=value1
    => (column=1111111:param2, value=value2
    => (column=1111111:param3, value=value3
    

    使用这种结构,您认为查询非常简单,然后您始终可以对列名进行切片以仅选择所需区间内的那些列。

    【讨论】:

    • 即使使用 OPP(我不建议使用 - 这是专家模式功能),您仍然无法仅针对复合行键的一部分执行 RangeSlicesQuery。您必须针对整个行键执行此操作,即获取 COMPLETE ROW KEY A 到 COMPLETE ROW KEY B 之间的所有键。
    • 你为什么这么说?正如我所说,您应该有一个可以正确排序复合值的分区器,但这与列名的逻辑几乎相同。实际上,应该只使用值 ComponentEquality.GREATER_THAN_EQUAL 或 ComponentEquality.EQUAL 设置复合键的空白部分,具体取决于键是起始键还是结束键。它的一部分,这是完全可能的..但肯定不建议。 ;)
    猜你喜欢
    • 2013-11-01
    • 2012-04-23
    • 2012-08-29
    • 2011-12-23
    • 2013-05-23
    • 2011-11-15
    • 2013-10-28
    • 2013-02-22
    • 2012-03-12
    相关资源
    最近更新 更多