解决办法:
a、 首先关闭 “major_compact” 任务 (这个是个自动任务,合并文件,清除删除、过期、多余版本的数据的。Hbase 中的数据是有多个时间戳版本的,对于删除的数据,并没有直接删除,而是打上了标记。这个任务会清理,所以先关闭它,要不会丢失数据。)。
b、写程序恢复 (思路: 读取到带删除标签的数据,然后把数据重新写一遍进去)
下面是关键代码
Scan s = new Scan();
s.setMaxVersions(); // 拿版本号最高的
s.setRaw(true); // Raw Scan: 是否可以读取到删除标识以及被删除但尚未被清理的数据
实例代码:
思路就是读出来,重新插入一遍。
注意这个 setRaw(true) 不是只查删除状态的,而是包括删除状态的数据,因为正常状况下,是不能查出删除标记的数据的。
重新插入的话,rowkey同样会覆盖,所以没删除的数据重写一遍也没事。这点注意一下。
保险起见,可以先查询,检验一下数据对吗。别上来就读取插入一起做。
public boolean recoverData() {
Scan scan = new Scan();
scan.setMaxVersions();
scan.setRaw(true); // 查询时包括删除的数据
List<GroupFact> all = new ArrayList<GroupFact>();
try {
all = hbase2Template.findAll(GROUP_TABLE, scan, new GetMapping<GroupFact>() {
@Override
public GroupFact mapping(Result result) {
GroupFact fact = new GroupFact();
String rowkey = Bytes.toString(result.getRow());
log.info("[GroupFact]RowKey" + rowkey);
String tables = getStr(result, "tables");
fact.setRowKey(rowkey);
fact.setTables(tables);
// // 插入数据
// try {
// Put put = new Put(Bytes.toBytes(rowkey));
// put.addColumn(Bytes.toBytes(FAMILY), Bytes.toBytes("tables"), Bytes.toBytes(tables));
// hbase2Template.add(GROUP_TABLE, put);
// }catch (Exception e) {
// log.error("出现异常");
// }
return fact;
}
});
log.info("[GroupFact]查询出数据量大小" + all.size());
}catch (Exception e) {
log.error("[GroupFact]出现异常",e);
}
log.info("[GroupFact]查询出数据" + JSON.toJSONString(all));
return true;
}