Comment supprimer en masse plusieurs lignes dans hbase?

J'ai les lignes suivantes avec ces clés dans la table hbase "mytable"

user_1
user_2
user_3
...
user_9999999

Je veux utiliser le shell Hbase pour supprimer des lignes de:

User_500 à user_900

Je sais qu'il n'y a aucun moyen de supprimer, mais y a-t-il un moyen d'utiliser le "BulkDeleteProcessor" pour le faire?

Je vois ici:

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

Je veux simplement coller dans les importations, puis coller ceci dans le shell, mais je n'ai aucune idée de comment s'y prendre. Est-ce que quelqu'un sait comment je peux utiliser ce point de terminaison à partir du shell JRuby hbase?

   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();

S'il n'existe aucun moyen de le faire via JRuby, Java ou un autre moyen de supprimer rapidement plusieurs lignes, c'est bien.

22
demandé sur Chris Martin 2015-09-16 03:52:24

2 réponses

Voulez-vous vraiment le faire dans shell parce qu'il y a plusieurs autres meilleures façons. Une façon est d'utiliser l'API java native

  • construire une liste de tableau de suppressions
  • passez cette liste de tableau à la Table.supprimer la méthode

Méthode 1: si vous connaissez déjà la plage de clés.

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);
        }
    }
}

Méthode 2: Si vous voulez faire une suppression par lots sur la base d'un résultat d'analyse.

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);

    }
}

Maintenant, nous passons à l'utilisation d'un coprocesseur. un seul conseil, "N'utilisez pas de coprocesseur" à moins vous êtes un expert en HBase. Les coprocesseurs ont de nombreux problèmes intégrés si vous avez besoin, je peux vous fournir une description détaillée. Deuxièmement, lorsque vous supprimez quelque chose de HBase, il n'est jamais directement supprimé de Hbase, il y a un marqueur de pierre tombale attaché à cet enregistrement et plus tard lors d'un compactage majeur, il est supprimé, donc pas besoin d'utiliser un coprocesseur qui est très exhaustif.

Code modifié pour prendre en charge le fonctionnement par lots.

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;
    }
}}

Créer HBase conf et obtenir la table instance.

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);
15
répondu Vikram Singh Chandel 2015-10-03 12:25:07

Si vous connaissez déjà les clés de ligne des enregistrements que vous souhaitez supprimer de la table HBase, vous pouvez utiliser l'approche suivante

1.Créez d'abord une liste d'objets avec ces touches de ligne

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

2.Ensuite, obtenez l'objet Table en utilisant la connexion HBase

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

3.Une fois que vous avez l'objet table appelez delete () en passant la liste

table.delete(deleteList);

Le code complet ressemblera ci-dessous

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);
4
répondu Prasad Khode 2015-09-29 05:55:30