Wednesday, November 2, 2011

Optimiser les accès en lecture sur HBase

Increase HBase read performance checklist

Accès en parallèle, client "multihtread"
Dans HBase les données sont découpées en Régions et ces Régions peuvent être servies par des Region Servers différents. La charge de lecture doit donc être dans la mesure du possible distribuée sur l'ensemble des serveurs. 

Privilégier les lectures en mode "batch"
L'API HBase permet de lotir des appels à la base dans des "Batch Operations". L’intérêt est d'éviter de trop nombreux aller/retour sur le réseau.
Ainsi les opérations PUT, GET, DELETE peuvent être regroupées dans un seul appel à la base de donnée.


HTable hTable = new HTable("cachetestdb");
List listOfget = new ArrayList();
for (int i = 0; i < 10; i++) {
String keyAsString = "17#" + i;
Get get = new Get(Bytes.toBytes(keyAsString));
listOfget.add(get);
}

Object[] batch = hTable.batch(listOfget);

for (Object object : batch) {
Result result = (Result) object; 
/* TODO : process data */
}



Le cache joue t-il correctement son rôle ?
Il est important de vérifier si le cache joue efficacement son rôle. HBase dispose en effet d'un cache de type LRU pour accélérer l'accès aux données récemment accédées.
Si ce n'est pas le cas car les accès se font sur des données non contiguës alors il peut être envisageable de diminuer la taille des blocs de données qui par défaut est de 64Ko Attention à ne pas confondre les blocs de données gérés par HBase avec les blocs de données du système de fichiers HDFS qui par défaut sont de 64Mo.
Au contraire si le cache est souvent atteint (lecture de plages de données contiguës) on peut augmenter la taille de ses blocs (e.g. 640Ko)




Paramètre IN_MEMORY sur les Column Family
Lors de la déclaration d'une Column Family il est possible de positionner le paramètre IN_MEMORY à true (par défaut il est à false). Dans ce cas HBase va faire son maximum pour garder les données en mémoire en les rendant plus prioritaire lors du nettoyage du cache.
Par défaut seules les 2 tables "systèmes" -ROOT- et .META. possèdent cette propriété afin de garantir un accès rapide aux données qu'elles contiennent. L'activation de cette propriété place donc vos données dans le cache avec le même niveau de priorité.

Utilisation des "Bloom filters"
Les Bloom filters permettent d'accélérer la recherche d'une ligne en excluant certains fichiers de données HFile de la recherche.
L'activation des Bloom filters peut se faire sur des données existantes, ils seront simplement générés et activés lors de la création de nouveau fichiers de données HFile lors de flush ou de (major/minor) compact.
De plus depuis l'arrivée du format HFile V2 avec la version 0.92 de HBase (en release candidate  à l'heure où j'écris ces lignes) la pression sur la mémoire engendrée par leur activation s'est considérablement amoindrie. A l'ouverture d'un fichier HFile V1 il fallait charger l'intégralité des données des bloom filters en mémoire : cela ralentissait l'ouverture du fichier et donc la disponibilité des données de la Region. Ce n'est plus le cas avec le nouveau format.
Depuis la version 0.92 HBase lit les HFile V1 et les convertis en V2 lors des opérations de flush ou de (major/minor) compact

Compression des données
HBase permet de compresser les données, le gain en terme de rapidité de lecture des données est en règle générale supérieur à l'augmentation de la consommation CPU induite par les algorithmes de compression. L'intégration de l'algorithme Google Snappy dans la version 0.92 vient compléter la liste des algorithmes déjà intégrés dans les versions antérieures : Gzip et LZO (attention cependant aux dépendances sur les bibliothèques natives pour LZO et Snappy)
Si il est en règle générale toujours une bonne chose d'activer la compression des données il faudra noter que cela n'apportera rien sur des données ayant déjà une trop grande entropie (archives .zip, images jpeg ...)
La compression des données se définie au niveau des Column Family.
Quel algorithme choisir ?
  • GZip : très bon taux de compression mais aussi très gourmand en CPU, ce qui diminue les débit de lectures et d'écritures
  • LZO : bon compromis entre taux de compression et débit
  • Snappy : taux de compression en retrait par rapport aux autres algorithme mais le débit qu'il assure est excellent
N.B : il s'agit de comportements généralement observés, si vous parcourez la mailing list vous trouverez des avis divergents concernant l'efficacité des algorithmes de compression