我想删除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);
}
}
}
}
1条答案
按热度按时间qgelzfjb1#
首先,简单介绍一下删除操作在hbase中的工作原理。在delete命令中,hbase将数据标记为已删除,并将有关数据的信息写入hfile。实际上,数据并没有从光盘中删除,存储器中有两条记录:数据和删除标记。只有在压缩之后,数据才会从光盘存储中删除。
所有这些信息都表示为
KeyValue
. 代表has的数据的for keyvalueKeyValue.Type
等于Put
. 对于删除,将mark keyvalue.type设置为以下值之一Delete
,DeleteColumn
,DeleteFamily
,DeleteFamilyVersion
.在您的例子中,您可以通过为创建具有特殊值的keyvalue来实现批量删除
KeyValue.Type
. 例如,如果只想删除一列,则应创建KeyValue
,使用构造函数第一个问题的答案你不需要特别的回答
DeleteSortReducer
,应为配置减速器KeyValue
. 第二个问题的答案是否定的。