HBase批量删除为;“整批装载”;
我想删除HBase表中的3亿行。我可以使用HBase API发送一批删除对象。但我担心这需要很多时间 以前的代码就是这样,我想插入数百万行。我没有使用HBase API和发送一批Put,而是使用了一个Map Reduce作业,该作业将RowKey/Put作为值发出,并使用HBase批量删除为;“整批装载”;,hbase,Hbase,我想删除HBase表中的3亿行。我可以使用HBase API发送一批删除对象。但我担心这需要很多时间 以前的代码就是这样,我想插入数百万行。我没有使用HBase API和发送一批Put,而是使用了一个Map Reduce作业,该作业将RowKey/Put作为值发出,并使用HFileOutputFormat2.configureIncrementalLoad(作业、表、区域定位器)来设置我的减速机,以便它直接写入准备由LoadIncrementalHFiles快速加载的输出(完整批量加载). 这要
HFileOutputFormat2.configureIncrementalLoad(作业、表、区域定位器)
来设置我的减速机,以便它直接写入准备由LoadIncrementalHFiles
快速加载的输出(完整批量加载). 这要快得多(5分钟而不是3小时)
所以我想对批量删除做同样的操作
但是,我似乎无法将此技术用于Delete,因为HFileOutputFormat2
尝试为KeyValue
或Put
(PutSortReducer)配置Reducer,但Delete不存在
我的第一个问题是为什么没有一个“DeleteSortReducer”来为Delete启用完整的批量加载技术?是不是只是缺少了一些东西,而没有做?还是有更深层的原因可以证明这一点
第二个问题,有点相关:如果我复制/粘贴PutSortReducer的代码,将其修改为Delete,并将其作为我的工作的减速机传递,它会工作吗?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);
}
}
}
}
公共类DeleteSortReducer扩展
减速器{
@凌驾
保护空洞减少(
ImmutableBytesWritable行,
java.lang.Iterable删除,
(上下文)
抛出java.io.IOException、InterruptedException
{
//虽然每行调用reduce(),但要处理病理情况
long threshold=context.getConfiguration().getLong(
“putsortreducer.row.threshold”,1L*(1首先,简单介绍一下删除操作在HBase中的工作原理。在delete命令中,HBase将数据标记为已删除,并将有关数据的信息写入HFile。实际上,数据并没有从光盘中删除,存储器中有两条记录:数据和删除标记。只有在压缩后,数据才会从光盘存储器中删除
所有这些信息都表示为。对于表示数据的键值,其等于Put
。对于删除标记键值。类型设置为以下值之一Delete
,DeleteColumn
,DeleteFamily
,DeleteFamilyVersion
在您的情况下,可以通过为KeyValue创建具有特殊值的KeyValue来实现批量删除。键入
。例如,如果您只想删除一列,则应使用构造函数创建一个KeyValue
KeyValue(字节[]行,字节[]系列,字节[]限定符,长时间戳,KeyValue.Type)
//范例
KeyValue kv=新的KeyValue(行、族、限定符、时间、KeyValue.Type.DeleteColumn)
第一个问题的答案你不需要一个特殊的DeleteSortReducer
,你应该为KeyValue
配置一个减速机。第二个问题的答案是否定的。你从上面的程序中发现了什么?你有没有尝试/发现其他方法?如果有,它们应该是什么?我的映射器会发出这样的信息:byte[]rowkey=…;KeyValue kv=新的KeyValue(rowkey,System.currentTimeMillis(),KeyValue.Type.Delete);是的,如果要删除整行。如果只想删除一列或列族,则应使用DeleteColumn,DeleteFamily修饰符。如果删除行的所有单元格,则该修饰符有效(为每个单元格写入DeleteColumn类型的KeyValue)。但如果尝试删除整行,则会失败(仅为类型为delete的整行写入一个KeyValue)。