hbase扫描正在返回已删除的行

zf9nrax1  于 2021-06-09  发布在  Hbase
关注(0)|答案(1)|浏览(443)

我正在使用singlecolumnvaluefilter返回要删除的行列表:

  1. SingleColumnValueFilter fileTimestampFilter = new SingleColumnValueFilter(
  2. Bytes.toBytes('a'),
  3. Bytes.toBytes('date'),
  4. CompareFilter.CompareOp.GREATER,
  5. Bytes.toBytes("20140101000000")
  6. );

然后创建一个delete对象并删除每一列。

  1. Delete delete = new Delete(Bytes.toBytes(rowKey));
  2. delete.deleteColumn(Bytes.toBytes('a'), Bytes.toBytes('date'));
  3. htable.delete(delete);

检索代码为

  1. private List<String> getRecordsToDelete(long maxResultSize)
  2. {
  3. ResultScanner rs = null;
  4. HTableInterface table = null;
  5. List<String> keyList = new ArrayList<String>();
  6. try
  7. {
  8. log.debug("Retrieving records");
  9. HbaseConnection hbaseConnectionConfig = myConfig.getHbaseConnection();
  10. Configuration configuration = getHbaseConfiguration(hbaseConnectionConfig);
  11. table = new HTable(configuration, 'mytable');
  12. FilterList list = new FilterList(FilterList.Operator.MUST_PASS_ALL);
  13. Filter filter = HbaseDao.getFilter();
  14. list.addFilter(filter);
  15. list.addFilter(new PageFilter(maxResultSize));
  16. Scan scan = new Scan();
  17. scan.setFilter(list);
  18. //scan.setMaxResultSize(maxResultSize);
  19. //scan.setCaching(1);
  20. //scan.setCacheBlocks(false);
  21. //log.debug("Scan raw? = " + scan.isRaw());
  22. //scan.setRaw(false);
  23. rs = table.getScanner(scan);
  24. Iterator<Result> iterator = rs.iterator();
  25. while (iterator.hasNext())
  26. {
  27. Result result = iterator.next();
  28. String key = Bytes.toString(result.getRow());
  29. log.debug("****************f key = " + key); //the same keys are always added here
  30. keyList.add(key);
  31. }
  32. log.debug("Done processing retrieval of records to delete Size = " + keyList.size());
  33. }
  34. catch (Exception ex)
  35. {
  36. log.error("Unable to process retrieval of records.", ex);
  37. }
  38. finally
  39. {
  40. try
  41. {
  42. if (table != null)
  43. {
  44. table.close();
  45. }
  46. if (rs != null)
  47. {
  48. rs.close();
  49. }
  50. }
  51. catch (IOException ioEx)
  52. {
  53. //do nothing
  54. log.error(ioEx);
  55. }
  56. }
  57. return keyList;
  58. }

此任务已安排,当它再次运行时,它将检索相同的行。我知道hbase会将行标记为删除,然后它们只会在主要压缩之后被物理删除。如果在任务运行之间通过hbase shell查询行,则该列肯定已被删除。为什么我的扫描在这个任务的后续运行中返回相同的行?
提前谢谢!

5cnsuln7

5cnsuln71#

它与主要压缩无关(默认情况下,它们每24小时运行一次)。删除行时,hbase将忽略已删除的数据,直到最终删除(在主压缩上)。请注意,如果没有激活autoflush,则必须首先通过调用 htable.flushCommits() (默认情况下,autoflush=on)。
你的问题可能是因为你只删除了 a:date 您的行中有更多的列正在被读取,并且它们正在传递筛选器,因为如果没有值存在,这是默认行为。
如果要删除整行,只需删除 delete.deleteColumn(Bytes.toBytes('a'), Bytes.toBytes('date')); 删除行,而不仅仅是列。
如果你只是想删除 a:date 列,同时保持行的其余部分不变,设置filterifmissing标志以避免使用 a:date == null 正在进行(因为它已被删除): filter.setFilterIfMissing(true); 或者,为了获得最佳性能,只将该列添加到扫描中,这将阻止读取其他列: scan.addColumn(Bytes.toBytes('a'), Bytes.toBytes('date')); 另一方面,请注意 list.addFilter(new PageFilter(maxResultSize)); 如果要从表的每个区域检索maxresultsize结果,则必须在键列表达到maxresultsize时通过打破它在迭代器中手动实现限制。
还有一个提示,当出于调试目的进行日志记录时,一定要记录完整的结果,以便准确地看到其中的内容。

相关问题