web-dev-qa-db-fra.com

Hbase compte rapidement le nombre de lignes

En ce moment, j'implémente le 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 l'informatique est grande.Je veux calculer en temps réel que je ne veux pas utiliser Mapreduce

Comment compter rapidement le nombre de lignes.

44
cldo

Utilisez RowCounter dans HBase RowCounter est une tâche mapreduce permettant de compter toutes les lignes d'une table. Il s'agit d'un bon utilitaire à utiliser comme contrôle de cohérence pour garantir que HBase peut lire tous les blocs d'une table en cas de problème d'incohérence dans les métadonnées. Il exécutera la mapreduce all en un seul processus, mais plus rapidement si vous avez un cluster MapReduce à exploiter. 

$ hbase org.Apache.hadoop.hbase.mapreduce.RowCounter <tablename>

Usage: RowCounter [options] 
    <tablename> [          
        --starttime=[start] 
        --endtime=[end] 
        [--range=[startKey],[endKey]] 
        [<column1> <column2>...]
    ]
92
Basil Saju

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' [interval]

La valeur renvoyée est le nombre de lignes.

Cette opération peut durer longtemps (exécutez ‘$ HADOOP_HOME/bin/hadoop jar Hbase.jar rowcount’ pour exécuter un travail de comptage mapreduce). Le nombre actuel est indiqué Toutes les 1000 lignes par défaut. Nombre intervalle peut être spécifié facultativement. L'analyse La mise en cache est activée par défaut sur le nombre d'analyses. La taille de 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
28
Neethu

Utilisez la mappe réduction du travail/- HBase fournie avec HBase

7
Arnon Rotem-Gal-Oz

Si vous ne pouvez pas utiliser RowCounter pour quelque raison que ce soit, la combinaison de ces deux filtres devrait constituer un moyen optimal d'obtenir un nombre:

FirstKeyOnlyFilter() AND KeyOnlyFilter()

La variable FirstKeyOnlyFilter fait en sorte que le scanneur ne retourne que le premier qualificatif de colonne trouvé, contrairement au scanneur qui renvoie tous les qualificateurs de colonnes du tableau, ce qui minimise la bande passante du réseau. Qu'en est-il simplement de choisir un qualificateur de colonne à renvoyer? Cela fonctionnerait si vous pouviez garantir que le qualificateur de colonne existe pour chaque ligne, mais si ce n'est pas le cas, vous obtiendrez un nombre inexact.

La variable KeyOnlyFilter aura pour résultat que le scanner renverra uniquement la famille de colonnes et ne renverra aucune valeur pour le qualificateur de colonne. Cela réduit davantage la bande passante du réseau, ce qui dans le cas général ne représenterait pas une réduction importante, mais il peut y avoir un cas Edge où la première colonne sélectionnée par le filtre précédent s'avère être 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 un début et une fin et j'ai effectué 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 a pris 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’est-à-dire la valeur par défaut), cela prend 309 secondes 

Je n'ai pas pris la peine de faire des tests appropriés à ce sujet, mais il semble clair que les variables FirstKeyOnlyFilter et KeyOnlyFilter sont bonnes.

De plus, les cellules de ce tableau sont très petites - je pense donc que les filtres auraient été encore meilleurs sur un tableau différent.


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; 
 importer org.Apache.hadoop.hbase.util.Bytes; 

 importer org.Apache.hadoop.hbase.filter.RowFilter; 
 importer 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; 
 .RegexStringComparator; 

 public class HBaseCount {
 public static void main (String [] args) lève l'IOException {
 Configuration config = HBaseConfiguration.create (); 

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

 Scan Scan = new Scan (
 Bytes.toBytes ("foo"), Bytes.toBytes ("foo ~") 
); 

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

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

 scan.setFilter (tous les filtres); 

 ResultScanner scanner = table.getScanner (scan); 

 int count = 0; 

 long start = System.currentTimeMillis (); 

 essayez {
 pour (résultat rr = scanner.next (); rr! = nul; rr = scanner.next ()) {
 compte + = 1; 
 if (nombre% 100000 == 0) System.out.println (nombre); 
 } 
 } 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 :

 depuis pychbase import Connection 
 c = Connexion () 
 t = c.table ('ma_table') 
 # Sous le capot, cela s'applique aux filtres FirstKeyOnlyFilter et KeyOnlyFilter 
 # similaire à l'exemple happybase ci-dessous 
 print t.count (row_prefix = "foo") 

Voici un exemple de code Happybase:

 depuis connexion happybase import 
 c = connexion (...) 
 t = c.table ('ma_table') 
 compte = 0 
 pour _ dans t.scan (filter = 'FirstKeyOnlyFilter () AND KeyOnlyFilter ()'): 
 compte + = 1 

 nombre de copies 

Merci à @Tuckr et @KennyCason pour le conseil.

6
Matthew Moisen

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 "décompte".

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

5
Balaji

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

3

Pour compter le nombre d'enregistrements de la table Hbase sur un cluster YARN approprié, vous devez également définir le nom de la file d'attente des tâches de réduction de carte:

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

Si vous utilisez un scanner, essayez dans votre scanner de renvoyer le moins de qualificateurs possible. En fait, le ou les qualificateurs que vous renvoyez doivent être les plus petits (en taille d’octets) disponibles. Cela accélérera énormément votre analyse.

Malheureusement, cela ne se fera que 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.

Stockez la sortie Mapreduce dans une cellule de 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’existe pas de moyen rapide de compter les lignes d’une autre manière. Vous ne pouvez compter que si vite.

1
Tucker

Allez dans le répertoire personnel Hbase et exécutez cette commande,

./bin/hbase org.Apache.hadoop.hbase.mapreduce.RowCounter 'espace de noms: nom_table'

Cela lancera une tâche mapreduce et la sortie indiquera le nombre d'enregistrements existant dans la table hbase.

1
jack AKA karthik

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(String tableName, String... 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 (String 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;
    }
1
Ranga Reddy

Deux façons Travaillé pour moi pour obtenir le nombre de lignes de la table hbase avec Speed ​​

Scénario 1

Si la taille de la table hbase est petite, connectez-vous à hbase Shell avec un utilisateur valide et exécutez-la.

>count '<tablename>'

Exemple 

>count 'employee'

6 row(s) in 0.1110 seconds

Scénario n ° 2

Si la taille de la table hbase est grande, exécutez le travail de réduction de mappe RowCounter intégré: Connectez-vous à la machine hadoop avec un utilisateur valide et exécutez:

/$HBASE_HOME/bin/hbase org.Apache.hadoop.hbase.mapreduce.RowCounter '<tablename>'

Exemple:

 /$HBASE_HOME/bin/hbase org.Apache.hadoop.hbase.mapreduce.RowCounter 'employee'

     ....
     ....
     ....
     Virtual memory (bytes) snapshot=22594633728
                Total committed heap usage (bytes)=5093457920
        org.Apache.hadoop.hbase.mapreduce.RowCounter$RowCounterMapper$Counters
                ROWS=6
        File Input Format Counters
                Bytes Read=0
        File Output Format Counters
                Bytes Written=0