【问题标题】:How to Delete recent version of all columns based on rowkey in Hbase如何根据 Hbase 中的行键删除所有列的最新版本
【发布时间】:2017-01-23 23:28:28
【问题描述】:

我需要从 Hbase 中删除数据。我想根据 Hbase 中的行键删除每个单元格的最新版本。 我想到了一种方法,用给定的 rowkey 获取每列的列名和最新时间​​戳.....然后用每列及其时间戳迭代地执行删除操作。

但我无法获取列名,所以我做不到。

如果您有任何想法或工作代码,请分享?

【问题讨论】:

    标签: hbase


    【解决方案1】:

    Here是我做过一次的自定义过滤器GetLatestColumnsFilter,可以用来获取时间戳最新的列,我觉得可以用来解决你的问题。

    public class GetLatestColumnsFilter extends TimestampsFilter {
        private long max;
    
        public GetLatestColumnsFilter() {
            super(new ArrayList<>());
            max = -1;
        }
    
        @Override
        public ReturnCode filterKeyValue(Cell v) {
            if (-1 == max) {
                max = Long.valueOf(v.getTimestamp());
            } else if (max != Long.valueOf(v.getTimestamp())) {
                return ReturnCode.SKIP;
            }
            return ReturnCode.INCLUDE;
        }
    
        public static GetLatestColumnsFilter parseFrom(byte[] pbBytes) throws DeserializationException {
            return new GetLatestColumnsFilter();
        }
    
    }
    

    【讨论】:

      【解决方案2】:

      HBase official guide for version 0.94可以看出:

      通过创建墓碑标记删除作品。例如,让我们假设 我们要删除一行。为此,您可以指定一个版本,否则 默认情况下使用 currentTimeMillis。这意味着“删除 版本小于或等于此版本的所有单元格”。 HBase 从不就地修改数据,因此例如删除不会 立即删除(或标记为已删除)存储中的条目 删除条件对应的文件。而是一个所谓的 墓碑被写入,这将掩盖删除的值[17]。如果 删除行时指定的版本大于版本 行中的任何值,那么您可以认为完整的行是 已删除。

      所以我看不出遵循标准删除程序的问题。

      但是,如果您只想删除最新版本的单元格,您可以使用 Scan 类的 setTimestamp 方法。所以,你可以做的是:

      List<Delete> deletes = new ArrayList<>();
      Scan scan = new Scan();
      scan.setTimestamp(latestVersionTimeStamp); //latestVersionTimeStamp is a long variable
      //set your filters here
      ResultScanner rscanner = table.getScanner(scan);
      for(Result rs : rscanner){
          deletes.add(new Delete(rs.getRow()));
      }
      try{
          table.delete(deletes);
      }
      catch(Exception e){
          e.printStackTrace();
      }
      

      但是,如果您的时间戳在各个单元格中不同,则这不适用于所有单元格。这可能会。

      List<Delete> deletes = new ArrayList<>();
      ArrayList<long> timestamps =  new ArrayList<>();//your list of timestamps
      Delete d;
      Scan scan = new Scan();
      //set your filters here
      ResultScanner rscanner = table.getScanner(scan);
      for(Pair<Result, long> item : zip(rscanner, timestamps)){
          d=new Delete(item.getLeft().getRow())
          d.setTimestamp(item.getRight());
          deletes.add(d);
      }
      try{
          table.delete(deletes);
      }
      catch(Exception e){
          e.printStackTrace();
      }
      

      不过,我不保证这会奏效。官方指南不够模糊,我可能误解了任何内容。如果我确实误解了,请提醒我,我将删除此答案。

      我的信息来源 setTimestamp method for Scan classsetTimestamp method for Delete class

      【讨论】:

      • 感谢 Nikhil 的回答。我不是在这里控制时间戳,所以我认为可以安全地假设每个单元格都有不同的时间戳。我将尝试使用您共享的代码 sn-p 并将更新。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-28
      • 1970-01-01
      相关资源
      最近更新 更多