9

有没有一种有效的方法来删除 HBase 中的多行,或者我的用例闻起来不适合 HBase?

有一个表说“图表”,其中包含图表中的项目。行键采用以下格式: chart|date_reversed|ranked_attribute_value_reversed|content_id

有时我想为给定日期重新生成图表,所以我想删除从“chart|date_reversed_1”到“chart|date_reversed_2”的所有行。有没有比为扫描找到的每一行发出删除更好的方法?所有要删除的行都将彼此靠近。

我需要删除这些行,因为我不希望一个项目(一个 content_id)有多个条目,如果它的ranked_attribute_value 已更改(它的更改是需要重新生成图表的原因)。

作为一个 HBase 初学者,所以我可能会误用行来代替列更好的东西——如果你有设计建议,很酷!或者,也许图表最好在文件中生成(例如,没有用于输出的 HBase)?我正在使用 MapReduce。

4

3 回答 3

7

首先,到了范围删除点,在 HBase、AFAIK 中还没有范围删除。但是有一种方法可以在HTableInterface API中一次删除多个行。为此,只需使用扫描中的行键形成一个 Delete 对象,并将它们放入 List 并使用 API,完成!为了使扫描更快,不要在扫描结果中包含任何列族,因为您只需要用于删除整行的行键。

其次,关于设计。首先我对需求的理解是,有内容ID的内容,每个内容都有针对它们生成的图表并存储这些数据;每个内容可以通过日期有多个图表,具体取决于排名。此外,我们希望最后生成的内容的图表显示在表格的顶部。

对于我对要求的假设,我建议使用三个表 - auto_id、content_charts 和 generate_order。content_charts 的行键是它的内容 id,而 generate_order 的行键是长的,它会使用HTableInterface API自动递减。对于递减,使用“-1”作为偏移量,并在应用程序首次启动时或手动初始化 auto_id 表中的 Long.MAX_VALUE 值。所以现在如果你想删除图表数据,只需使用delete清理列族然后把新数据放回去,然后放到generate_order表中。这样,最新插入也将位于最新插入表的顶部,该表将内容 id 作为单元格值。如果您想确保 generate_order 每个内容只有一个条目,请先保存 generate_order id,然后在放置时和删除列族之前将值保存到 content_charts 中,首先从 generate_order 中删除行。这样,您可以使用最多 2 个获取来查找内容并绘制图表,并且不需要对图表进行扫描。

我希望这是有帮助的。

于 2011-01-07T06:43:54.237 回答
2

您可以使用 BulkDeleteProtocol,它使用定义相关范围(开始行、结束行、过滤器)的扫描。

这里

于 2014-02-18T15:16:35.270 回答
2

我遇到了你的情况,这是我实现你想要的代码

Scan scan = new Scan();
    scan.addFamily("Family");
    scan.setStartRow(structuredKeyMaker.key(starDate));
    scan.setStopRow(structuredKeyMaker.key(endDate + 1));
try {
    ResultScanner scanner = table.getScanner(scan);


    Iterator<Entity> cdrIterator = new EntityIteratorWrapper(scanner.iterator(), EntityMapper.create(); // this is a simple iterator that maps rows to exact entity of mine, not so important ! 

    List<Delete> deletes = new ArrayList<Delete>();
    int bufferSize = 10000000; // this is needed so I don't run out of memory as I have a huge amount of data ! so this is a simple in memory buffer
    int counter = 0;
    while (entityIterator.hasNext()) {
        if (counter < bufferSize) {
                            // key maker is used to extract key as byte[] from my entity 
            deletes.add(new Delete(KeyMaker.key(entityIterator.next())));
            counter++;

        } else {
            table.delete(deletes);
            deletes.clear();
            counter = 0;
        }
    }

    if (deletes.size() > 0) {
        table.delete(deletes);
        deletes.clear();
    }

} catch (IOException e) {
    e.printStackTrace();
}
于 2014-03-07T11:46:38.473 回答