Accélérer vos requêtes avec les vues matérialisées dans Apache Hive

Accélérer vos requêtes avec les vues matérialisées dans Apache Hive

Jesus Camacho Rodriguez a organisé une présentation “Accelerating query processing with materialized views in Apache Hive” sur une nouvelle fonctionnalité à venir dans Apache Hive 3.0 : les vues matérialisées.

Cet article va décrire le principe général de cette fonctionnalité, donner quelques exemples et les améliorations prévues dans la roadmap du projet.

Ni une vue, ni une table : voici la vue matérialisée

D’après Wikipédia, une vue SQL est la synthèse d’une requête sur une base des données. En tant qu’utilisateur d’une base de données, vous accédez à vos données en pratiquant souvent les mêmes jointures, filtres ou agrégations. À l’aide d’une vue, il n’est pas nécessaire de répéter les mêmes requêtes complexes à chaque fois. On peut ainsi simplifier l’accès aux données tout en donnant plus de sens à l’utilisateur.

Par exemple un utilisateur a besoin d’un jeu de données d’un commerce. Pour accéder à la liste des marques préférées des clients, on va avoir besoin de faire une jointure sur les tables Clients, Commandes et Produit. On peut facilement cacher la complexité de ce schéma à l’utilisateur avec une seule table et gérer son accès avec ses propres ACLs.

Cependant des vues virtuelles sont composées de requêtes lentes et gourmandes. On pourrait à la place stocker le résultat de notre requête dans une autre table régulièrement, mais cela implique de modifier les modèles d’accès et il n’est pas simple de s’assurer que les données restent à jour.

Nous pouvons identifier quatre types d’optimisations :

  • Modifier physiquement la répartition des données (Tri, distribution…) ;
  • Filtrage et partitionnage ;
  • Dénormalisation ;
  • Pre agrégation.

Le but des vues matérialisées (MV) est d’augmenter les performances des requêtes en ne nécessitant aucune maintenance.

Les principales fonctionnalités sont :

  • Stocker le résultat d’une requête dans une table (Le stockage peut s’effectuer dans Hive ou dans Druid)
  • La définition de la vue est utilisée pour réécrire la requête et ne demande aucun changement dans les modèles d’accès
  • La fraîcheur des données est assurée par le système
  • Une insertion dans la table est très efficace puis qu’elle ne demande pas de reconstruire la vue

Exemples

Voyons quelques exemples pour illustrer les capacités de réécriture.

Dénormalisation et filtrage

La dénormalisation consiste à grouper plusieurs tables dans une table plus grande. Les opérations JOIN très lourdes ne sont ainsi plus nécessaires.

Nous étudierons ici deux tables contenant des employés avec leur départements respectifs dans l’entreprise.

Dans cet exemple nous allons dénormaliser ces tables et filtrer nos entrées selon la date d’embauche de nos employés :

empId empName deptID empSalary empHireDate
0 Frodo 10 20000 2018-03-03
1 Sam 10 22300 2016-11-11
2 Gimli 20 42300 2016-02-13
3 Galadriel 30 50000 2015-05-28
4 Legolas 30 72000 2015-05-01
deptId deptName
10 Accounting
20 Workers
30 HR

Notre requête pourrait ressembler à quelque chose comme ça pour lister les employés des Ressources Humaines recrutés au premier semestre 2016 :

SELECT employees.empId, employees.empName
 FROM employees JOIN departments
 ON (employees.deptId = departments.deptId)
 AND departments.deptName = 'HR'
 AND employees.empHireDate >= '2016-01-01'
 AND employees.empHireDate <= '2016-07-01';

Et voilà la vue matérialisée créée précédemment, contenant les employés et leur départements, filtrés sur l’année 2016.

CREATE MATERIALIZED VIEW mv AS
 SELECT
 employees.empId as empId,
 employees.empName as empName,
 departments.deptId as deptId,
 departments.deptName as deptName
 employees.empHireDate as empHireDate
 from employees, departments
 WHERE employees.deptId = departments.deptId
 AND employees.empHireDate >= '2016-01-01'
 AND employees.empHireDate <= '2016-12-31';

Notre requête une fois réécrite ressemble désormais à ceci, plus besoin de JOIN :

SELECT empId, empName
 from mv
 AND deptName = 'HR'
 AND empHireDate <= '2016-07-01'

Regroupement

Dans cet exemple nous stockons l’activité des utilisateurs sur un dépôt GIT. Chaque entrée contient le nombre de lignes ajoutées et supprimées d’un commit.

commitId commitDate commitAuthor commitLinesAdded commitLinesRemoved
0b42f0b 2018-01-02 18:04:33 Linus 123 3
d346b3d 2018-01-03 17:33:46 Linus 2 234
7151de5 2018-01-03 18:24:21 Richard 13 11

À l’aide d’une vue matérialisée, on peut regrouper les commits par jour et uniquement stocker l’agrégation des lignes. C’est un cas d’utilisation très pertinent dans le cadre d’un stockage sur Druid.

CREATE MATERIALIZED VIEW mv_commits_by_day
STORED AS 'org.apache.hadoop.hive.druid.DruidStorageHandler'
AS
  SELECT
    floor(time to day),
    commitAuthor as author,
    sum(commitLinesAdded) as linesAdded,
    sum(commitLinesRemoved) as linesRemoved
  FROM commits
  GROUP BY floor(time to day), author

Nos requêtes peuvent maintenant être très optimisées. Avant la réécriture :

SELECT
  floor(time to month),
  sum(commitLinesAdded)
FROM commits
GROUP BY floor(time to month)

Après la réécriture, la requête est bien plus légère grâce au groupement des lignes :

SELECT
  floor(time to month),
  sum(linesAdded)
FROM mv_commits_by_day
GROUP BY floor(time to month)

Activer la réécriture de requêtes

La réécriture de requêtes utilisant les vues matérialisées s’active avec la propriété suivante : SET hive.materializedview.rewriting=true;.

À l’échelle d’une vue, on peut activer ou désactiver la réécriture : ALTER MATERIALIZED VIEW mv ENABLE|DISABLE REWRITE.

La réécriture de requêtes est activée par défaut pour toutes les vues matérialisées.

Reconstruire une vue matérialisée

Une fois la vue créée, elle va présenter une image de ce qui est présent dans la table d’origine à un instant t.

Mais une fois la table mise à jour, la vue doit être reconstruite manuellement pour rester pertinente.

ALTER MATERIALIZED VIEW mv REBUILD;

Le moteur va toujours essayer une reconstruction incrémentale plutôt qu’une reconstruction complète. Actuellement une reconstruction incrémentale n’est possible que dans le cas d’une insertion dans la table.

Si un DELETE ou un UPDATE a été réalisé, la vue doit être entièrement reconstruite.

Données obsolètes

Une vue matérialisée est considérée comme obsolète dès que des modifications dans la table originale ont eu lieu.

Le système est capable de suivre le statut de ses vues. L’optimiseur va donc utiliser une combinaison des données obsolètes de la vue et des données fraîches de la table.

Le comportement par défaut est d’ignorer les données obsolètes, il est possible de changer ceci avec le paramètre hive.materializedview.rewriting.time.window. Ce paramètre est un intervalle pendant lequel les vues obsolètes peuvent quand même être utilisés pour la réécriture de requêtes.

Roadmap

Les développements sont toujours en cours et plusieurs améliorations sont prévues :

  • Amélioration de l’algorithme de réécriture de requête dans Apache Calcite ;
  • Gestion de la distribution des données dans la vue (SORT BY, CLUSTER BY, DISTRIBUTE BY) ;
  • Support des UPDATE et DELETE dans la reconstruction incrémentale des vues.

Conclusion

Cette nouvelle fonctionnalité de Hive est très prometteuse. On peut facilement l’intégrer à un grand nombre de cas d’utilisation grâce aux faibles impacts qu’elle engendre.

La nécessité d’une reconstruction complète après chaque mise à jour est encore un point très limitant. Cette amélioration est prévue dans la roadmap.

Les vues matéralisées devraient être disponible dans Hive 3.0.

Liens

Documentation

JIRA sur la fonctionnalité dans Apache Calcite

Accelerating query processing with materialized views in Apache Hive

Canada - Morocco - France

International locations

10 rue de la Kasbah
2393 Rabbat
Canada

Nous sommes une équipe passionnées par l'Open Source, le Big Data et les technologies associées telles que le Cloud, le Data Engineering, la Data Science le DevOps…

Nous fournissons à nos clients un savoir faire reconnu sur la manière d'utiliser les technologies pour convertir leurs cas d'usage en projets exploités en production, sur la façon de réduire les coûts et d'accélérer les livraisons de nouvelles fonctionnalités.

Si vous appréciez la qualité de nos publications, nous vous invitons à nous contacter en vue de coopérer ensemble.