Hbase compte rapidement le nombre de lignes

En ce moment, ResultScanner nombre de lignes sur ResultScanner comme ceci

 for (Result rs = scanner.next(); rs != null; rs = scanner.next()) { number++; } 

Si les données atteignant des millions de fois, le calcul est important. Je veux calculer en temps réel le fait que je ne veuille pas utiliser Mapreduce

Comment compter rapidement le nombre de lignes.

Utiliser RowCounter dans HBase RowCounter est un travail mapreduce permettant de compter toutes les lignes d’une table. Ceci est un bon utilitaire à utiliser comme vérification de l’intégrité pour s’assurer que HBase peut lire tous les blocs d’une table s’il existe des problèmes d’incohérence de métadonnées. Il exécutera mapreduce tout en un seul processus mais il s’exécutera plus rapidement si vous avez un cluster MapReduce en place pour l’exploiter.

 $ hbase org.apache.hadoop.hbase.mapreduce.RowCounter  Usage: RowCounter [options]  [ --starttime=[start] --endtime=[end] [--range=[startKey],[endKey]] [ ...] ] 

Vous pouvez utiliser la méthode count dans hbase pour compter le nombre de lignes. Mais oui, compter les lignes d’une grande table peut être slow.count ‘nom_table’ [intervalle]

La valeur de retour est le nombre de lignes.

Cette opération peut prendre du temps (Exécutez ‘$ HADOOP_HOME / bin / hadoop jar hbase.jar rowcount’ pour exécuter un job de décompte de compte). Le compte actuel est affiché toutes les 1000 lignes par défaut. L’intervalle de comptage peut éventuellement être spécifié. La mise en cache de l’parsing est activée sur les parsings par défaut. La taille du cache par défaut est de 10 lignes. Si vos lignes sont de petite taille, vous souhaiterez peut-être augmenter ce paramètre.

Exemples:

 hbase> count 't1' hbase> count 't1', INTERVAL => 100000 hbase> count 't1', CACHE => 1000 hbase> count 't1', INTERVAL => 10, CACHE => 1000 

Les mêmes commandes peuvent également être exécutées sur une référence de table. Supposons que vous ayez une référence à la table ‘t1’, les commandes correspondantes seraient:

 hbase> t.count hbase> t.count INTERVAL => 100000 hbase> t.count CACHE => 1000 hbase> t.count INTERVAL => 10, CACHE => 1000 

Utilisez la carte HBase rowcount / réduisez le travail inclus avec HBase

Si vous ne pouvez pas utiliser RowCounter pour quelque raison que ce soit, une combinaison de ces deux filtres devrait être un moyen optimal pour obtenir un décompte:

 FirstKeyOnlyFilter() AND KeyOnlyFilter() 

FirstKeyOnlyFilter l’parsingur de renvoyer uniquement le premier qualificateur de colonne trouvé, contrairement à l’parsingur qui renvoie tous les qualificateurs de colonne de la table, ce qui minimisera la bande passante réseau. Qu’en est-il simplement de choisir un qualificatif de colonne à renvoyer? Cela fonctionnerait si vous pouviez garantir que le qualificatif de colonne existe pour chaque ligne, mais si cela n’est pas vrai, vous obtiendrez un compte inexact.

Le KeyOnlyFilter le scanner de renvoyer uniquement la famille de colonnes et ne renverra aucune valeur pour le qualificatif de colonne. Cela réduit encore la bande passante du réseau, ce qui, dans le cas général, ne représenterait pas une grande partie de la réduction, mais il peut y avoir un cas extrême où la première colonne prise par le filtre précédent est une valeur extrêmement grande.

J’ai essayé de jouer avec scan.setCaching mais les résultats étaient partout. Peut-être que cela pourrait aider.

J’ai eu 16 millions de lignes entre chaque début et j’ai arrêté les tests pseudo-empiriques suivants:

 Avec FirstKeyOnlyFilter et KeyOnlyFilter activés:

     Avec la mise en cache non définie (c'est-à-dire la valeur par défaut), il a fallu 188 secondes.
     Avec la mise en cache définie sur 1, il a fallu 188 secondes
     Avec la mise en cache définie sur 10, cela prend 200 secondes
     Avec la mise en cache définie sur 100, il a fallu 187 secondes
     Avec la mise en cache définie sur 1000, il a fallu 183 secondes.
     Avec la mise en cache définie sur 10000, il a fallu 199 secondes.
     Avec la mise en cache définie sur 100000, il a fallu 199 secondes.

 Avec FirstKeyOnlyFilter et KeyOnlyFilter désactivés:

     Avec la mise en cache non définie (c.-à-d. La valeur par défaut), il a fallu 309 secondes

Je n’ai pas pris la peine de faire des tests appropriés, mais il semble clair que FirstKeyOnlyFilter et KeyOnlyFilter sont bons.

De plus, les cellules de cette table sont très petites – je pense donc que les filtres auraient été encore meilleurs sur une autre table.


Voici un exemple de code Java:

 import java.io.IOException;

 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.HBaseConfiguration;
 import org.apache.hadoop.hbase.client.HTable;
 import org.apache.hadoop.hbase.client.Result;
 import org.apache.hadoop.hbase.client.ResultScanner;
 import org.apache.hadoop.hbase.client.Scan;
 import org.apache.hadoop.hbase.util.Bytes;

 import org.apache.hadoop.hbase.filter.RowFilter;
 import org.apache.hadoop.hbase.filter.KeyOnlyFilter; 
 import org.apache.hadoop.hbase.filter.FirstKeyOnlyFilter; 
 import org.apache.hadoop.hbase.filter.FilterList;

 import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
 import org.apache.hadoop.hbase.filter.RegexSsortingngComparator; 

 classe publique HBaseCount {
     public principal statique vide (Ssortingng [] args) génère une exception IOException {
         Configuration config = HBaseConfiguration.create ();

         HTable table = new HTable (config, "my_table");

         Scan scan = nouvelle parsing (
             Bytes.toBytes ("foo"), Bytes.toBytes ("foo ~")
         );

         if (args.length == 1) {
             scan.setCaching (Integer.valueOf (args [0]));
         }
         System.out.println ("la mise en cache de l'parsing est" + scan.getCaching ());

         FilterList allFilters = new FilterList ();
         allFilters.addFilter (new FirstKeyOnlyFilter ());
         allFilters.addFilter (new KeyOnlyFilter ());

         scan.setFilter (allFilters);

         ResultScanner scanner = table.getScanner (scan);

         int count = 0;

         long start = System.currentTimeMillis ();

         essayez {
             pour (Résultat rr = scanner.next (); rr! = null; rr = scanner.next ()) {
                 compte + = 1;
                 if (count% 100000 == 0) System.out.println (count);
             }
         } enfin {
             scanner.close ();
         }

         long end = System.currentTimeMillis ();

         long elapsedTime = end-start;

         System.out.println ("Le temps écoulé était" + (elapsedTime / 1000F));

     }
 }


Voici un exemple de code pychbase :

     de pychbase importation Connexion
     c = connexion ()
     t = c.table ('my_table')
     # Sous le capot ceci applique le FirstKeyOnlyFilter et le KeyOnlyFilter
     # similaire à l'exemple happybase ci-dessous
     print t.count (row_prefix = "foo")

Voici un exemple de code Happybase:

     de la connexion d'importation de happybase
     c = connexion (...)
     t = c.table ('my_table')
     count = 0
     pour _ dans t.scan (filter = 'FirstKeyOnlyFilter () AND KeyOnlyFilter ()'):
         compte + = 1

     nombre d'impressions

Merci à @Tuckr et @KennyCason pour le conseil.

Moyen simple, efficace et efficace de compter les lignes dans HBASE:

  1. Chaque fois que vous insérez une ligne, déclenchez cette API qui incrémentera cette cellule particulière.

     Htable.incrementColumnValue(Bytes.toBytes("count"), Bytes.toBytes("details"), Bytes.toBytes("count"), 1); 
  2. Pour vérifier le nombre de lignes présentes dans cette table. Il suffit d’utiliser l’API “Get” ou “scan” pour cette ligne particulière “count”.

En utilisant cette méthode, vous pouvez obtenir le nombre de lignes en moins d’une milliseconde.

Vous pouvez utiliser le coprocesseur comme disponible depuis HBase 0.92. Voir Coprocessor et AggregateProtocol et exemple

Pour compter le nombre d’enregistrements de tables Hbase sur un cluster YARN approprié, vous devez également définir le nom de la queue des travaux:

 hbase org.apache.hadoop.hbase.mapreduce.RowCounter -Dmapreduce.job.queuename= < Your Q Name which you have SUBMIT access> < TABLE_NAME> 

Si vous utilisez un scanner, dans votre scanner, essayez de renvoyer le moins de qualificateurs possible. En fait, le ou les qualificatifs que vous retournez doivent être les plus petits (en taille d’octet), selon votre disponibilité. Cela accélérera considérablement votre scan.

Malheureusement, cela ne va pas aller jusqu’à présent (des millions de milliards?). Pour aller plus loin, vous pouvez le faire en temps réel, mais vous devrez d’abord exécuter un travail mapreduce pour compter toutes les lignes.

Stocker la sortie Mapreduce dans une cellule dans HBase. Chaque fois que vous ajoutez une ligne, incrémentez le compteur de 1. Chaque fois que vous supprimez une ligne, décrémentez le compteur.

Lorsque vous devez accéder au nombre de lignes en temps réel, vous lisez ce champ dans HBase.

Il n’y a pas de moyen rapide de compter les lignes autrement d’une manière qui évolue. Vous ne pouvez compter que si vite.

Vous pouvez trouver un exemple d’exemple ici:

 /** * Used to get the number of rows of the table * @param tableName * @param familyNames * @return the number of rows * @throws IOException */ public long countRows(Ssortingng tableName, Ssortingng... familyNames) throws IOException { long rowCount = 0; Configuration configuration = connection.getConfiguration(); // Increase RPC timeout, in case of a slow computation configuration.setLong("hbase.rpc.timeout", 600000); // Default is 1, set to a higher value for faster scanner.next(..) configuration.setLong("hbase.client.scanner.caching", 1000); AggregationClient aggregationClient = new AggregationClient(configuration); try { Scan scan = new Scan(); if (familyNames != null && familyNames.length > 0) { for (Ssortingng familyName : familyNames) { scan.addFamily(Bytes.toBytes(familyName)); } } rowCount = aggregationClient.rowCount(TableName.valueOf(tableName), new LongColumnInterpreter(), scan); } catch (Throwable e) { throw new IOException(e); } return rowCount; } 

Accédez au répertoire principal de Hbase et exécutez cette commande,

./bin/hbase org.apache.hadoop.hbase.mapreduce.RowCounter ‘namespace: tablename’

Cela lancera un travail mapreduce et la sortie affichera le nombre d’enregistrements existant dans la table hbase.

Vous pouvez essayer les méthodes api hbase!

org.apache.hadoop.hbase.client.coprocessor.AggregationClient