代码之家  ›  专栏  ›  技术社区  ›  Rolando

如何批量删除hbase中的多行?

  •  24
  • Rolando  · 技术社区  · 9 年前

    我在hbase表“mytable”中有以下带有这些键的行

    user_1
    user_2
    user_3
    ...
    user_9999999
    

    我想使用Hbase外壳删除以下行:

    user_500到user_900

    我知道没有办法删除,但有没有办法使用“BulkDeleteProcessor”来删除?

    我在这里看到:

    https://github.com/apache/hbase/blob/master/hbase-examples/src/test/java/org/apache/hadoop/hbase/coprocessor/example/TestBulkDeleteProtocol.java

    我只想在导入中粘贴,然后将其粘贴到外壳中,但不知道如何执行此操作。有人知道我如何从jruby hbase shell使用这个端点吗?

       Table ht = TEST_UTIL.getConnection().getTable("my_table");
        long noOfDeletedRows = 0L;
        Batch.Call<BulkDeleteService, BulkDeleteResponse> callable =
          new Batch.Call<BulkDeleteService, BulkDeleteResponse>() {
          ServerRpcController controller = new ServerRpcController();
          BlockingRpcCallback<BulkDeleteResponse> rpcCallback =
            new BlockingRpcCallback<BulkDeleteResponse>();
    
          public BulkDeleteResponse call(BulkDeleteService service) throws IOException {
            Builder builder = BulkDeleteRequest.newBuilder();
            builder.setScan(ProtobufUtil.toScan(scan));
            builder.setDeleteType(deleteType);
            builder.setRowBatchSize(rowBatchSize);
            if (timeStamp != null) {
              builder.setTimestamp(timeStamp);
            }
            service.delete(controller, builder.build(), rpcCallback);
            return rpcCallback.get();
          }
        };
        Map<byte[], BulkDeleteResponse> result = ht.coprocessorService(BulkDeleteService.class, scan
            .getStartRow(), scan.getStopRow(), callable);
        for (BulkDeleteResponse response : result.values()) {
          noOfDeletedRows += response.getRowsDeleted();
        }
        ht.close();
    

    如果无法通过JRuby、Java或其他快速删除多行的方法来执行此操作,则可以。

    2 回复  |  直到 9 年前
        1
  •  17
  •   britter Vikram Singh Chandel    9 年前

    你真的想在shell中做吗?因为还有其他更好的方法。一种方法是使用本机java API

    • 构造删除的数组列表
    • 将此数组列表传递给表。删除方法

    方法1:如果你已经知道关键点的范围。

    public void massDelete(byte[] tableName) throws IOException {
        HTable table=(HTable)hbasePool.getTable(tableName);
    
        String tablePrefix = "user_";
        int startRange = 500;
        int endRange = 999;
    
        List<Delete> listOfBatchDelete = new ArrayList<Delete>();
    
        for(int i=startRange;i<=endRange;i++){
            String key = tablePrefix+i; 
            Delete d=new Delete(Bytes.toBytes(key));
            listOfBatchDelete.add(d);  
        }
    
        try {
            table.delete(listOfBatchDelete);
        } finally {
            if (hbasePool != null && table != null) {
                hbasePool.putTable(table);
            }
        }
    }
    

    方法2:如果要根据扫描结果进行批量删除。

    public bulkDelete(final HTable table) throws IOException {
        Scan s=new Scan();
        List<Delete> listOfBatchDelete = new ArrayList<Delete>();
        //add your filters to the scanner
        s.addFilter();
        ResultScanner scanner=table.getScanner(s);
        for (Result rr : scanner) {
            Delete d=new Delete(rr.getRow());
            listOfBatchDelete.add(d);
        }
        try {
            table.delete(listOfBatchDelete);
        } catch (Exception e) {
            LOGGER.log(e);
    
        }
    }
    

    现在归结到使用CoProcessor。只有一条建议,“不要使用CoProcessor”,除非你是HBase专家。 CoProcessors有许多内置问题,如果您需要,我可以向您提供详细描述。 其次,当您从HBase中删除任何内容时,它永远不会直接从HBase删除,有墓碑标记会附加到该记录上,稍后在主要压缩过程中,它会被删除,因此无需使用资源高度耗尽的协处理器。

    修改代码以支持批处理操作。

    int batchSize = 50;
    int batchCounter=0;
    for(int i=startRange;i<=endRange;i++){
    
    String key = tablePrefix+i;
    Delete d=new Delete(Bytes.toBytes(key));
    listOfBatchDelete.add(d);  
    batchCounter++;
    
    if(batchCounter==batchSize){
        try {
            table.delete(listOfBatchDelete);
            listOfBatchDelete.clear();
            batchCounter=0;
        }
    }}
    

    创建HBase conf并获取表实例。

    Configuration hConf = HBaseConfiguration.create(conf);
    hConf.set("hbase.zookeeper.quorum", "Zookeeper IP");
    hConf.set("hbase.zookeeper.property.clientPort", ZookeeperPort);
    
    HTable hTable = new HTable(hConf, tableName);
    
        2
  •  4
  •   Prasad Khode    9 年前

    如果您已经知道要从HBase表中删除的记录的行键,那么可以使用以下方法

    1.首先使用这些行键创建List对象

    for (int rowKey = 1; rowKey <= 10; rowKey++) {
        deleteList.add(new Delete(Bytes.toBytes(rowKey + "")));
    }
    

    2.然后使用HBase Connection获取Table对象

    Table table = connection.getTable(TableName.valueOf(tableName));
    

    3.一旦有了表对象,通过传递列表调用delete()

    table.delete(deleteList);
    

    完整的代码如下所示

    Configuration config = HBaseConfiguration.create();
    config.addResource(new Path("/etc/hbase/conf/hbase-site.xml"));
    config.addResource(new Path("/etc/hadoop/conf/core-site.xml"));
    
    String tableName = "users";
    
    Connection connection = ConnectionFactory.createConnection(config);
    Table table = connection.getTable(TableName.valueOf(tableName));
    
    List<Delete> deleteList = new ArrayList<Delete>();
    
    for (int rowKey = 500; rowKey <= 900; rowKey++) {
        deleteList.add(new Delete(Bytes.toBytes("user_" + rowKey)));
    }
    
    table.delete(deleteList);