Accumulo 范围 - 结束键不包含

Accumulo Range - End Key Not Inclusive

我正在学习 Accumulo,但似乎无法让 Range 中指定的结束键包含在内。我的代码如下。我曾尝试在 Range 中将 endKeyInclusive 显式设置为 true,但这没有帮助。

BatchWriter writer = conn.createBatchWriter("table", config);

List<String> deterTimes = new ArrayList<>();

String rowId = "3015551212<ll>";
String columnFamily = "deter";
for (int i = 0; i < 10; i++) {
    String deterTime = "20181112:21:46:33" + i;
    deterTimes.add(deterTime);
    writer.addMutation(makeRecord(rowId, columnFamily, deterTime, "DETER" + i));                   
}

writer.flush();
writer.close();

Scanner scan = conn.createScanner("table", auths);

Key startKey = new Key(rowId.getBytes(), columnFamily.getBytes(), deterTimes.get(1).getBytes());
Key endKey = new Key(rowId.getBytes(), columnFamily.getBytes(), deterTimes.get(4).getBytes());
Range range = new Range(startKey, endKey);
if (range.isEndKeyInclusive())  System.out.println("true");
scan.setRange(range);

for (Entry<Key,Value> entry : scan) {
    Text row = entry.getKey().getRow();
    Text cq = entry.getKey().getColumnQualifier();
    Value value = entry.getValue();
    System.out.println("Fetched row " + row + " with value: " + value + ", cq=" + cq);
}

输出:

true
Fetched row 3015551212<ll> with value: DETER1, cq='20181112:21:46:331'
Fetched row 3015551212<ll> with value: DETER2, cq='20181112:21:46:332'
Fetched row 3015551212<ll> with value: DETER3, cq='20181112:21:46:333'

这里的范围是 运行,但您添加的值可能有问题

这会更容易通过输出进行诊断,但是您是否有可能期望阻止时间增加一倍,因为数组从零开始,所以您看到的阻止时间比预期少一倍?

如果不是这种情况,请分享您的输出

您正在使用 ( row, column family, column qualifier ) 作为字节数组构建结束键,键的剩余维度 ( column visibility, timestamp ) 设置为默认值(具体来说,一个空字节数组和 Long.MAX_VALUE , 分别).

扫描仪将停在那个确切的键处,包括在内。但是,您的实际数据输入几乎肯定不是那个 exact 键(您没有提供 makeRecord 的实现来验证)。即使您的数据实际上具有空列可见性,时间戳也几乎肯定不是 Long.MAX_VALUE,而是您在 makeRecord 实现中设置的内容,或者它是根据 tserver 的时间或某些 [=38] 设置的=] 逻辑计数器。由于密钥的时间戳维度是降序排列的,因此您的扫描器将在 Long.MAX_LONG 到达您的条目之前停止查找数据。

这有点像在字典中搜索 analogy,但是当您到达 analog 时停止:您将错过剩余的以 analog 开头的词。

这是基于精确键构建范围时的常见陷阱。通常最好基于行构建范围(inclusive on rows 将包括整个行),而不是键(有 Range constructor for that)。或者,指定结束键以使其独占工作。您可以通过将空字节附加到列的最后一个有意义的元素的末尾来实现。例如,您可以执行以下操作:

Key endKey = new Key(rowId.getBytes(),
                     columnFamily.getBytes(),
                     (deterTimes.get(4) + "[=10=]").getBytes());
Range range = new Range(startKey, true, endKey, false);

另一个你应该小心的陷阱是使用 String.getBytes() 来获取你的字节数组,而不指定编码。最好使用一致的东西,比如 "abc".getBytes(StandardCharsets.UTF_8)(不过我通常做静态导入,所以我只能指定 UTF_8)。