Hbase compte rapidement le nombre de rangées
en ce moment je 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 atteignent des millions, l'informatique temporelle est grande.Je veux calculer en temps réel que je ne veux pas utiliser Mapreduce
comment compter rapidement le nombre de lignes.
11 réponses
utilisez RowCounter dans HBase RowCounter est un travail mapreduce pour compter toutes les lignes d'une table. Il s'agit d'un bon utilitaire à utiliser comme contrôle de bon sens pour s'assurer que HBase peut lire tous les blocs d'une table s'il y a des préoccupations d'incohérence des métadonnées. Il exécutera le MapReduce all en un seul processus, mais il s'exécutera plus rapidement si vous avez un cluster MapReduce en place pour qu'il l'exploite.
$ hbase org.apache.hadoop.hbase.mapreduce.RowCounter <tablename>
Usage: RowCounter [options]
<tablename> [
--starttime=[start]
--endtime=[end]
[--range=[startKey],[endKey]]
[<column1> <column2>...]
]
vous pouvez utiliser la méthode count dans hbase pour compter le nombre de lignes. Mais oui, compter les rangées d'une grande table peut être lent.le comte "tablename" [intervalle]
valeur de Retour est le nombre de lignes.
cette opération peut prendre beaucoup de temps (Run ' $HADOOP_HOME / bin/hadoop jar hbase.jar rowcount " pour exécuter un comptage travail de mapreduce). Le compte courant est affiché tous les 1000 rangs par défaut. L'intervalle de comptage peut être spécifié en option. Scannez la mise en cache est activée par défaut sur les numérisations. La taille par défaut du cache est de 10 lignes. Si vos lignes sont de petite taille, vous pouvez 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 aussi être exécutées sur une référence de table. Supposons que vous ayez une référence au tableau '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
HBase rowcount map / reduce job c'est inclus avec HBase
Si vous ne pouvez pas utiliser RowCounter
pour une raison quelconque, alors une combinaison de ces deux filtres devrait être un moyen optimal pour obtenir un compte:
FirstKeyOnlyFilter() AND KeyOnlyFilter()
FirstKeyOnlyFilter
aura pour résultat que le scanner retournera seulement le premier qualificatif de colonne qu'il trouve, par opposition au scanner retournera tous les qualificatifs de colonne dans la table, ce qui minimisera la bande réseau avec. Pourquoi ne pas simplement choisir un qualificatif de colonne à retourner? Ça marcherait si vous pouviez garder cette colonne. qualificatif existe pour chaque ligne, mais si ce n'est pas vrai, alors vous obtiendrez un compte inexact.
KeyOnlyFilter
aura pour résultat que le scanner retournera seulement la famille de colonnes, et ne retournera aucune valeur pour le qualificatif de colonnes. Cela réduit encore la bande passante du réseau, ce qui dans le cas général ne serait pas une grande partie d'une réduction, mais il peut y avoir un cas de bord où la première colonne choisie par le filtre précédent se trouve juste être un extrêmement grand valeur.
j'ai essayé de jouer avec les scan.setCaching
mais les résultats étaient partout. Elle pourrait peut-être aider.
j'ai eu 16 millions de lignes entre un début et de fin que j'ai fait la pseudo-empirique:
With FirstKeyOnlyFilter and KeyOnlyFilter activated: With caching not set (i.e., the default value), it took 188 seconds. With caching set to 1, it took 188 seconds With caching set to 10, it took 200 seconds With caching set to 100, it took 187 seconds With caching set to 1000, it took 183 seconds. With caching set to 10000, it took 199 seconds. With caching set to 100000, it took 199 seconds. With FirstKeyOnlyFilter and KeyOnlyFilter disabled: With caching not set, (i.e., the default value), it took 309 seconds
Je n'ai pas pris la peine de faire des tests appropriés à ce sujet, mais il semble clair que le FirstKeyOnlyFilter
et KeyOnlyFilter
sont bonnes.
de plus, les cellules dans ce tableau sont très petites - donc je pense que les filtres auraient été encore mieux 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.RegexStringComparator; public class HBaseCount { public static void main(String[] args) throws 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("scan's caching is " + 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(); try { for (Result rr = scanner.next(); rr != null; rr = scanner.next()) { count += 1; if (count % 100000 == 0) System.out.println(count); } } finally { scanner.close(); } long end = System.currentTimeMillis(); long elapsedTime = end - start; System.out.println("Elapsed time was " + (elapsedTime/1000F)); } }
Voici un pychbase exemple de code:
from pychbase import Connection c = Connection() t = c.table('my_table') # Under the hood this applies the FirstKeyOnlyFilter and KeyOnlyFilter # similar to the happybase example below print t.count(row_prefix="foo")
voici un exemple de code Happybase:
from happybase import Connection c = Connection(...) t = c.table('my_table') count = 0 for _ in t.scan(filter='FirstKeyOnlyFilter() AND KeyOnlyFilter()'): count += 1 print count
merci à @Tuckr and @KennyCason pour l'astuce.
méthode Simple, efficace et efficiente pour compter les lignes dans HBASE:
chaque fois que vous insérez une ligne déclenchez cette API qui va incrémenter cette cellule particulière.
Htable.incrementColumnValue(Bytes.toBytes("count"), Bytes.toBytes("details"), Bytes.toBytes("count"), 1);
pour vérifier le nombre de lignes présentes dans ce tableau. 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 coprocesseur ce qui est disponible depuis HBase 0.92. Voir Coprocesseur et Agrégateprotocol et exemple
pour compter L'enregistrement de la table Hbase compter sur un groupe de fils approprié vous devez définir la carte réduire le nom de la file d'attente d'emploi ainsi:
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, scanner essayer de revenir le plus petit nombre de qualificatifs que possible. En fait, le(s) qualificatif (s) que vous retournez devrait être le plus petit (en octet-size) que vous avez disponible. Cela accélérera considérablement votre scan.
malheureusement, cela ne se fera que jusqu'à présent (millions-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.
Magasin de la Mapreduce sortie dans une cellule dans HBase. Chaque fois que vous ajoutez une rangée, incrémentez le compteur de 1. Chaque fois que vous supprimez une ligne, décrémente 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 pour compter les lignes autrement d'une manière qui balance. Vous pouvez seulement prendre en compte de façon rapide.
U peut trouver un exemple de 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;
}
Aller à Hbase maison répertoire et exécutez cette commande,
./ bin / hbase org.Apache.hadoop.hbase.mapreduce.RowCounter 'espace de noms:nom de la table'
ceci lancera un travail mapreduce et la sortie indiquera le nombre d'enregistrements existant dans la table hbase.
Vous pouvez essayer les méthodes de l'api hbase!
org.Apache.hadoop.hbase.client.coprocesseur.AggregationClient