Vous ne détestez pas vraiment la latence ? Ouais, je déteste ça aussi.
Aujourd’hui, je veux parler de la création d’applications sur des entrepôts de données. Je souhaite expliquer comment obtenir une faible latence si votre application consomme des données de BigQuery, Snowflake, Redshift ou de tout autre entrepôt de données basé sur le cloud.
Mon objectif est de vous donner un cours accéléré sur les performances des entrepôts de données, d’expliquer comment comprendre les performances des API de données et de mettre en évidence quelques outils qui aident à créer des applications réactives au-dessus des entrepôts de données.
Que sont les entrepôts de données ?
D’une manière générale, les entrepôts de données sont des emplacements centraux pour les données provenant de plusieurs sources. Appelez cela une source unique de vérité. C’est à vous de configurer un processus pour extraire, transformer et charger (ETL) les données des systèmes sources en fonction d’un calendrier ou d’un ensemble d’événements. Ensuite, vous exécutez généralement des rapports et des analyses de données pour obtenir des informations commerciales.
Les entrepôts de données sont généralement optimisés pour le traitement analytique en ligne (OLAP). Cela signifie exécuter un volume relativement faible de requêtes analytiques complexes avec des jointures lourdes de tables d’un milliard de lignes. Les requêtes incluront souvent des calculs numériques utilisant des fonctions d’agrégat comme AVG
, COUNT DISTINCT
, PERCENTILE_CONT
, et bien d’autres comme eux.
En conséquence directe, les entrepôts de données sont souvent conçus comme des systèmes à mise à l’échelle automatique et fortement distribués avec des moteurs de stockage en colonnes.
Snowflake Data Cloud, Google BigQuery et Amazon Redshift sont tous de bons exemples de tels entrepôts de données et le choix le plus utilisé et le plus populaire pour stocker d’énormes quantités de données. Si votre entreprise utilise un entrepôt de données, il s’agit probablement de l’un de ces mastodontes.
OLAP est souvent opposé à OLTP, qui signifie traitement des transactions en ligne. Cela signifie exécuter un volume élevé de requêtes pas si complexes où les données sont principalement insérées ou mises à jour plutôt que d’être lues. Cependant, le spectre est beaucoup plus large et il y a plus de dimensions (jeu de mots).
Alors que les entreprises collectent et transfèrent des volumes fous de données dans leurs entrepôts de données, elles veulent avoir un aperçu de ces données. Vos utilisateurs internes s’intéressent davantage à l’obtention de rapports à la demande plutôt qu’à des impressions hebdomadaires. Votre entreprise devient moins tolérante aux outils de BI avec un délai d’analyse comparable au temps qu’il faut pour préparer une tasse de café plutôt qu’au temps qu’il faut pour penser à en préparer une.
En tant que développeur d’applications, vous devez soudainement comprendre comment créer des applications réactives et performantes au-dessus des entrepôts de données tout en assurant la satisfaction de votre entreprise et de vos utilisateurs. Mais que fait exactement « réactif et performant » moyenne? Voyons cela.
Performances de l’entrepôt de données du point de vue d’un développeur d’applications
En tant que développeurs d’applications, nous souhaitons que nos utilisateurs maintiennent le sentiment qu’ils opèrent directement sur les données, indépendamment d’une opération, du volume de données ou du nombre d’autres utilisateurs agissant en parallèle. Des études indiquent qu’une application réagit « instantanément » si elle répond aux actions de l’utilisateur dans les 10 ms, et 1 seconde est la limite au-dessus de laquelle une application risque d’interrompre le flux de ses pensées. Nous arrivons ici à la latence des requêtes.
Latence
La latence des requêtes est le temps qu’il faut pour exécuter une requête et recevoir le résultat. Prenons maintenant en compte la vitesse de la lumière ! Sérieusement, imaginons qu’un utilisateur de Californie envoie une demande à votre application déployée dans une région populaire, par exemple, us-east-1
sur AWS. Avec un aller-retour de deux fois la distance de 3 000 milles et la vitesse de la lumière de 186 000 mi/s, le délai minimum entre l’envoi de la demande et l’obtention de la réponse serait de 30 ms. Attendez, et qu’en est-il de nos utilisateurs à l’étranger ? Vous pouvez réellement utiliser des CDN massivement distribués comme CloudFront ou Netlify Edge pour rapprocher votre application des utilisateurs, mais est-ce pratique pour les entrepôts de données avec lesquels votre application interagit ?
Cela signifie que toute demande de votre application à un entrepôt de données devrait prendre moins d’une seconde. Réellement, bien moins d’une seconde si nous souhaitons prendre en compte la vitesse de la lumière, les retards du réseau, le temps d’exécution des requêtes, le temps d’exécution de notre logique métier en plus des données, etc.
Qu’est-ce qui affecte le temps d’exécution de la requête ? Il s’agit principalement de la quantité de données à analyser. Avec des ensembles de données plus volumineux, ces analyses prennent plus de temps. Pour répartir la charge, les entrepôts de données utilisent plusieurs nœuds, ce qui introduit des retards pour les communications entre les nœuds.
Voyons maintenant ce que les entrepôts de données du monde réel peuvent offrir.
Latence des requêtes dans BigQuery
Commençons par BigQuery, un entrepôt de Big Data sans serveur disponible dans le cadre de Google Cloud Platform. Il est hautement évolutif, ce qui signifie qu’il peut traiter de minuscules ensembles de données ainsi que des pétaoctets de données en quelques secondes, en utilisant plus de capacité cloud selon les besoins. Vous pouvez gérer ses performances en choisissant le modèle de tarification (à la demande par défaut, forfait disponible en option) qui affecte la façon dont BigQuery alloue les emplacements, ses unités de calcul virtuelles avec les processeurs, la mémoire et le stockage temporaire utilisés pour l’exécution requêtes. BigQuery calcule automatiquement le nombre d’emplacements requis par chaque requête, en fonction de la taille et de la complexité de la requête. Il convient de noter que chaque requête est en concurrence pour les emplacements avec d’autres requêtes au sein d’un projet GCP, ainsi qu’avec d’autres projets si vous vous en tenez au modèle de tarification à la demande par défaut, comme beaucoup le font.
Utilisons la console interactive de BigQuery dans GCP pour estimer les latences possibles.
Après avoir importé des données TPC-H avec 150 millions de lignes dans mon propre ensemble de données, je voulais trouver quelques exemples de requêtes dont j’aurais besoin pour mes analyses. Tout d’abord, je voudrais voir une liste de toutes les commandes par jour d’un certain statut.
Voici la requête SQL que j’ai exécutée dans BigQuery.
L’exécution de la requête prend 1,4 seconde et a traité 2,7 Go. Si vous l’exécutez deux fois, vous verrez que la latence de la deuxième exécution est bien inférieure à une seconde car les résultats de la première exécution ont été mis en cache.
Cependant, si vous modifiez la requête, ajoutez ou mettez peut-être à jour un filtre dans le WHERE
clause, vous rencontrerez toujours la même latence de requête d’environ une seconde et demie. Pourquoi? La réponse est la mise en cache. BigQuery mettra en cache la réponse d’une requête afin que la requête identique suivante obtienne un temps de réponse beaucoup plus rapide. La documentation BigQuery explique plus en détail ce que sont les résultats mis en cache. Mais ce que vous devez savoir, c’est que pour récupérer les données du cache, le texte de la requête en double doit être exactement le même que la requête d’origine. Tous les résultats de la requête sont mis en cache dans des tables temporaires pendant environ 24 heures.
Le prix des requêtes mises en cache est déroutant. Vous n’êtes pas facturé pour les requêtes qui utilisent des résultats mis en cache, mais ces requêtes sont soumises aux règles de quota de BigQuery.
BigQuery est distribué par nature et ses unités de calcul sont par défaut partagées entre les utilisateurs. C’est pourquoi, dans BigQuery, la latence des requêtes inclut non seulement temps d’exécution de la requête mais aussi temps d’initialisation qui est dépensé pour créer un plan de requête, vérifier les quotas et les limites et allouer des créneaux. C’est pourquoi il n’est pas réaliste de s’attendre à ce que BigQuery fournisse une latence de requête inférieure à la seconde.
D’accord, mais qu’en est-il de Snowflake ?
Latence des requêtes dans Snowflake
Contrairement à BigQuery, Snowflake ne partage pas ses ressources de calcul entre les utilisateurs. Il traite les requêtes en utilisant ce qu’on appelle entrepôts virtuels, et chaque entrepôt virtuel contient de nombreux nœuds de calcul dédiés alloués par un fournisseur de cloud pour votre projet. Ainsi, chaque entrepôt virtuel ne partage pas de ressources de calcul avec d’autres entrepôts virtuels et n’a aucun impact sur les performances des autres entrepôts virtuels. Cependant, vos propres requêtes seront en effet en concurrence pour les ressources de vos entrepôts virtuels.
La latence des requêtes de Snowflake est améliorée grâce à des entrepôts virtuels pré-alloués. Cependant, tout a un prix, jeu de mots voulu. Gérer un entrepôt virtuel vous coûtera entre 1 et 128 crédits par heure. Cela finit par se situer entre 50 $ et 6 000 $ US par jour, selon le modèle de tarification basé sur l’utilisation de Snowflake.
Personne n’aime gaspiller de l’argent pour rien, donc Snowflake prend en charge la suspension automatique des entrepôts virtuels inactifs après un laps de temps spécifié. Un entrepôt suspendu ne consomme pas de crédits, mais lorsqu’une requête arrive, elle doit être re-provisionnée. Snowflake affirme que le provisionnement de l’entrepôt prend généralement 1 ou 2 secondes, cependant, selon la taille de l’entrepôt et la disponibilité des ressources de calcul, cela peut prendre plus de temps. Cela signifie qu’avec Snowflake, nous devons soit payer une prime importante, soit nous attendre à des retards intermittents lorsqu’un entrepôt virtuel suspendu est en cours de provisionnement.
Utilisons la console interactive de Snowflake pour vérifier notre intuition. J’ai choisi l’ensemble de données public TPC-H et utilisé l’exemple de base de données intégré fourni par Snowflake. Ces données sont fournies dans plusieurs schémas dans le SNOWFLAKE_SAMPLE_DATA
base de données partagée, basée sur l’exposant de 10, augmentant à partir de l’ensemble de données de base d’environ quelques millions d’éléments. Le schéma que j’ai utilisé est le TPCH_SF100
schéma avec 150 millions de lignes.
Les données que je veux correspondent exactement à la requête que j’ai exécutée sur BigQuery dans l’exemple ci-dessus. Je veux voir le montant total des commandes regroupées par jour et par statut dans une période comprise entre les années 1998 et 1999.
La requête a duré 4,7 secondes. Il a renvoyé 214 lignes à partir d’un ensemble de données contenant 150 millions d’éléments. J’ai utilisé l’instance de calcul X-Small dans Snowflake pour ce test. Bien sûr, vous pouvez faire évoluer les instances de calcul. Mais combien d’argent êtes-vous prêt à dépenser ? Ainsi, cela nous met dans un monde où obtenir une latence de requête inférieure à la seconde à partir d’un entrepôt de données est quelque chose comme une licorne magique.
Et je n’ai parlé que de latence jusqu’à présent. Nous pouvons tous convenir qu’il y a beaucoup d’autres facteurs en jeu. Permettez-moi de continuer en expliquant quelques-uns d’entre eux ci-dessous.
Latence vs concurrence
En tant que développeurs d’applications, nous créons des produits utilisés par des centaines, des milliers et des millions d’utilisateurs. Il est rare qu’un utilisateur seul exécute une seule requête à un moment donné. Votre application doit pouvoir exécuter plusieurs requêtes sur un entrepôt de données en parallèle. Le problème est que ces requêtes seront en concurrence pour les ressources disponibles.
La question est de savoir comment ces requêtes concurrentes parallèles auraient-elles un impact sur la latence des requêtes ? Nous savons que BigQuery peut fournir un temps de réponse d’environ 3 secondes pour une requête qui traite de grandes quantités de données, peut-être des pétaoctets. Quels seraient les temps de réponse pour 10 requêtes simultanées ? Ou peut-être, pendant le Black Friday, même quelques centaines de requêtes ?
La simultanéité des requêtes est le nombre de requêtes parallèles co-exécutant activement. La partie « activement » est importante ici, car les entrepôts de données peuvent mettre les requêtes en file d’attente au-delà d’une certaine limite et les exécuter uniquement lorsque les requêtes précédentes sont terminées. Dans BigQuery, selon ses quotas et ses limites, la simultanéité est limitée à 100 requêtes par projet. C’est un nombre relativement élevé, méfiez-vous simplement de cette partie « par projet ». Cela signifie que le quota est partagé entre toutes les applications qui interagissent avec le même projet GCP.
Les requêtes dont les résultats sont renvoyés par le cache de requêtes sont également soumises au quota. La raison en est que BigQuery doit déterminer qu’il s’agit d’un accès au cache. Cependant, vous n’êtes pas facturé pour les requêtes qui utilisent des résultats mis en cache. Étant donné que BigQuery est une boîte noire, la meilleure solution consiste à améliorer les performances des requêtes. Heureusement, il y a une explication détaillée dans les documents BigQuery sur la façon d’y parvenir. Voici un rapide aperçu.
Vous devez limiter les données d’entrée et les sources de données ; moins votre requête lit d’octets, mieux c’est. Ne jamais utiliser SELECT * ...
car il analysera toutes les colonnes de l’ensemble de données. Ensuite, améliorez la communication entre les slots, en réduisant les données avant d’utiliser un GROUP BY
ou JOIN
clause.
Utilisation ORDER BY
et LIMIT
uniquement dans la requête la plus externe pour améliorer les performances de calcul des requêtes et gérer la sortie des requêtes. Rappelles toi,…