hbase批量删除为“完全批量加载”

jgzswidk  于 2021-06-10  发布在  Hbase
关注(0)|答案(1)|浏览(435)

我想删除hbase表中的3亿行。我可以使用hbase api发送一批delete对象。但恐怕要花很多时间。
以前的代码就是这样,我想插入数百万行。我没有使用hbase api和send batch of put,而是使用map reduce作业,它将rowkey/put作为值发出,并使用 HFileOutputFormat2.configureIncrementalLoad(job, table, regionLocator) 设置我的减速机,以便它直接写入准备快速加载的输出 LoadIncrementalHFiles (全部散装)。速度要快得多(5分钟而不是3小时)。
所以我想做同样的批量删除。
但是,似乎我不能将delete作为 HFileOutputFormat2 尝试为配置减速机 KeyValue 或者 Put (putsortreducer)但是没有要删除的内容。
我的第一个问题是为什么没有一个“deletesortreducer”来为delete启用完整的批量加载技术?只是少了点什么,还没做?还是有更深层的原因来证明这一点?
第二个问题,有点相关:如果我复制/粘贴putsortreducer的代码,将其修改为delete,并将其作为我的工作的reducer传递,它会工作吗?hbase完全批量加载是否会产生满是墓碑的hfiles?
例子:

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);
            }
        }
    }
}
qgelzfjb

qgelzfjb1#

首先,简单介绍一下删除操作在hbase中的工作原理。在delete命令中,hbase将数据标记为已删除,并将有关数据的信息写入hfile。实际上,数据并没有从光盘中删除,存储器中有两条记录:数据和删除标记。只有在压缩之后,数据才会从光盘存储中删除。
所有这些信息都表示为 KeyValue . 代表has的数据的for keyvalue KeyValue.Type 等于 Put . 对于删除,将mark keyvalue.type设置为以下值之一 Delete , DeleteColumn , DeleteFamily , DeleteFamilyVersion .
在您的例子中,您可以通过为创建具有特殊值的keyvalue来实现批量删除 KeyValue.Type . 例如,如果只想删除一列,则应创建 KeyValue ,使用构造函数

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 . 第二个问题的答案是否定的。

相关问题