Disponible depuis juillet 2018 avec HDP3 (Hortonworks Data Platform 3), Apache Hive 3 apporte de nombreuses fonctionnalités intéressantes à l'entrepôt de données. Malheureusement, à l'instar de nombreuses versions majeures du logiciel "FOSS", il contient des pièges et peu de documentation.

Dans un premier temps, je passerai en revue les nouvelles fonctionnalités disponibles avec Hive 3, puis je donnerai quelques conseils et astuces tirés de leur utilisation en production pendant plusieurs mois. La première partie de l'article est basée sur la présentation. Quoi de neuf dans Apache Hive? enseigné par Jason Dere au DataWorks Summit 2019 Barcelona.

Les nouvelles fonctionnalités de Hive 3

De nombreuses fonctions et améliorations ont été apportées à Hive 3, élargissant considérablement les cas d'utilisation pouvant être couverts. Regardons ceux disponibles dans HDP3, ce qui est le cas pour la plupart d'entre eux.

Vues matérialisées (MV)

Les vues matérialisées sont enfin disponibles dans HDP. Mieux que les vues traditionnelles, ils fournissent:

  • Stockage pour résultats intermédiaires: comme le nom l'indique, les résultats des vues matérialisées sont stockés, ce qui permet une mutualisation des coûts de calcul;
  • la reconstruction incrémentale: la mise à jour d'une vue matérialisée est effectuée uniquement à partir des nouvelles données insérées dans les tables source après la dernière mise à jour;
  • la réécriture des requêtes: Lorsque cela est possible, l'optimiseur de coûts utilise par conséquent des vues matérialisées existantes au lieu de tables source pour planifier et optimiser les requêtes. transparent, sans intervention de l'utilisateur!

Pour plus d'informations sur les points de vue matérialisés, voir l'article de mon collègue Paul-Adrien Cordonnier Accélérez vos requêtes avec des vues matérialisées dans Apache Hive.

Fonctionnalités SQL

Restrictions et valeurs par défaut

Il est maintenant possible d'utiliser des restrictions SQL UNIQUE et NOT NULL, en plus de PRIMARY|FOREIGN KEY (ajouté dans Hive 2.1). En outre, vous pouvez spécifier une valeur DEFAULT pour chaque colonne et utiliser cette valeur par défaut dans les instructions INSERT et UPDATE.

CREATE TABLE users (
  id INT NOT NULL,
  firstname STRING,
  lastname STRING,
  join_date DATE DEFAULT CURRENT_DATE(),
  PRIMARY KEY (id) DISABLE NOVALIDATE
);
INSERT INTO TABLE users VALUES (1, 'John', 'Doe', DEFAULT);

Informations de la table

Hive 3 facilite l'exploration de tout l'entrepôt avec les bases information_schema et sys :

SELECT table_schema, table_name
FROM information_schema.columns
WHERE column_name LIKE '%ssn%';

Connecteurs JDBC, Druid et Kafka

Deux nouveaux connecteurs sont disponibles pour les tables externes:

  • la Connecteur JDBC (JdbcStorageHandler), qui est en lecture seule pour le moment. Il vous permet de lire et d'importer facilement des données depuis n'importe quelle base de données compatible: MySQL, PostgreSQL, Oracle, MSSQL et Apache Derby.
  • la Connecteur Kafka, qui peut être utilisé pour interroger des données en temps réel d'Apache Kafka, et permet également une entrée de données en temps réel dans Hive avec une garantie "unique" et une transformation des données en temps réel. Regarder Intégrer Hive et Kafka Pour plus de détails.

En outre, l'ingestion de "exactement une fois" de Kafka à Druid peut être gérée par Hive.

ACID v2

Dans les versions précédentes, Hive ACID (Atomicité, Cohérence, Isolement et Durabilité) a fait beaucoup de choses géré stocké au format Apache ORC:

  • Ingestion de transmission de données;
  • opérations INSERT/UPDATE/DELETE dans les tables existantes sans affecter les opérations en cours.

La deuxième version de Hive ACID présente plusieurs améliorations:

  • Des performances aussi bonnes que les tables non-ACID;
  • Les tables transactionnelles (qui prennent en charge les opérations ACID) ne doivent plus être groupées;
  • Prise en charge des formats non-ORC pour les opérations INSERT/SELECT ;
  • Compatibilité avec les fournisseurs de stockage en nuage, par exemple Amazon S3;
  • La nouvelle API HiveStreaming (v2).

Hortonworks a décidé d'activer l'ACID par défaut dans HDP3. Par exemple, les tables ORC internes doivent être transactionnelles.

Malheureusement, la plupart des problèmes rencontrés avec Hive 3 proviennent de Hive ACID et de l'API HiveStreaming. Ces problèmes et leurs solutions sont discutés ci-dessous dans la deuxième partie de l'article.

Le connecteur Hive Warehouse pour Apache Spark

À partir de HDP 3.0, toutes les interactions entre Hive et Apache Spark doivent passer par le connecteur du connecteur de magasin Hive. Ce connecteur tire parti de Hive LLAP pour permettre une interaction transmission / ACID entre Hive et Spark. L'application Spark doit accéder à un serveur Hive interactif (avec LLAP activé) pour lire les tables. géré de Hive, mais elle n'en aura pas besoin pour écrire dans les tableaux géré ou lire / écrire des tables externes. Ne soyez pas surpris si la manière traditionnelle d'accéder aux tables Hive de Spark ne fonctionne plus!




Beehive Store Connector

Gérer les charges de travail LLAP

Cette grande nouvelle fonctionnalité améliore votre contrôle sur Live Hive et Process Hive (LLAP) dans des environnements multi-utilisateur avec les plans de ressources :

  • Divisez vos ressources LLAP en piscines, par exemple bi (pour Business Analytics) et etl (Extraire la transformation et la charge);
  • Attribuer automatiquement des applications à piscinespar exemple, Tableau a la piscine bi ;
  • Créer déclencheurs déplacer dynamiquement les applications d'un piscine à un autre, par exemple, déplacer de longues requêtes vers piscine etl ;
  • Activer / désactiver votre plans de ressources en fonction des besoins de ses utilisateurs (un actif à la fois).
CREATE RESOURCE PLAN my_plan;
CREATE POOL my_plan.bi
WITH ALLOC_FRACTION=70,QUERY_PARALLELISM=4;
CREATE POOL my_plan.etl
WITH ALLOC_FRACTION=30,QUERY_PARALLELISM=10;
CREATE TRIGGER my_plan.slow_query
WHEN execution_time_ms > 60000
DO MOVE TO etl;
ALTER PLAN my_plan SET DEFAULT POOL=bi;
ALTER PLAN my_plan ENABLE ACTIVATE;

Performance améliorée

Basé sur un test de performances récent de TPC-DS mené par l'équipe MR3, Hive LLAP 3.1.0 est le système SQL-on-Hadoop le plus rapide disponible dans HDP 3.0.1. Le benchmark compare tous les systèmes SQL intégrés avec HDP3, ainsi que Ruche en MR3 (un nouveau moteur d’exécution pour Hadoop et Kubernetes) exécutant un ensemble de 99 requêtes SQL.

système Durée totale de TCP-DS (secondes)
HDP 3.0.1 LLAP 5516.89
Beehive 3.1.0 / MR3 6575.052
HDP 3.0.1 teint 12227.317
Presto 0,208e 12948.224
Spark 2.3.1 26 247 471

Je vous invite à lire l'article très complet. Évaluation des performances des systèmes SQL sur Hadoop à l'aide du test de performances TPC-DS et les performances de Jason Dere vous donnent plus de détails sur ce qui accélère Hive 3.

Hive 3, trucs et astuces

J'ai maintenu une instance de Hive 3 pendant plus de 5 mois. Durant cette période, j'ai rencontré des problèmes de stabilité et mis en œuvre des solutions parfois complexes. Plus de détails sur la configuration Hive utilisée sont disponibles à la fin de l'article.

Si vous envisagez d'utiliser Hive 3, cela vous aidera probablement à identifier et à résoudre vos problèmes, au moins avant qu'ils ne soient résolus dans une prochaine version officielle.

Fuites de mémoire dans l'API HiveStreaming

La nouvelle API HiveStreaming mentionnée ci-dessus a deux pertes de mémoire connues (HIVE-20979). Cela concerne toutes les applications clientes utilisant l’API, qui peuvent être bloquées en raison d’une tas de la machine virtuelle Java.

Dans mon cas, l'application cliente était Apache NiFi et son processeur PutHive3Streaming. C'est le processeur officiel fourni avec NiFi 1.7.0 pour écrire dans Hive 3.0+. Puisque j'utilise l'API HiveStreaming (v2), mon cluster NiFi tombe toujours en panne après quelques heures de fonctionnement.

J'ai passé du temps à analyser NiFi et j'ai fini par réécrire le processeur (NiFi Hive3Streaming Fixed). Cette réimplémentation intègre des correctifs fournis par la communauté Hive (HIVE-20979). Si vous voulez en savoir plus sur ce problème particulier lié à NiFi, consultez l'article dédié Dépannage d'un tuyau NiFi-HiveStreaming (à venir bientôt)

Si vous examinez attentivement le ticket JIRA HIVE-20979, vous verrez que le correctif est supposé être de la version 3.1.1 de Hive. Cependant, ce n'est pas le cas … Mais ce n'est pas si grave, car même s'il est corrigé, vous devez attendre la migration de Hortonworks vers Hive 3.1.1 et la mise à jour de l'ensemble de votre cluster (si vous utilisez HDP).

Enfin, la bonne chose à propos de ce problème HiveStreaming est qu’il peut le résoudre. Comme je l'ai fait pour réécrire le processeur, étudiez les correctifs fournis par la communauté Hive (HIVE-20979) et intégrez les classes Java pertinentes dans votre application. Si vous en avez besoin, vous pouvez réutiliser des parties de mon code publiées sur GitHub!

Problèmes liés au compactage de ruches ACID

Comme mentionné précédemment, les tables Hive sont transactionnel défaut dans HDP 3 et tableaux géré dans ORC, cela ne peut pas être non transactionnel. Cela signifie qu'ils prennent en charge les opérations ACID:

  • atomicité: une opération réussit ou échoue;
  • consistance: Une fois qu'une opération a été effectuée, chaque opération suivante verra ses résultats.
  • isolation: une opération incomplète n'affecte pas les autres opérations;
  • durabilité: Une fois l'opération terminée, elle est conservée même en cas de panne de la machine ou du système.

Bien que cela fournisse davantage de fonctions aux tables, cela pose également de nouveaux problèmes, car le mécanisme interne des tables de transactions est plus complexe. J'ai trouvé plusieurs problèmes avec le système de compactage.

Que sont les compactions de ruche?

Avant de détailler les problèmes, vous devez comprendre ce que sont les compactions et pourquoi elles sont nécessaires avec Hive ACID.

Pour effectuer des opérations ACID, chaque transaction (INSERT,UPDATE, DELETE) sur un seau créer de nouveaux fichiers stockés dans des répertoires delta. Chaque partition de table contient un répertoire base et plusieurs annuaires delta :

hdfs dfs -ls -R /warehouse/tablespace/managed/hive/d.db/t
drwxr-xr-x   - hive hive     0 2016-06-09 17:03 /warehouse/tablespace/managed/hive/d.db/t/base_0000022
-rw-r--r--   1 hive hive   602 2016-06-09 17:03 /warehouse/tablespace/managed/hive/d.db/t/base_0000022/bucket_00000
drwxr-xr-x   - hive hive     0 2016-06-09 17:06 /warehouse/tablespace/managed/hive/d.db/t/delta_0000023_0000023_0000
-rw-r--r--   1 hive hive   611 2016-06-09 17:06 /warehouse/tablespace/managed/hive/d.db/t/delta_0000023_0000023_0000/bucket_00000
drwxr-xr-x   - hive hive     0 2016-06-09 17:07 /warehouse/tablespace/managed/hive/d.db/t/delta_0000024_0000024_0000
-rw-r--r--   1 hive hive   610 2016-06-09 17:07 /warehouse/tablespace/managed/hive/d.db/t/delta_0000024_0000024_0000/bucket_00000

Comme vous pouvez l'imaginer, une partition contient autant de dossiers delta transactions (en réalité, les transactions sont regroupées et validées par lots). Cela peut rapidement devenir un problème s’il est ingéré en continu, car Hive devra lire de plus en plus de fichiers à chaque fois.

Pour sauvegarder les performances de Hive, il existe deux types de compactions:

  • Comparaisons mineures fusionner les fichiers delta ongle seau dans un fichier delta ;
  • Grandes compactions fusionner tous les fichiers delta ongle seau dans les archives base existant de cette seau.

Par défaut, Hive est censé activer automatiquement des compactions basées sur un ensemble de propriétés (voir la documentation officielle). Cependant, d'après mon expérience, cela ne fonctionne vraiment pas comme prévu …

Les compactions ne tirent pas

Après avoir utilisé les tables de transactions comme destination d'un flux de données NiFi, j'ai découvert que les compactions ne fonctionnaient pas comme elles le devraient. Le comportement que j'ai observé est le suivant:

  1. Une nouvelle partition est créée, elle n’a donc pas de fichier de base pas de fichier delta ;
  2. Hive inspecte cette partition pendant son cycle de vérification. Vous pouvez voir quelles partitions sont marquées dans le fichier hivemetastore.log :

    cat /var/log/hive/hivemetastore.log | grep -P 'Checking to see if we should compact'
  3. Puisqu'il n'y a pas de fichier base, le seuil de compilation de fichier base il est atteint lors de la première vérification (car les fichiers delta représente un pourcentage infini de la taille de la partition);
  4. Le compactage principal et le fichier sont activés base il est créé;
  5. Après cela, plus aucune vérification n'est faite sur cette partition …

Apparemment, je ne suis pas le seul à traiter ce problème (problème de débordement de pile), bien que je ne sois pas sûr que tout le monde y fasse face et que je n’aie pas trouvé la cause.

Après avoir essayé de régler les paramètres hive.compactor.* sans succès, j'ai fini par écrire un flux de travail automatisé avec Apache Oozie pour activer des compactions "manuelles" plus importantes. la flux de travail Effectue les opérations suivantes au niveau de la base de données toutes les 10 minutes:

  1. Obtenir une liste de dossiers delta et base avec un script bash:

    
    hdfs dfs -ls -R "/warehouse/tablespace/managed/hive/$target_db.db" 
    | grep 'drwx' | grep -P -o '(^ )*(delta_d{7}|base)_d{7}_*d{0,4}$' 
  2. Analysez la liste et générez une demande de compactage pour chaque partition qui en a besoin. Je le fais avec un script Python.
  3. Publiez des requêtes générées sur Hive, ce que je fais via Beeline qui vous permet d'envoyer un fichier de requête paramétré:

    
    ALTER TABLE target_db.tbl1 PARTITION (col1 = 'value1') COMPACT 'major';

Voici comment vous pouvez garantir les performances Hive si vous rencontrez les mêmes problèmes de compactage. Si vous choisissez cette méthode, faites attention à:

  • La file d'attente YARN dans laquelle vous publiez vos demandes de compactage. Pour éviter de pénaliser vos utilisateurs et de vous assurer que les compactions ne sont pas retardées, je vous suggère de dédier une file d'attente.
  • Propriété yarn.scheduler.capacity(.queue).maximum-am-resource-percent, soit 20% par défaut. Chaque compactage est libéré 1 Application maître et 1 carte. Afin que vous puissiez augmenter le maximum-am-resource-percent, surtout si vous dédiez une ligne. Dans ce cas, cette propriété vous permet également de contrôler le nombre de compactages effectués en parallèle.
  • La mémoire utilisée par le compacteur. Si vous remarquez que certaines compactions prennent trop de temps, vous pouvez écraser la propriété compactor.mapreduce.map.memory.mb au niveau de la table ou lors de la consultation du compactage:

    ALTER TABLE target_db.tbl1 PARTITION (col1 = 'value1')
    COMPACT 'major'
    WITH OVERWRITE TBLPROPERTIES ('compactor.mapreduce.map.memory.mb' = '3072');
  • Le nombre maximum de fichiers. delta compacté simultanément avec la propriété hive.compactor.max.num.delta. Cela aide à normaliser le temps nécessaire aux compactions et à éviter les exceptions de type "OutOfMemory":

    hive.compactor.max.num.delta = 100
  • La propriété de la table NO_AUTO_COMPACTIONQui est-ce false par défaut. Si vous ne voulez pas que Hive interfère avec votre programme de compactage personnalisé, vous pouvez le configurer dans true dans des tableaux spécifiques:

    CREATE TABLE target_db.tbl1 (
    ...
    )
    TBLPROPERTIES ('NO_AUTO_COMPACTION' = 'true');

Erreur d'usurpation d'identité

Si vous utilisez Apache Ranger pour gérer les autorisations sur Hive, la propriété hive.server2.enable.doAs est réglé sur false de sorte que toute opération effectuée via le serveur Hive est exécutée comme hive. utilisateur hive a généralement tous les fichiers dans la table géré.

Cependant, lorsque vous utilisez HiveStreaming pour insérer des données dans des tables, vous ne communiquez pas avec le serveur Hive, mais directement avec le serveur Hive Meivetore! Par conséquent, vous devez faire attention aux informations d'identification de l'utilisateur appelant l'API. oui hive vous n'êtes pas le propriétaire des partitions de la table, vous pouvez trouver cette erreur dans le fichier hivemetastore.log :

2019-03-03T00:00:00,799 ERROR (pool-8-thread-188): server.TThreadPoolServer (TThreadPoolServer.java:run(297)) - Error occurred during processing of message.
java.lang.RuntimeException: org.apache.thrift.transport.TTransportException: Peer indicated failure: GSS initiate failed
...
Caused by: org.apache.thrift.transport.TTransportException: Peer indicated failure: GSS initiate failed

Si vous activez le mode déboguerVous obtiendrez la source de l'erreur:

2019-03-14T12:55:46,299 ERROR (Thread-19): transport.TSaslTransport (TSaslTransport.java:open(315)) - SASL negotiation failure
javax.security.sasl.SaslException: GSS initiate failed
...
    at java.security.AccessController.doPrivileged(Native Method) (?:1.8.0_112)
    at javax.security.auth.Subject.doAs(Subject.java:422) (?:1.8.0_112)
...
    at org.apache.hadoop.hive.ql.txn.compactor.Cleaner.removeFiles(Cleaner.java:352)...

Promotion chez notre partenaire