Théorie et pratique de l'utilisation de HBase

Bon aprÚs-midi Je m'appelle Danil Lipovoy, notre équipe chez Sbertech a commencé à utiliser HBase comme stockage pour les données opérationnelles. Au cours de son étude, une expérience s'est accumulée que j'ai voulu systématiser et décrire (nous espérons qu'elle sera utile à beaucoup). Toutes les expériences ci-dessous ont été réalisées avec les versions HBase 1.2.0-cdh5.14.2 et 2.0.0-cdh6.0.0-beta1.

  1. Architecture générale
  2. Écriture de donnĂ©es sur HBASE
  3. Lecture de données depuis HBASE
  4. Mise en cache des données
  5. Traitement des données par lots MultiGet/MultiPut
  6. Stratégie de fractionnement des tables en régions (fractionnement)
  7. Tolérance aux pannes, compactification et localisation des données
  8. ParamĂštres et performances
  9. Tests de résistance
  10. résultats

1. Architecture générale

Théorie et pratique de l'utilisation de HBase
Le MaĂźtre de sauvegarde Ă©coute le battement de cƓur de l'actif sur le nƓud ZooKeeper et, en cas de disparition, reprend les fonctions du maĂźtre.

2. Écrivez les donnĂ©es sur HBASE

Tout d'abord, examinons le cas le plus simple : Ă©crire un objet clĂ©-valeur dans une table Ă  l'aide de put(rowkey). Le client doit d'abord dĂ©couvrir oĂč se trouve le serveur de rĂ©gion racine (RRS), qui stocke la table hbase:meta. Il reçoit ces informations de ZooKeeper. AprĂšs quoi, il accĂšde Ă  RRS et lit la table hbase:meta, Ă  partir de laquelle il extrait des informations sur le RegionServer (RS) responsable du stockage des donnĂ©es pour une clĂ© de ligne donnĂ©e dans la table d'intĂ©rĂȘt. Pour une utilisation future, la mĂ©ta-table est mise en cache par le client et donc les appels ultĂ©rieurs sont plus rapides, directement vers RS.

Ensuite, RS, aprĂšs avoir reçu une demande, l'Ă©crit tout d'abord dans WriteAheadLog (WAL), ce qui est nĂ©cessaire Ă  la rĂ©cupĂ©ration en cas de crash. Enregistrez ensuite les donnĂ©es sur MemStore. Il s'agit d'un tampon en mĂ©moire qui contient un ensemble triĂ© de clĂ©s pour une rĂ©gion donnĂ©e. Une table peut ĂȘtre divisĂ©e en rĂ©gions (partitions), chacune contenant un ensemble disjoint de clĂ©s. Cela vous permet de placer des rĂ©gions sur diffĂ©rents serveurs pour obtenir des performances plus Ă©levĂ©es. Cependant, malgrĂ© l’évidence de cette affirmation, nous verrons plus loin que cela ne fonctionne pas dans tous les cas.

AprÚs avoir placé une entrée dans le MemStore, une réponse est renvoyée au client indiquant que l'entrée a été enregistrée avec succÚs. Cependant, en réalité, ils sont stockés uniquement dans un tampon et n'arrivent sur le disque qu'aprÚs un certain temps ou lorsqu'ils sont remplis de nouvelles données.

Théorie et pratique de l'utilisation de HBase
Lors de l'exĂ©cution de l'opĂ©ration « Supprimer Â», les donnĂ©es ne sont pas physiquement supprimĂ©es. Ils sont simplement marquĂ©s comme supprimĂ©s, et la destruction elle-mĂȘme se produit au moment de l'appel de la fonction majeure compacte, qui est dĂ©crite plus en dĂ©tail au paragraphe 7.

Les fichiers au format HFile sont accumulés dans HDFS et de temps en temps le processus de compactage mineur est lancé, qui fusionne simplement les petits fichiers en plus gros sans rien supprimer. Au fil du temps, cela se transforme en un problÚme qui n'apparaßt qu'à la lecture des données (nous y reviendrons un peu plus tard).

En plus du processus de chargement dĂ©crit ci-dessus, il existe une procĂ©dure beaucoup plus efficace, qui constitue peut-ĂȘtre l'aspect le plus fort de cette base de donnĂ©es : BulkLoad. Cela rĂ©side dans le fait que nous formons indĂ©pendamment des HFiles et les mettons sur le disque, ce qui nous permet d'Ă©voluer parfaitement et d'atteindre des vitesses trĂšs dĂ©centes. En fait, la limitation ici n'est pas HBase, mais les capacitĂ©s du matĂ©riel. Vous trouverez ci-dessous les rĂ©sultats de dĂ©marrage sur un cluster composĂ© de 16 RegionServers et de 16 NodeManager YARN (CPU Xeon E5-2680 v4 Ă  2.40 GHz * 64 threads), HBase version 1.2.0-cdh5.14.2.

Théorie et pratique de l'utilisation de HBase

Ici, vous pouvez voir qu'en augmentant le nombre de partitions (régions) dans le tableau, ainsi que les exécuteurs Spark, nous obtenons une augmentation de la vitesse de téléchargement. De plus, la vitesse dépend du volume d'enregistrement. Les gros blocs donnent une augmentation du Mo/sec, les petits blocs du nombre d'enregistrements insérés par unité de temps, toutes choses étant égales par ailleurs.

Vous pouvez Ă©galement commencer Ă  charger sur deux tables en mĂȘme temps et doubler la vitesse. Ci-dessous, vous pouvez voir que l'Ă©criture simultanĂ©e de blocs de 10 Ko sur deux tables se produit Ă  une vitesse d'environ 600 Mo/s dans chacune (total 1275 623 Mo/s), ce qui coĂŻncide avec la vitesse d'Ă©criture sur une table de 11 Mo/s (voir n° XNUMX ci-dessus)

Théorie et pratique de l'utilisation de HBase
Mais la deuxiĂšme exĂ©cution avec des enregistrements de 50 Ko montre que la vitesse de tĂ©lĂ©chargement augmente lĂ©gĂšrement, ce qui indique qu'elle se rapproche des valeurs limites. Dans le mĂȘme temps, vous devez garder Ă  l'esprit qu'il n'y a pratiquement aucune charge créée sur HBASE lui-mĂȘme, tout ce qui lui est demandĂ© est d'abord de donner les donnĂ©es de hbase:meta, et aprĂšs avoir alignĂ© HFiles, de rĂ©initialiser les donnĂ©es BlockCache et de sauvegarder le Tampon MemStore sur le disque, s'il n'est pas vide.

3. Lecture des données depuis HBASE

Si nous supposons que le client dispose dĂ©jĂ  de toutes les informations de hbase:meta (voir point 2), alors la requĂȘte va directement au RS oĂč est stockĂ©e la clĂ© requise. Tout d'abord, la recherche est effectuĂ©e dans MemCache. Qu'il y ait ou non des donnĂ©es, la recherche est Ă©galement effectuĂ©e dans le tampon BlockCache et, si nĂ©cessaire, dans HFiles. Si des donnĂ©es ont Ă©tĂ© trouvĂ©es dans le fichier, elles sont placĂ©es dans BlockCache et seront renvoyĂ©es plus rapidement lors de la prochaine requĂȘte. La recherche dans HFile est relativement rapide grĂące Ă  l'utilisation du filtre Bloom, c'est-Ă -dire aprĂšs avoir lu une petite quantitĂ© de donnĂ©es, il dĂ©termine immĂ©diatement si ce fichier contient la clĂ© requise et sinon, passe au suivant.

Théorie et pratique de l'utilisation de HBase
Ayant reçu des données de ces trois sources, RS génÚre une réponse. Il peut notamment transférer plusieurs versions trouvées d'un objet à la fois si le client a demandé le versionnage.

4. Mise en cache des données

Les tampons MemStore et BlockCache occupent jusqu'Ă  80 % de la mĂ©moire RS allouĂ©e sur le tas (le reste est rĂ©servĂ© aux tĂąches de service RS). Si le mode d'utilisation typique est tel que les processus Ă©crivent et lisent immĂ©diatement les mĂȘmes donnĂ©es, il est alors logique de rĂ©duire BlockCache et d'augmenter MemStore, car Lorsque les donnĂ©es d'Ă©criture ne pĂ©nĂštrent pas dans le cache pour ĂȘtre lues, BlockCache sera utilisĂ© moins frĂ©quemment. Le tampon BlockCache se compose de deux parties : LruBlockCache (toujours sur le tas) et BucketCache (gĂ©nĂ©ralement hors tas ou sur un SSD). BucketCache doit ĂȘtre utilisĂ© lorsqu'il y a beaucoup de demandes de lecture et qu'elles ne rentrent pas dans LruBlockCache, ce qui conduit au travail actif de Garbage Collector. Dans le mĂȘme temps, il ne faut pas s'attendre Ă  une augmentation radicale des performances grĂące Ă  l'utilisation du cache de lecture, mais nous y reviendrons au paragraphe 8.

Théorie et pratique de l'utilisation de HBase
Il existe un BlockCache pour l'ensemble du RS et un MemStore pour chaque table (un pour chaque famille de colonnes).

Comme dĂ©crit en thĂ©orie, lors de l'Ă©criture, les donnĂ©es ne vont pas dans le cache et en effet, ces paramĂštres CACHE_DATA_ON_WRITE pour la table et « Cache DATA on Write » pour RS sont dĂ©finis sur false. Cependant, en pratique, si nous Ă©crivons des donnĂ©es sur MemStore, puis les vidons sur le disque (les effaçant ainsi), puis supprimons le fichier rĂ©sultant, puis en exĂ©cutant une requĂȘte get, nous recevrons avec succĂšs les donnĂ©es. De plus, mĂȘme si vous dĂ©sactivez complĂštement BlockCache et remplissez le tableau avec de nouvelles donnĂ©es, puis rĂ©initialisez le MemStore sur le disque, supprimez-les et demandez-les Ă  une autre session, elles seront toujours rĂ©cupĂ©rĂ©es quelque part. Ainsi, HBase stocke non seulement des donnĂ©es, mais aussi des mystĂšres mystĂ©rieux.

hbase(main):001:0> create 'ns:magic', 'cf'
Created table ns:magic
Took 1.1533 seconds
hbase(main):002:0> put 'ns:magic', 'key1', 'cf:c', 'try_to_delete_me'
Took 0.2610 seconds
hbase(main):003:0> flush 'ns:magic'
Took 0.6161 seconds
hdfs dfs -mv /data/hbase/data/ns/magic/* /tmp/trash
hbase(main):002:0> get 'ns:magic', 'key1'
 cf:c      timestamp=1534440690218, value=try_to_delete_me

Le paramĂštre « Cache DATA on Read Â» est dĂ©fini sur false. Si vous avez des idĂ©es, n'hĂ©sitez pas Ă  en discuter dans les commentaires.

5. Traitement des données par lots MultiGet/MultiPut

Le traitement de requĂȘtes uniques (Get/Put/Delete) est une opĂ©ration assez coĂ»teuse, donc si possible, vous devez les combiner dans une liste ou une liste, ce qui vous permet d'obtenir une amĂ©lioration significative des performances. Cela est particuliĂšrement vrai pour l'opĂ©ration d'Ă©criture, mais lors de la lecture, il existe le piĂšge suivant. Le graphique ci-dessous montre le temps nĂ©cessaire pour lire 50 000 enregistrements de MemStore. La lecture a Ă©tĂ© effectuĂ©e dans un thread et l'axe horizontal indique le nombre de clĂ©s dans la requĂȘte. Ici, vous pouvez voir qu'en augmentant jusqu'Ă  mille clĂ©s en une seule requĂȘte, le temps d'exĂ©cution diminue, c'est-Ă -dire la vitesse augmente. Cependant, avec le mode MSLAB activĂ© par dĂ©faut, aprĂšs ce seuil, une baisse radicale des performances commence, et plus la quantitĂ© de donnĂ©es dans l'enregistrement est importante, plus la durĂ©e de fonctionnement est longue.

Théorie et pratique de l'utilisation de HBase

Les tests ont Ă©tĂ© rĂ©alisĂ©s sur une machine virtuelle, 8 cƓurs, version HBase 2.0.0-cdh6.0.0-beta1.

Le mode MSLAB est conçu pour rĂ©duire la fragmentation du tas, qui se produit en raison du mĂ©lange de donnĂ©es de nouvelle et d'ancienne gĂ©nĂ©ration. Pour contourner ce problĂšme, lorsque MSLAB est activĂ©, les donnĂ©es sont placĂ©es dans des cellules relativement petites (morceaux) et traitĂ©es par morceaux. Par consĂ©quent, lorsque le volume du paquet de donnĂ©es demandĂ© dĂ©passe la taille allouĂ©e, les performances chutent fortement. D'un autre cĂŽtĂ©, dĂ©sactiver ce mode n'est pas non plus conseillĂ©, car cela entraĂźnerait des arrĂȘts dus au GC lors des moments de traitement intensif des donnĂ©es. Une bonne solution est d'augmenter le volume des cellules dans le cas d'une Ă©criture active via put en mĂȘme temps que la lecture. Il convient de noter que le problĂšme ne se produit pas si, aprĂšs l'enregistrement, vous exĂ©cutez la commande flush, qui rĂ©initialise MemStore sur le disque, ou si vous chargez Ă  l'aide de BulkLoad. Le tableau ci-dessous montre que les requĂȘtes du MemStore pour des donnĂ©es plus volumineuses (et de mĂȘme quantitĂ©) entraĂźnent des ralentissements. Cependant, en augmentant la taille des morceaux, nous ramenons le temps de traitement Ă  la normale.

Théorie et pratique de l'utilisation de HBase
En plus d'augmenter la taille des fragments, il est utile de diviser les données par région, c'est-à-dire fractionnement des tables. Cela se traduit par moins de demandes arrivant dans chaque région et si elles rentrent dans une cellule, la réponse reste bonne.

6. Stratégie de fractionnement des tables en régions (splitting)

Étant donnĂ© que HBase est un stockage clĂ©-valeur et que le partitionnement est effectuĂ© par clĂ©, il est extrĂȘmement important de diviser les donnĂ©es de maniĂšre Ă©gale dans toutes les rĂ©gions. Par exemple, diviser une telle table en trois parties entraĂźnera la division des donnĂ©es en trois rĂ©gions :

Théorie et pratique de l'utilisation de HBase
Il arrive que cela entraĂźne un fort ralentissement si les donnĂ©es chargĂ©es ultĂ©rieurement ressemblent, par exemple, Ă  des valeurs longues, la plupart commençant par le mĂȘme chiffre, par exemple :

1000001
1000002
...
1100003

Étant donnĂ© que les clĂ©s sont stockĂ©es sous forme de tableau d'octets, elles commenceront toutes de la mĂȘme maniĂšre et appartiendront Ă  la mĂȘme rĂ©gion n°1 stockant cette plage de clĂ©s. Il existe plusieurs stratĂ©gies de partitionnement :

HexStringSplit – Transforme la clĂ© en une chaĂźne codĂ©e hexadĂ©cimale dans la plage "00000000" => "FFFFFFFF" et remplit la gauche avec des zĂ©ros.

UniformSplit – Transforme la clĂ© en un tableau d'octets avec un codage hexadĂ©cimal dans la plage "00" => "FF" et un remplissage Ă  droite avec des zĂ©ros.

De plus, vous pouvez spĂ©cifier n'importe quelle plage ou jeu de clĂ©s pour le fractionnement et configurer le fractionnement automatique. Cependant, l'une des approches les plus simples et les plus efficaces est UniformSplit et l'utilisation de la concatĂ©nation de hachage, par exemple la paire d'octets la plus significative issue de l'exĂ©cution de la clĂ© via la fonction CRC32 (rowkey) et la rowkey elle-mĂȘme :

hachage + clé de ligne

Ensuite, toutes les données seront réparties uniformément entre les régions. Lors de la lecture, les deux premiers octets sont simplement supprimés et la clé d'origine reste. RS contrÎle également la quantité de données et de clés dans la région et, si les limites sont dépassées, la divise automatiquement en plusieurs parties.

7. Tolérance aux pannes et localisation des données

Puisqu'une seule rĂ©gion est responsable de chaque jeu de clĂ©s, la solution aux problĂšmes associĂ©s aux pannes ou au dĂ©classement de RS consiste Ă  stocker toutes les donnĂ©es nĂ©cessaires dans HDFS. Lorsque RS tombe, le maĂźtre le dĂ©tecte grĂące Ă  l'absence de battement de cƓur sur le nƓud ZooKeeper. Ensuite, il attribue la rĂ©gion desservie Ă  un autre RS et puisque les HFiles sont stockĂ©s dans un systĂšme de fichiers distribuĂ©, le nouveau propriĂ©taire les lit et continue de servir les donnĂ©es. Cependant, comme certaines donnĂ©es peuvent se trouver dans le MemStore et n'ont pas eu le temps d'entrer dans HFiles, WAL, qui est Ă©galement stockĂ© dans HDFS, est utilisĂ© pour restaurer l'historique des opĂ©rations. Une fois les modifications appliquĂ©es, RS est capable de rĂ©pondre aux demandes, mais ce dĂ©placement conduit au fait que certaines des donnĂ©es et les processus qui les gĂšrent se retrouvent sur des nƓuds diffĂ©rents, c'est-Ă -dire la localitĂ© diminue.

La solution au problĂšme est un compactage majeur - cette procĂ©dure dĂ©place les fichiers vers les nƓuds qui en sont responsables (oĂč se trouvent leurs rĂ©gions), de sorte qu'au cours de cette procĂ©dure, la charge sur le rĂ©seau et les disques augmente fortement. Cependant, Ă  l’avenir, l’accĂšs aux donnĂ©es sera sensiblement accĂ©lĂ©rĂ©. De plus, major_compaction effectue la fusion de tous les HFiles en un seul fichier au sein d'une rĂ©gion et nettoie Ă©galement les donnĂ©es en fonction des paramĂštres de la table. Par exemple, vous pouvez spĂ©cifier le nombre de versions d'un objet qui doivent ĂȘtre conservĂ©es ou la durĂ©e de vie aprĂšs laquelle l'objet est physiquement supprimĂ©.

Cette procĂ©dure peut avoir un effet trĂšs positif sur le fonctionnement de HBase. L'image ci-dessous montre comment les performances se sont dĂ©gradĂ©es en raison de l'enregistrement actif des donnĂ©es. Ici, vous pouvez voir comment 40 threads ont Ă©crit dans une table et 40 threads ont lu simultanĂ©ment des donnĂ©es. Les threads d'Ă©criture gĂ©nĂšrent de plus en plus de HFiles, qui sont lus par d'autres threads. En consĂ©quence, de plus en plus de donnĂ©es doivent ĂȘtre supprimĂ©es de la mĂ©moire et finalement le GC commence Ă  fonctionner, ce qui paralyse pratiquement tout le travail. Le lancement d'un important compactage a permis le dĂ©blayage des dĂ©bris rĂ©sultants et le rĂ©tablissement de la productivitĂ©.

Théorie et pratique de l'utilisation de HBase
Le test a été réalisé sur 3 DataNodes et 4 RS (CPU Xeon E5-2680 v4 à 2.40 GHz * 64 threads). HBase version 1.2.0-cdh5.14.2

Il convient de noter qu'un compactage majeur a Ă©tĂ© lancĂ© sur une table « en direct », dans laquelle les donnĂ©es Ă©taient activement Ă©crites et lues. Il y avait une dĂ©claration en ligne selon laquelle cela pourrait conduire Ă  une rĂ©ponse incorrecte lors de la lecture des donnĂ©es. Pour vĂ©rifier, un processus a Ă©tĂ© lancĂ© qui a gĂ©nĂ©rĂ© de nouvelles donnĂ©es et les a Ă©crites dans une table. AprĂšs quoi, j'ai immĂ©diatement lu et vĂ©rifiĂ© si la valeur rĂ©sultante coĂŻncidait avec ce qui avait Ă©tĂ© Ă©crit. Pendant que ce processus Ă©tait en cours, un compactage majeur a Ă©tĂ© effectuĂ© environ 200 fois et aucun Ă©chec n'a Ă©tĂ© enregistrĂ©. Le problĂšme apparaĂźt peut-ĂȘtre rarement et uniquement en cas de charge Ă©levĂ©e. Il est donc plus sĂ»r d'arrĂȘter les processus d'Ă©criture et de lecture comme prĂ©vu et d'effectuer un nettoyage pour Ă©viter de tels retraits du GC.

De plus, un compactage majeur n'affecte pas l'Ă©tat du MemStore ; pour le vider sur le disque et le compacter, vous devez utiliser flush (connection.getAdmin().flush(TableName.valueOf(tblName))).

8. ParamĂštres et performances

Comme dĂ©jĂ  mentionnĂ©, HBase montre son plus grand succĂšs lĂ  oĂč il n'a rien Ă  faire, lors de l'exĂ©cution de BulkLoad. Cependant, cela s’applique Ă  la plupart des systĂšmes et des personnes. Cependant, cet outil est plus adaptĂ© au stockage de donnĂ©es en masse dans de gros blocs, alors que si le processus nĂ©cessite plusieurs requĂȘtes de lecture et d'Ă©criture concurrentes, les commandes Get et Put dĂ©crites ci-dessus sont utilisĂ©es. Pour dĂ©terminer les paramĂštres optimaux, des lancements ont Ă©tĂ© effectuĂ©s avec diverses combinaisons de paramĂštres et rĂ©glages de table :

  • 10 threads ont Ă©tĂ© lancĂ©s simultanĂ©ment 3 fois de suite (appelons cela un bloc de threads).
  • Le temps de fonctionnement de tous les threads d’un bloc Ă©tait moyennĂ© et constituait le rĂ©sultat final du fonctionnement du bloc.
  • Tous les threads travaillaient avec la mĂȘme table.
  • Avant chaque dĂ©marrage du bloc de thread, un compactage majeur Ă©tait effectuĂ©.
  • Chaque bloc n'a effectuĂ© qu'une seule des opĂ©rations suivantes :

-Mettre
-Obtenir
—Obtenir+Mettre

  • Chaque bloc a effectuĂ© 50 000 itĂ©rations de son opĂ©ration.
  • La taille de bloc d'un enregistrement est de 100 octets, 1000 10000 octets ou XNUMX XNUMX octets (alĂ©atoire).
  • Les blocs ont Ă©tĂ© lancĂ©s avec diffĂ©rents nombres de clĂ©s demandĂ©es (soit une clĂ©, soit 10).
  • Les blocs ont Ă©tĂ© exĂ©cutĂ©s sous diffĂ©rents paramĂštres de table. ParamĂštres modifiĂ©s :

— BlockCache = activĂ© ou dĂ©sactivĂ©
— BlockSize = 65 Ko ou 16 Ko
— Partitions = 1, 5 ou 30
— MSLAB = activĂ© ou dĂ©sactivĂ©

Le bloc ressemble donc Ă  ceci :

un. Le mode MSLAB a été activé/désactivé.
b. Une table a Ă©tĂ© créée pour laquelle les paramĂštres suivants ont Ă©tĂ© dĂ©finis : BlockCache = true/none, BlockSize = 65/16 Ko, Partition = 1/5/30.
c. La compression a été réglée sur GZ.
d. 10 threads ont Ă©tĂ© lancĂ©s simultanĂ©ment en effectuant 1/10 opĂ©rations put/get/get+put dans cette table avec des enregistrements de 100/1000/10000 octets, effectuant 50 000 requĂȘtes d'affilĂ©e (clĂ©s alĂ©atoires).
e. Le point d a été répété trois fois.
F. La durée de fonctionnement de tous les threads a été moyennée.

Toutes les combinaisons possibles ont Ă©tĂ© testĂ©es. Il est prĂ©visible que la vitesse diminuera Ă  mesure que la taille de l'enregistrement augmente, ou que la dĂ©sactivation de la mise en cache entraĂźnera un ralentissement. Cependant, l'objectif Ă©tait de comprendre le degrĂ© et l'importance de l'influence de chaque paramĂštre, c'est pourquoi les donnĂ©es collectĂ©es ont Ă©tĂ© introduites dans une fonction de rĂ©gression linĂ©aire, ce qui permet d'Ă©valuer l'importance Ă  l'aide de statistiques t. Vous trouverez ci-dessous les rĂ©sultats des blocs effectuant des opĂ©rations Put. Ensemble complet de combinaisons 2*2*3*2*3 = 144 options + 72 tk. certains ont Ă©tĂ© rĂ©alisĂ©s deux fois. Il y a donc 216 exĂ©cutions au total :

Théorie et pratique de l'utilisation de HBase
Les tests ont été effectués sur un mini-cluster composé de 3 DataNodes et 4 RS (CPU Xeon E5-2680 v4 à 2.40 GHz * 64 threads). HBase version 1.2.0-cdh5.14.2.

La vitesse d'insertion la plus élevée de 3.7 secondes a été obtenue avec le mode MSLAB désactivé, sur une table avec une partition, avec BlockCache activé, BlockSize = 16, enregistrements de 100 octets, 10 piÚces par paquet.
La vitesse d'insertion la plus basse de 82.8 secondes a été obtenue avec le mode MSLAB activé, sur une table avec une partition, avec BlockCache activé, BlockSize = 16, enregistrements de 10000 1 octets, XNUMX chacun.

Regardons maintenant le modĂšle. On voit la bonne qualitĂ© du modĂšle basĂ© sur R2, mais il est tout Ă  fait clair que l’extrapolation est ici contre-indiquĂ©e. Le comportement rĂ©el du systĂšme lorsque les paramĂštres changent ne sera pas linĂ©aire ; ce modĂšle n'est pas nĂ©cessaire pour faire des prĂ©dictions, mais pour comprendre ce qui s'est passĂ© dans le cadre des paramĂštres donnĂ©s. Par exemple, nous voyons ici d’aprĂšs le critĂšre de Student que les paramĂštres BlockSize et BlockCache n’ont pas d’importance pour l’opĂ©ration Put (qui est gĂ©nĂ©ralement assez prĂ©visible) :

Théorie et pratique de l'utilisation de HBase
Mais le fait que l'augmentation du nombre de partitions entraĂźne une diminution des performances est quelque peu inattendu (nous avons dĂ©jĂ  vu l'impact positif de l'augmentation du nombre de partitions avec BulkLoad), bien que comprĂ©hensible. PremiĂšrement, pour le traitement, il faut gĂ©nĂ©rer des requĂȘtes vers 30 rĂ©gions au lieu d'une, et le volume de donnĂ©es n'est pas tel que cela puisse gĂ©nĂ©rer un gain. DeuxiĂšmement, la durĂ©e totale de fonctionnement est dĂ©terminĂ©e par le RS le plus lent, et comme le nombre de DataNodes est infĂ©rieur au nombre de RS, certaines rĂ©gions ont une localitĂ© nulle. Eh bien, regardons les cinq premiers :

Théorie et pratique de l'utilisation de HBase
Évaluons maintenant les rĂ©sultats de l'exĂ©cution des blocs Get :

Théorie et pratique de l'utilisation de HBase
Le nombre de partitions a perdu de son importance, ce qui s'explique probablement par le fait que les donnĂ©es sont bien mises en cache et que le cache de lecture est le paramĂštre le plus important (statistiquement). Naturellement, augmenter le nombre de messages dans une requĂȘte est Ă©galement trĂšs utile pour les performances. Meilleurs scores:

Théorie et pratique de l'utilisation de HBase
Et bien, enfin, regardons le modĂšle du bloc qui a d'abord effectuĂ© get puis put :

Théorie et pratique de l'utilisation de HBase
Tous les paramÚtres sont ici significatifs. Et les résultats des dirigeants :

Théorie et pratique de l'utilisation de HBase

9. Test de charge

Bon, enfin, nous lancerons une charge plus ou moins décente, mais c'est toujours plus intéressant quand on a quelque chose à comparer. Sur le site de DataStax, le développeur clé de Cassandra, on trouve résultats NT d'un certain nombre de stockages NoSQL, y compris HBase version 0.98.6-1. Le chargement a été effectué par 40 threads, taille des données 100 octets, disques SSD. Le résultat des tests des opérations de lecture-modification-écriture a montré les résultats suivants.

Théorie et pratique de l'utilisation de HBase
D'aprĂšs ce que je comprends, la lecture a Ă©tĂ© effectuĂ©e par blocs de 100 enregistrements et pour 16 nƓuds HBase, le test DataStax a montrĂ© une performance de 10 XNUMX opĂ©rations par seconde.

Heureusement que notre cluster dispose Ă©galement de 16 nƓuds, mais ce n'est pas trĂšs « chanceux » que chacun ait 64 cƓurs (threads), alors que dans le test DataStax il n'y en a que 4. Par contre, ils ont des disques SSD, alors que nous avons des disques durs ou plus, la nouvelle version de HBase et l'utilisation du processeur pendant le chargement n'ont pratiquement pas augmentĂ© de maniĂšre significative (visuellement de 5 Ă  10 %). Cependant, essayons de commencer Ă  utiliser cette configuration. ParamĂštres de table par dĂ©faut, la lecture est effectuĂ©e dans la plage clĂ© de 0 Ă  50 millions de maniĂšre alĂ©atoire (c'est-Ă -dire essentiellement nouvelle Ă  chaque fois). La table contient 50 millions d'enregistrements, rĂ©partis en 64 partitions. Les clĂ©s sont hachĂ©es Ă  l'aide de crc32. Les paramĂštres du tableau sont par dĂ©faut, MSLAB est activĂ©. En lançant 40 threads, chaque thread lit un ensemble de 100 clĂ©s alĂ©atoires et réécrit immĂ©diatement les 100 octets gĂ©nĂ©rĂ©s sur ces clĂ©s.

Théorie et pratique de l'utilisation de HBase
Support : 16 DataNode et 16 RS (CPU Xeon E5-2680 v4 Ă  2.40 GHz * 64 threads). HBase version 1.2.0-cdh5.14.2.

Le résultat moyen est plus proche de 40 10 opérations par seconde, ce qui est nettement meilleur que dans le test DataStax. Cependant, à des fins expérimentales, vous pouvez légÚrement modifier les conditions. Il est peu probable que tous les travaux soient effectués exclusivement sur une seule table, ainsi que sur des clés uniques. Supposons qu'il existe un certain ensemble de touches « chaudes » qui génÚrent la charge principale. Par conséquent, essayons de créer une charge avec des enregistrements plus gros (100 Ko), également par lots de 4, dans 50 tables différentes et en limitant la plage de clés demandées à 40 100. Le graphique ci-dessous montre le lancement de 10 threads, chaque thread lit un jeu de XNUMX clés et écrit immédiatement XNUMX Ko aléatoires sur ces clés.

Théorie et pratique de l'utilisation de HBase
Support : 16 DataNode et 16 RS (CPU Xeon E5-2680 v4 Ă  2.40 GHz * 64 threads). HBase version 1.2.0-cdh5.14.2.

Pendant le chargement, un compactage majeur a été lancé à plusieurs reprises, comme indiqué ci-dessus, sans cette procédure, les performances se dégraderont progressivement, cependant, une charge supplémentaire apparaßtra également pendant l'exécution. Les prélÚvements sont causés par diverses raisons. Parfois, les threads finissaient de fonctionner et il y avait une pause pendant leur redémarrage, parfois des applications tierces créaient une charge sur le cluster.

Lire et Ă©crire immĂ©diatement est l'un des scĂ©narios de travail les plus difficiles pour HBase. Si vous effectuez uniquement de petites requĂȘtes put, par exemple 100 octets, en les combinant en paquets de 10 Ă  50 50 Ă©lĂ©ments, vous pouvez obtenir des centaines de milliers d'opĂ©rations par seconde, et la situation est similaire avec les requĂȘtes en lecture seule. Il convient de noter que les rĂ©sultats sont radicalement meilleurs que ceux obtenus par DataStax, principalement grĂące Ă  des requĂȘtes par blocs de XNUMX XNUMX.

Théorie et pratique de l'utilisation de HBase
Support : 16 DataNode et 16 RS (CPU Xeon E5-2680 v4 Ă  2.40 GHz * 64 threads). HBase version 1.2.0-cdh5.14.2.

10. Conclusions

Ce systĂšme est configurĂ© de maniĂšre assez flexible, mais l'influence d'un grand nombre de paramĂštres reste encore inconnue. Certains d’entre eux ont Ă©tĂ© testĂ©s, mais n’ont pas Ă©tĂ© inclus dans l’ensemble de tests rĂ©sultant. Par exemple, des expĂ©riences prĂ©liminaires ont montrĂ© une signification insignifiante d'un paramĂštre tel que DATA_BLOCK_ENCODING, qui code les informations en utilisant les valeurs des cellules voisines, ce qui est comprĂ©hensible pour les donnĂ©es gĂ©nĂ©rĂ©es alĂ©atoirement. Si vous utilisez un grand nombre d’objets dupliquĂ©s, le gain peut ĂȘtre important. De maniĂšre gĂ©nĂ©rale, on peut dire que HBase donne l'impression d'une base de donnĂ©es assez sĂ©rieuse et bien pensĂ©e, qui peut ĂȘtre assez productive lors de la rĂ©alisation d'opĂ©rations avec de gros blocs de donnĂ©es. Surtout s'il est possible de sĂ©parer dans le temps les processus de lecture et d'Ă©criture.

S'il y a quelque chose Ă  votre avis qui n'est pas suffisamment divulguĂ©, je suis prĂȘt Ă  vous le dire plus en dĂ©tail. Nous vous invitons Ă  partager votre expĂ©rience ou Ă  discuter si vous n'ĂȘtes pas d'accord avec quelque chose.

Source: habr.com

Achetez un hĂ©bergement fiable pour les sites avec protection DDoS, serveurs VPS VDS đŸ”„ Achetez un hĂ©bergement web fiable avec protection DDoS, serveurs VPS et VDS | ProHoster