首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >HBase大容量删除为“完整大容量加载”

HBase大容量删除为“完整大容量加载”
EN

Stack Overflow用户
提问于 2016-09-02 12:56:43
回答 1查看 1.6K关注 0票数 3

我想删除HBase表中的3亿行。我可以使用HBase API并发送批量删除对象。但恐怕要花很多时间。

以前的一段代码就是这种情况,我想要插入数百万行。我没有使用HBase API和发送批处理的Put,而是使用了一个映射减少作业,它将RowKey /Put作为值,并使用HFileOutputFormat2.configureIncrementalLoad(job, table, regionLocator)来设置Reducer,这样它就可以直接写入由LoadIncrementalHFiles (完全批量加载)快速加载的输出。这要快得多(5分钟而不是3小时)。

所以我也想做同样的大容量删除。

但是,当HFileOutputFormat2试图为KeyValuePut (PutSortReducer)配置Reducer时,我似乎无法在Delete中使用此技术,但对于Delete则不存在。

我的第一个问题是,为什么没有一个"DeleteSortReducer“来为删除启用完整的大容量装载技术?只是缺少了什么,还没有做完吗?还是有更深层次的理由来证明这一点?

第二个相关的问题是:如果我复制/粘贴PutSortReducer的代码,将其修改为删除,并将其作为我工作的减速器传递,它会起作用吗?HBase完全批量装载将产生充满墓碑的HFiles吗?

例子:

代码语言:javascript
复制
public class DeleteSortReducer extends
        Reducer<ImmutableBytesWritable, Delete, ImmutableBytesWritable, KeyValue> {

    @Override
    protected void reduce(
            ImmutableBytesWritable row,
            java.lang.Iterable<Delete> deletes,
            Reducer<ImmutableBytesWritable, Delete,
                    ImmutableBytesWritable, KeyValue>.Context context)
            throws java.io.IOException, InterruptedException
    {
        // although reduce() is called per-row, handle pathological case
        long threshold = context.getConfiguration().getLong(
                "putsortreducer.row.threshold", 1L * (1<<30));
        Iterator<Delete> iter = deletes.iterator();
        while (iter.hasNext()) {
            TreeSet<KeyValue> map = new TreeSet<KeyValue>(KeyValue.COMPARATOR);
            long curSize = 0;
            // stop at the end or the RAM threshold
            while (iter.hasNext() && curSize < threshold) {
                Delete d = iter.next();
                for (List<Cell> cells: d.getFamilyCellMap().values()) {
                    for (Cell cell: cells) {
                        KeyValue kv = KeyValueUtil.ensureKeyValue(cell);
                        map.add(kv);
                        curSize += kv.heapSize();
                    }
                }
            }
            context.setStatus("Read " + map.size() + " entries of " + map.getClass()
                    + "(" + StringUtils.humanReadableInt(curSize) + ")");
            int index = 0;
            for (KeyValue kv : map) {
                context.write(row, kv);
                if (++index % 100 == 0)
                    context.setStatus("Wrote " + index);
            }

            // if we have more entries to process
            if (iter.hasNext()) {
                // force flush because we cannot guarantee intra-row sorted order
                context.write(null, null);
            }
        }
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-09-04 18:45:58

首先,简单介绍一下HBase中删除操作是如何工作的。在delete命令中,HBase将数据标记为已删除,并将有关数据的信息写入HFile。实际上,数据没有从光盘中删除,存储中有两条记录:数据和删除标记。只有在压缩之后,数据才会从磁盘存储中删除。

所有这些信息都表示为KeyValue。对于KeyValue,表示数据的KeyValue.Type等于Put。对于删除标记KeyValue.Type,设置以下值之一DeleteDeleteColumnDeleteFamilyDeleteFamilyVersion

在这种情况下,可以通过为KeyValue创建具有特殊值的KeyValue.Type来实现大容量删除。例如,如果要删除唯一的一列,则应使用构造函数创建KeyValue

代码语言:javascript
复制
KeyValue(byte[] row, byte[] family, byte[] qualifier, long timestamp, KeyValue.Type type)

// example 

KeyValue kv = new KeyValue(row, family, qualifier, time, KeyValue.Type.DeleteColumn)

对于第一个问题,您不需要一个特殊的DeleteSortReducer,您应该为KeyValue配置一个减速器。对于第二个问题,答案是否定的。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39293007

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档