Démo AresDB: outil d'analyse en temps réel open source basé sur GPU Uber

Grùce à une analyse en temps réel, nous, les employés d'Uber, nous faisons une idée de la situation et de l'efficacité du travail, et sur la base des données, nous décidons comment améliorer la qualité du travail sur la plate-forme Uber. Par exemple, l'équipe de projet surveille l'état du marché et identifie les problÚmes potentiels sur notre plateforme; un logiciel basé sur des modÚles d'apprentissage automatique prédit les offres de passagers et la demande de conducteurs; Les spécialistes du traitement des données améliorent les modÚles d'apprentissage automatique - à leur tour, pour améliorer la qualité des prévisions.



Dans le passé, pour l'analyse en temps réel, nous utilisions des solutions de base de données d'autres sociétés, mais aucune ne répondait à tous nos critÚres de fonctionnalité, d'évolutivité, d'efficacité, de coût et d'exigences opérationnelles.


Sorti en novembre 2018, AresDB est un outil d'analyse open source en temps réel. Il utilise une alimentation non conventionnelle, des processeurs graphiques (GPU), ce qui vous permet d'augmenter l'échelle de l'analyse. La technologie GPU, un outil d'analyse en temps réel prometteur, a considérablement progressé ces derniÚres années, ce qui la rend idéale pour le calcul parallÚle et le traitement de données en temps réel.


Dans les sections suivantes, nous décrivons la structure d'AresDB et comment cette solution intéressante pour l'analyse en temps réel nous a permis d'unifier, de simplifier et d'améliorer plus efficacement et plus rationnellement les solutions de base de données Uber pour l'analyse en temps réel. Nous espérons qu'aprÚs avoir lu cet article, vous essayerez AresDB dans le cadre de vos propres projets et vous assurerez également de son utilité!


Applications d'analyse en temps réel Uber


L'analyse des données est essentielle au succÚs d'Uber. Entre autres fonctions, des outils analytiques sont utilisés pour résoudre les tùches suivantes:


  • CrĂ©ation de tableaux de bord pour la surveillance des mesures commerciales.
  • Prendre des dĂ©cisions automatiques (par exemple, dĂ©terminer le coĂ»t d'un voyage et identifier les cas de fraude ) sur la base des mĂ©triques rĂ©capitulatives collectĂ©es.
  • CrĂ©ez des requĂȘtes alĂ©atoires pour diagnostiquer, dĂ©panner et dĂ©panner les opĂ©rations commerciales.

Nous classons ces fonctions avec différentes exigences comme suit:



Les tableaux de bord et les systĂšmes de prise de dĂ©cision utilisent des systĂšmes d'analyse en temps rĂ©el pour crĂ©er des requĂȘtes similaires sur des sous-ensembles de donnĂ©es relativement petits mais trĂšs importants (avec le plus haut niveau de pertinence des donnĂ©es) avec un QPS Ă©levĂ© et une faible latence.


Besoin d'un autre module analytique


Le problÚme le plus courant qu'Uber utilise des outils d'analyse en temps réel pour résoudre est le calcul des populations de séries chronologiques. Ces calculs donnent une idée des interactions des utilisateurs afin que nous puissions améliorer la qualité des services en conséquence. Sur cette base, nous demandons des indicateurs pour certains paramÚtres (par exemple, jour, heure, identifiant de ville et état du trajet) pendant une certaine période de temps pour des données filtrées de maniÚre aléatoire (ou parfois combinées). Au fil des ans, Uber a déployé plusieurs systÚmes conçus pour résoudre ce problÚme de diverses maniÚres.


Voici quelques solutions tierces que nous avons utilisées pour résoudre ce type de problÚme:


  • Apache Pinot , une base de donnĂ©es analytique open source distribuĂ©e Ă©crite en Java, convient Ă  l'analyse de donnĂ©es Ă  grande Ă©chelle. Pinot utilise une architecture lambda interne pour interroger les donnĂ©es des paquets et les donnĂ©es en temps rĂ©el dans le stockage des colonnes, un index binaire inversĂ© pour le filtrage et un arbre en Ă©toile pour mettre en cache les rĂ©sultats agrĂ©gĂ©s. Cependant, il ne prend pas en charge la dĂ©duplication, la mise Ă  jour ou l'insertion, la fusion ou les fonctionnalitĂ©s de requĂȘte avancĂ©es telles que le filtrage gĂ©ospatial. De plus, Ă©tant donnĂ© que Pinot est une base de donnĂ©es basĂ©e sur JVM, les requĂȘtes sont trĂšs coĂ»teuses en termes d'utilisation de la mĂ©moire.
  • Elasticsearch est utilisĂ© par Uber pour rĂ©soudre diverses tĂąches d'analyse de streaming. Il est construit sur la base de la bibliothĂšque Apache Lucene , qui stocke des documents, pour la recherche de mots clĂ©s en texte intĂ©gral et un index inversĂ©. Le systĂšme est rĂ©pandu et Ă©tendu pour prendre en charge des donnĂ©es agrĂ©gĂ©es. Un index inversĂ© fournit un filtrage mais n'est pas optimisĂ© pour le stockage et le filtrage des donnĂ©es en fonction des plages de temps. Les enregistrements sont stockĂ©s sous forme de documents JSON, ce qui impose des coĂ»ts supplĂ©mentaires pour fournir l'accĂšs au rĂ©fĂ©rentiel et aux requĂȘtes. Comme Pinot, Elasticsearch est une base de donnĂ©es basĂ©e sur JVM et, par consĂ©quent, ne prend pas en charge la fonction de jointure, et l'exĂ©cution des requĂȘtes occupe une grande quantitĂ© de mĂ©moire.

Bien que ces technologies aient leurs points forts, il leur manquait certaines des fonctionnalités nécessaires à notre cas d'utilisation. Nous avions besoin d'une solution unifiée, simplifiée et optimisée, et dans sa recherche nous avons travaillé dans une direction non standard (plus précisément, à l'intérieur du GPU).


Utilisation du GPU pour une analyse en temps réel


Pour un rendu réaliste des images avec une fréquence d'images élevée, les GPU traitent simultanément un grand nombre de formes et de pixels à grande vitesse. Bien que la tendance à augmenter la fréquence d'horloge des unités de traitement des données au cours des derniÚres années ait commencé à décliner, le nombre de transistors dans la puce n'a augmenté que conformément à la loi de Moore . En conséquence, la vitesse de calcul du GPU, mesurée en gigaflops par seconde (Gflops / s), augmente rapidement. La figure 1 ci-dessous montre une comparaison de la tendance de vitesse théorique (Gflops / s) du GPU NVIDIA et du CPU Intel au fil des ans:



Figure 1. Comparaison des performances du processeur à virgule flottante simple précision sur plusieurs années. Image tirée du guide de programmation CUDA C de Nvidia.


Lors du développement du mécanisme de demande d'analyse en temps réel, la décision d'intégrer le GPU était naturelle. Dans Uber, une demande d'analyse en temps réel typique nécessite de traiter les données en quelques jours avec des millions, voire des milliards d'enregistrements, puis de les filtrer et de les résumer en peu de temps. Cette tùche de calcul s'intÚgre parfaitement dans le modÚle de traitement parallÚle GPU à usage général, car ils:


  • Ils traitent les donnĂ©es en parallĂšle Ă  trĂšs grande vitesse.
  • Ils fournissent une vitesse de calcul plus Ă©levĂ©e (Gflops / s), ce qui les rend excellents pour effectuer des tĂąches de calcul complexes (dans des blocs de donnĂ©es) qui peuvent ĂȘtre parallĂ©lisĂ©es.
  • Ils fournissent des performances supĂ©rieures (sans dĂ©lai) dans l'Ă©change de donnĂ©es entre l'unitĂ© de calcul et le stockage (ALU et GPU de mĂ©moire globale) par rapport aux unitĂ©s de traitement centrales (CPU), ce qui les rend idĂ©ales pour le traitement des tĂąches d'E / S de mĂ©moire parallĂšle, qui nĂ©cessite une quantitĂ© importante de donnĂ©es.

En nous concentrant sur l'utilisation d'une base de données analytique basée sur GPU, nous - du point de vue de nos besoins - avons évalué plusieurs solutions analytiques existantes qui utilisent des GPU:


  • Kinetica , un outil analytique basĂ© sur GPU, est arrivĂ© sur le marchĂ© en 2009, initialement destinĂ© Ă  l'armĂ©e amĂ©ricaine et aux agences de renseignement. Bien qu'elle dĂ©montre le potentiel Ă©levĂ© de la technologie GPU dans l'analyse, nous avons constatĂ© que pour nos conditions d'utilisation, de nombreuses fonctions clĂ©s manquent, y compris la modification du schĂ©ma, l'insertion ou la mise Ă  jour partielle, la compression des donnĂ©es, la configuration du disque et de la mĂ©moire au niveau de la colonne, ainsi qu'une connexion relations gĂ©ospatiales.
  • OmniSci , un module de requĂȘte SQL open source, semblait ĂȘtre une option prometteuse, mais lors de l'Ă©valuation du produit, nous avons rĂ©alisĂ© qu'il lui manquait des fonctionnalitĂ©s importantes pour une utilisation dans Uber, telles que la dĂ©duplication. Bien qu'OminiSci ait introduit le code open source de son projet en 2017, aprĂšs avoir analysĂ© leur solution basĂ©e sur C ++, nous sommes arrivĂ©s Ă  la conclusion que ni changer ni brancher leur base de code n'est pratiquement faisable.
  • Les outils d'analyse en temps rĂ©el basĂ©s sur GPU, notamment GPUQP , CoGaDB , GPUDB , Ocelot , OmniDB et Virginian , sont souvent utilisĂ©s dans les Ă©tablissements de recherche et d'enseignement. Cependant, compte tenu de leurs objectifs acadĂ©miques, ces dĂ©cisions se concentrent sur le dĂ©veloppement d'algorithmes et de tests de concepts, plutĂŽt que sur la rĂ©solution de problĂšmes rĂ©els. Pour cette raison, nous ne les avons pas pris en compte - dans les conditions de notre volume et de notre Ă©chelle.

Dans l'ensemble, ces systÚmes démontrent l'énorme avantage et le potentiel du traitement des données à l'aide de la technologie GPU, et ils nous ont inspiré pour créer notre propre solution d'analyse GPU en temps réel adaptée aux besoins d'Uber. Sur la base de ces concepts, nous avons développé et ouvert le code source d'AresDB.


Présentation de l'architecture AresDB


À un niveau Ă©levĂ©, AresDB stocke la plupart des donnĂ©es dans la mĂ©moire hĂŽte (RAM, qui est connectĂ©e au CPU), utilise le CPU pour traiter les donnĂ©es reçues et les disques pour rĂ©cupĂ©rer les donnĂ©es. Pendant la pĂ©riode de demande, AresDB transfĂšre les donnĂ©es de la mĂ©moire hĂŽte vers la mĂ©moire GPU pour un traitement parallĂšle dans le GPU. Comme le montre la figure 2 ci-dessous, AresDB comprend le stockage en mĂ©moire, le stockage des mĂ©tadonnĂ©es et le disque:



Figure 2. L'architecture unique d'AresDB comprend le stockage en mémoire, le disque et le stockage des métadonnées.


Des tables


Contrairement Ă  la plupart des systĂšmes de gestion de bases de donnĂ©es relationnelles (SGBDR), AresDB n'a pas de portĂ©e de base de donnĂ©es ou de schĂ©ma. Toutes les tables appartiennent Ă  la mĂȘme portĂ©e dans un cluster / instance d'AresDB, ce qui permet aux utilisateurs d'y accĂ©der directement. Les utilisateurs stockent leurs donnĂ©es sous forme de tables de faits et de tables de dimensions.


Table de faits


La table de faits stocke un flux infini d'Ă©vĂ©nements de sĂ©ries chronologiques. Les utilisateurs utilisent une table de faits pour stocker les Ă©vĂ©nements / faits qui se produisent en temps rĂ©el, et chaque Ă©vĂ©nement est associĂ© Ă  l'heure de l'Ă©vĂ©nement, et la table est souvent interrogĂ©e par l'heure de l'Ă©vĂ©nement. À titre d'exemple du type d'informations stockĂ©es dans la table de faits, nous pouvons nommer les trajets, oĂč chaque trajet est un Ă©vĂ©nement, et l'heure de la demande de voyage est souvent appelĂ©e l'heure de l'Ă©vĂ©nement. Si plusieurs horodatages sont associĂ©s Ă  un Ă©vĂ©nement, un seul horodatage est indiquĂ© comme heure de l'Ă©vĂ©nement et s'affiche dans la table des faits.


Table de mesure


Le tableau de mesure enregistre les caractéristiques actuelles des installations (y compris les villes, les clients et les chauffeurs). Par exemple, les utilisateurs peuvent stocker des informations sur la ville, en particulier le nom de la ville, le fuseau horaire et le pays, dans le tableau de mesure. Contrairement aux tables de faits, qui ne cessent de croßtre, les tables de dimensions sont toujours de taille limitée (par exemple, pour Uber, la table des villes est limitée par le nombre réel de villes dans le monde). Les tableaux de mesure ne nécessitent pas de colonne de temps spéciale.


Types de données


Le tableau ci-dessous montre les types de données actuels pris en charge par AresDB:



Dans AresDB, les chaĂźnes sont automatiquement converties en Ă©numĂ©rations avant d'entrer dans la base de donnĂ©es pour augmenter la commoditĂ© du stockage et l'efficacitĂ© des requĂȘtes. Cela permet des vĂ©rifications d'Ă©galitĂ© sensibles Ă  la casse, mais ne prend pas en charge les opĂ©rations avancĂ©es telles que la concatĂ©nation, les sous-chaĂźnes, les masques et la correspondance d'expressions rĂ©guliĂšres. À l'avenir, nous avons l'intention d'ajouter l'option de support de ligne complĂšte.


Fonctions principales


L'architecture AresDB prend en charge les fonctionnalités suivantes:


  • Stockage sur colonne avec compression pour augmenter l'efficacitĂ© du stockage (moins de mĂ©moire en octets pour le stockage des donnĂ©es) et l'efficacitĂ© des requĂȘtes (moins d'Ă©change de donnĂ©es entre la mĂ©moire CPU et la mĂ©moire GPU lors du traitement d'une demande)
  • Mise Ă  jour ou insertion en temps rĂ©el avec dĂ©duplication de clĂ© primaire pour amĂ©liorer la prĂ©cision des donnĂ©es et mettre Ă  jour les donnĂ©es en temps rĂ©el en quelques secondes
  • Traitement des requĂȘtes GPU pour un traitement des donnĂ©es GPU hautement parallĂšle avec une faible latence des requĂȘtes (de quelques fractions de seconde Ă  plusieurs secondes)

Stockage sur colonne


Vecteur


AresDB stocke toutes les données dans un format de colonne. Les valeurs de chaque colonne sont stockées en tant que vecteur de valeur de colonne. Le marqueur de confiance / incertitude des valeurs de chaque colonne est stocké dans un vecteur zéro séparé, tandis que le marqueur de confiance de chaque valeur est présenté sous la forme d'un bit.


Stockage actif


AresDB stocke les données de colonne non compressées et non triées (vecteurs actifs) dans le stockage actif. Les enregistrements de données dans le stockage actif sont divisés en paquets (actifs) d'un volume donné. De nouveaux paquets sont créés lors de la réception des données, tandis que les anciens paquets sont supprimés aprÚs l'archivage des enregistrements. L'index de clé primaire est utilisé pour localiser la déduplication et mettre à jour les enregistrements. La figure 3 ci-dessous montre comment nous organisons les enregistrements actifs et utilisons la valeur de clé primaire pour déterminer leur emplacement:



Figure 3. Nous utilisons la valeur de clé primaire pour déterminer l'emplacement du package et la position de chaque enregistrement dans le package.


Les valeurs de chaque colonne du package sont stockées en tant que vecteur de colonne. Le marqueur de fiabilité / incertitude des valeurs dans chaque vecteur de valeur est stocké en tant que vecteur zéro séparé, et le marqueur de fiabilité de chaque valeur est présenté comme un bit. Dans la figure 4 ci-dessous, nous proposons un exemple avec cinq valeurs pour la colonne city_id :



Figure 4. Nous stockons les valeurs (valeur réelle) et les vecteurs zéro (marqueur de confiance) des colonnes non compressées dans le tableau de données.


Stockage d'archives


AresDB stocke également les données de colonne complétées, triées et compressées (vecteurs d'archive) dans le stockage d'archive via des tables de faits. Les enregistrements dans le stockage d'archives sont également distribués par lots. Contrairement aux packages actifs, le package d'archives stocke les enregistrements par jour en fonction du temps universel coordonné (UTC). Un paquet d'archives utilise le nombre de jours comme identifiant de paquet depuis Unix Epoch.


Les enregistrements sont stockés sous forme triée conformément à un ordre de tri des colonnes défini par l'utilisateur. Comme le montre la figure 5 ci-dessous, nous trions d'abord par la colonne city_id , puis par la colonne status:



Figure 5. Nous trions toutes les lignes par city_id, puis par état, puis compressons chaque colonne par codage de groupe. AprÚs tri et compression, chaque colonne recevra un vecteur comptable.


L'objectif de la définition de l'ordre de tri utilisateur pour les colonnes est le suivant:


  • Maximiser l'effet de compression en triant les colonnes avec un petit nombre d'Ă©lĂ©ments en premier lieu. La compression maximale amĂ©liore l'efficacitĂ© du stockage (moins d'octets sont nĂ©cessaires pour stocker les donnĂ©es) et l'efficacitĂ© des requĂȘtes (moins d'octets sont transfĂ©rĂ©s entre la mĂ©moire CPU et la mĂ©moire GPU).
  • Fournir un prĂ©-filtrage pratique basĂ© sur la plage pour les filtres Ă©quivalents courants, par exemple city_id = 12. Le prĂ©-filtrage minimise le nombre d'octets nĂ©cessaires pour transfĂ©rer des donnĂ©es entre la mĂ©moire CPU et la mĂ©moire GPU, ce qui maximise l'efficacitĂ© des requĂȘtes.

Une colonne n'est compressée que si elle est présente dans l'ordre de tri spécifié par l'utilisateur. Nous n'essayons pas de compresser les colonnes avec un grand nombre d'éléments, car cela économise peu de mémoire.


AprĂšs le tri, les donnĂ©es de chaque colonne qualifiĂ©e sont compressĂ©es Ă  l'aide d'une option de codage de groupe spĂ©cifique. En plus du vecteur valeur et du vecteur zĂ©ro, nous introduisons un vecteur comptable pour reprĂ©senter Ă  nouveau la mĂȘme valeur.


Réception de données en temps réel avec prise en charge des fonctions de mise à jour et d'insertion


Les clients reçoivent des données via l'API HTTP en publiant un service pack. Un Service Pack est un format binaire ordonné spécial qui minimise l'utilisation de l'espace tout en conservant un accÚs aléatoire aux données.


Lorsque AresDB reçoit le Service Pack, il Ă©crit d'abord le Service Pack dans le journal des opĂ©rations de rĂ©cupĂ©ration. Lorsqu'un service pack est ajoutĂ© Ă  la fin du journal des Ă©vĂ©nements, AresDB identifie et ignore les entrĂ©es tardives dans les tables de faits Ă  utiliser dans le stockage actif. Un enregistrement est considĂ©rĂ© comme «en retard» si l'heure de l'Ă©vĂ©nement est antĂ©rieure Ă  l'heure archivĂ©e de l'Ă©vĂ©nement de dĂ©connexion. Pour les enregistrements qui ne sont pas considĂ©rĂ©s comme «en retard», AresDB utilise l'index de clĂ© primaire pour localiser le package dans le magasin actif oĂč vous souhaitez les insĂ©rer. Comme le montre la figure 6 ci-dessous, les nouveaux enregistrements (non rencontrĂ©s prĂ©cĂ©demment en fonction de la valeur de la clĂ© primaire) sont insĂ©rĂ©s dans l'espace vide et les enregistrements existants sont mis Ă  jour directement:



Figure 6. Lorsque des données sont reçues, aprÚs avoir ajouté le Service Pack au journal des événements, les entrées «tardives» sont ajoutées à la file d'attente inversée et les autres entrées au stockage actif.


Archivage


Lorsque les données sont reçues, les enregistrements sont soit ajoutés / mis à jour dans le stockage actif, soit ajoutés à la file d'attente inversée, en attente de placement dans le stockage d'archives.


Nous commençons pĂ©riodiquement un processus planifiĂ©, appelĂ© archivage, en relation avec les enregistrements du stockage actif pour attacher de nouveaux enregistrements (enregistrements qui n'ont jamais Ă©tĂ© archivĂ©s auparavant) au stockage d'archives. Le processus d'archivage traite uniquement les enregistrements dans le stockage actif avec l'heure de l'Ă©vĂ©nement dans la plage comprise entre l'ancien temps d'arrĂȘt (temps d'arrĂȘt du dernier processus d'archivage) et le nouveau temps d'arrĂȘt (nouveau temps d'arrĂȘt basĂ© sur le paramĂštre de dĂ©lai d'archivage dans le schĂ©ma de table).


L'heure de l'Ă©vĂ©nement d'enregistrement est utilisĂ©e pour dĂ©terminer dans quels enregistrements de packages d'archives doivent ĂȘtre combinĂ©s lors du compactage des donnĂ©es d'archives dans des packages quotidiens. L'archivage ne nĂ©cessite pas de dĂ©duplication de l'index de la valeur de la clĂ© primaire lors de la fusion, car seuls les enregistrements compris entre l'ancien et le nouveau temps d'arrĂȘt sont archivĂ©s.


La figure 7 ci-dessous montre un graphique en fonction de l'heure de l'événement d'un enregistrement particulier.



Figure 7. Nous utilisons l'heure de l'événement et l'heure du trajet pour définir les enregistrements comme nouveaux (actifs) et anciens (l'heure de l'événement est antérieure à l'heure archivée de l'événement de voyage).


Dans ce cas, l'intervalle d'archivage est l'intervalle de temps entre les deux processus d'archivage, et le délai d'archivage est la période aprÚs l'heure de l'événement, mais jusqu'à ce que l'événement soit archivé. Les deux paramÚtres sont définis dans les paramÚtres du schéma de table AresDB.


Remblai


Comme le montre la figure 7 ci-dessus, les anciens enregistrements (dont l'heure de l'Ă©vĂ©nement est antĂ©rieure Ă  l'heure d'archivage de l'Ă©vĂ©nement d'arrĂȘt) pour les tables de faits sont ajoutĂ©s Ă  la file d'attente inversĂ©e et sont finalement traitĂ©s dans le cadre du processus de renvoi. Les dĂ©clencheurs de ce processus sont Ă©galement le temps ou la taille de la file d'attente inverse, si elle atteint un niveau seuil. ComparĂ© au processus d'ajout de donnĂ©es au stockage actif, le remplissage est asynchrone et relativement plus cher en termes de ressources CPU et mĂ©moire. Le remblayage est utilisĂ© dans les scĂ©narios suivants:


  • Traitement de donnĂ©es alĂ©atoires et trĂšs tardives
  • Capture manuelle des donnĂ©es historiques Ă  partir d'un flux de donnĂ©es en amont
  • Saisie de donnĂ©es historiques dans les colonnes rĂ©cemment ajoutĂ©es

Contrairement Ă  l'archivage, le processus de renvoi est idempotent et nĂ©cessite une dĂ©duplication basĂ©e sur la valeur de la clĂ© primaire. Les donnĂ©es remplissables seront finalement visibles par les requĂȘtes.


La file d'attente inversée est conservée en mémoire avec une taille prédéfinie et avec une charge importante de remplissage, le processus sera bloqué pour le client jusqu'à ce que la file d'attente soit effacée en démarrant le processus de remplissage.


Traitement des demandes


Dans l'implĂ©mentation actuelle, l'utilisateur doit utiliser le langage de requĂȘte Ares (AQL) créé par Uber pour exĂ©cuter des requĂȘtes dans AresDB. AQL est un langage efficace pour les requĂȘtes analytiques de sĂ©ries chronologiques et ne suit pas la syntaxe SQL standard comme «SELECT FROM WHERE GROUP BY» comme d'autres langages similaires Ă  SQL. A la place, AQL est utilisĂ© dans les champs structurĂ©s et peut ĂȘtre inclus dans les objets JSON, YAML et Go. Par exemple, au lieu de la /SELECT (*) /FROM /GROUP BY city_id, /WHERE = «» /AND request_at >= 1512000000 , la variante AQL Ă©quivalente en JSON s'Ă©crit comme suit:


 { “table”: “trips”, “dimensions”: [ {“sqlExpression”: “city_id”} ], “measures”: [ {“sqlExpression”: “count(*)”} ], ;”> “rowFilters”: [ “status = 'completed'” ], “timeFilter”: { “column”: “request_at”, “from”: “2 days ago” } } 

Au format JSON, AQL offre aux dĂ©veloppeurs d'un tableau de bord et d'un systĂšme dĂ©cisionnel un algorithme de requĂȘte de programme plus pratique que SQL, leur permettant de composer facilement des requĂȘtes et de les manipuler Ă  l'aide de code sans se soucier de choses comme l'injection SQL. Il agit comme un format de requĂȘte universel pour les architectures typiques des navigateurs Web, des serveurs externes et internes jusqu'Ă  la base de donnĂ©es (AresDB). De plus, AQL fournit une syntaxe pratique pour le filtrage par heure et le traitement par lots avec prise en charge de son propre fuseau horaire. En outre, le langage prend en charge un certain nombre de fonctions, telles que les sous-requĂȘtes implicites, pour Ă©viter les erreurs courantes dans les requĂȘtes et facilite le processus d'analyse et de réécriture des requĂȘtes pour les dĂ©veloppeurs de l'interface interne.


MalgrĂ© les nombreux avantages qu'offre AQL, nous savons bien que la plupart des ingĂ©nieurs connaissent mieux SQL. Fournir une interface SQL pour exĂ©cuter les requĂȘtes est l'une des prochaines Ă©tapes que nous examinerons dans le cadre de nos efforts pour amĂ©liorer l'interaction avec les utilisateurs d'AresDB.


L'organigramme d'exĂ©cution des requĂȘtes AQL est illustrĂ© Ă  la figure 8 ci-dessous:



Figure 8. L'organigramme de requĂȘte AresDB utilise notre propre langage de requĂȘte AQL pour traiter et rĂ©cupĂ©rer rapidement et efficacement les donnĂ©es.


Compilation de requĂȘtes


Une requĂȘte AQL est compilĂ©e dans le contexte de requĂȘte interne. Les expressions dans les filtres, les mesures et les paramĂštres sont analysĂ©es dans des arbres de syntaxe abstraite (AST) pour un traitement ultĂ©rieur via un processeur graphique (GPU).


Chargement des données


AresDB utilise des prĂ©filtres pour filtrer les donnĂ©es d'archives Ă  moindre coĂ»t avant de les envoyer au GPU pour un traitement parallĂšle. Étant donnĂ© que les donnĂ©es archivĂ©es sont triĂ©es selon l'ordre des colonnes configurĂ©, certains filtres peuvent utiliser cet ordre de tri et la mĂ©thode de recherche binaire pour dĂ©terminer la plage de correspondance appropriĂ©e. En particulier, des filtres Ă©quivalents pour toutes les colonnes X initialement triĂ©es et un filtre de plage facultatif pour les colonnes triĂ©es X + 1 peuvent ĂȘtre utilisĂ©s comme filtres prĂ©liminaires, comme le montre la figure 9 ci-dessous.



Figure 9. AresDB pré-filtre les données de la colonne avant de les envoyer au GPU pour traitement.


AprĂšs le prĂ©-filtrage, seules les valeurs vertes (rĂ©pondant Ă  la condition de filtre) doivent ĂȘtre envoyĂ©es au GPU pour un traitement parallĂšle. Les donnĂ©es d'entrĂ©e sont chargĂ©es dans le GPU et traitĂ©es un paquet Ă  la fois. Cela inclut les packages actifs et les packages d'archivage.


AresDB utilise les flux CUDA pour le pipelining et le traitement des données. Pour chaque demande, deux flux sont appliqués alternativement pour un traitement en deux étapes qui se chevauchent. Dans la figure 10 ci-dessous, nous proposons un graphique illustrant ce processus.



Figure 10. Dans AresDB, deux threads CUDA transmettent et traitent alternativement des données.


ExĂ©cution de requĂȘte


Pour plus de simplicitĂ©, AresDB utilise la bibliothĂšque Thrust pour implĂ©menter des procĂ©dures d'exĂ©cution de requĂȘte, qui propose des blocs d'un algorithme parallĂšle finement rĂ©glĂ© pour une implĂ©mentation rapide des requĂȘtes dans l'outil actuel.


Dans Thrust, les données vectorielles d'entrée et de sortie sont évaluées à l'aide d'itérateurs à accÚs aléatoire. Chaque thread GPU recherche les itérateurs d'entrée dans sa position de travail, lit les valeurs et effectue des calculs, puis écrit le résultat à la position correspondante dans l'itérateur de sortie.


Pour Ă©valuer les expressions AresDB, le modĂšle «un opĂ©rateur par cƓur» (OOPK) suit.


Dans la figure 11 ci-dessous, cette procĂ©dure est illustrĂ©e Ă  l'aide de l'exemple AST gĂ©nĂ©rĂ© Ă  partir de l'expression de dimension request_at – request_at % 86400 au stade de la compilation de la demande:



Figure 11. AresDB utilise le modÚle OOPK pour évaluer les expressions.


Dans le modĂšle OOPK, le moteur de requĂȘte AresDB contourne chaque nƓud feuille de l'arborescence AST et renvoie un itĂ©rateur pour le nƓud source. Si le nƓud racine est Ă©galement fini, l'action racine est effectuĂ©e directement sur l'itĂ©rateur d'entrĂ©e.


Pour chaque nƓud non racine non final ( opĂ©ration modulo dans cet exemple), un vecteur d'espace de travail temporaire est allouĂ© pour stocker le rĂ©sultat intermĂ©diaire obtenu Ă  partir de l'expression request_at% 86400 . À l'aide de Thrust, une fonction de noyau est lancĂ©e pour calculer le rĂ©sultat de cette instruction dans le GPU. Les rĂ©sultats sont stockĂ©s dans l'itĂ©rateur de l'espace de travail.


Pour un nƓud racine, la fonction noyau s'exĂ©cute de la mĂȘme maniĂšre que pour un nƓud non racine, non fini. Diverses actions de sortie sont effectuĂ©es en fonction du type d'expression, qui est dĂ©crit en dĂ©tail ci-dessous:


  • Filtrage pour rĂ©duire le nombre d'Ă©lĂ©ments vectoriels d'entrĂ©e
  • Enregistrement des donnĂ©es de sortie de mesure dans un vecteur de mesure pour une fusion ultĂ©rieure des donnĂ©es
  • Enregistrer la sortie des paramĂštres dans le vecteur de paramĂštres pour une fusion de donnĂ©es ultĂ©rieure

AprÚs avoir évalué l'expression, un tri et une transformation sont effectués pour enfin combiner les données. Dans les opérations de tri et de transformation, nous utilisons les valeurs du vecteur de dimension comme valeurs clés pour le tri et la transformation, et les valeurs du vecteur de paramÚtres comme valeurs pour combiner les données. Ainsi, les lignes avec des valeurs de dimension similaires sont regroupées et combinées. La figure 12 ci-dessous montre ce processus de tri et de conversion.



Figure 12. AprÚs avoir évalué l'expression, AresDB trie et convertit les données en fonction des valeurs clés des vecteurs de mesure (valeur clé) et des paramÚtres (valeur).


AresDB prend Ă©galement en charge les fonctions de requĂȘte avancĂ©es suivantes:


  • Join : AresDB prend actuellement en charge une option de jointure de hachage entre la table de faits et la table de dimension
  • Estimation du nombre d'Ă©lĂ©ments Hyperloglog: AresDB utilise l'algorithme Hyperloglog
  • Geo Intersect : AresDB ne prend actuellement en charge que les opĂ©rations interconnectĂ©es entre GeoPoint et GeoShape

Gestion des ressources


En tant que base de données basée sur la mémoire interne, AresDB doit gérer les types d'utilisation de la mémoire suivants:



Au démarrage d'AresDB, il utilise le budget de mémoire partagée configuré. Le budget est divisé en six types de mémoire et devrait également laisser suffisamment d'espace pour le systÚme d'exploitation et d'autres processus. Ce budget comprend également une estimation de congestion configurée statiquement, un magasin de données actif surveillé par le serveur et des données archivées que le serveur peut décider de télécharger et de supprimer en fonction du budget de mémoire restant.
La figure 13 ci-dessous montre le modÚle de mémoire hÎte AresDB.



Figure 13. AresDB gÚre sa propre utilisation de la mémoire afin qu'elle ne dépasse pas le budget de processus total configuré.


AresDB permet aux utilisateurs de définir des jours de préchargement et des priorités au niveau des colonnes pour les tables de faits et les données archivées de préchargement uniquement les jours de préchargement. Les données qui n'ont pas été téléchargées précédemment sont chargées en mémoire à partir du disque sur demande. Une fois rempli, AresDB supprime également les données archivées de la mémoire hÎte. Les principes de suppression d'AresDB sont basés sur les paramÚtres suivants: le nombre de jours de préchargement, les priorités des colonnes, le jour de compilation du package et la taille de la colonne.


AresDB gĂšre Ă©galement plusieurs pĂ©riphĂ©riques GPU et simule les ressources des pĂ©riphĂ©riques en tant que threads GPU et mĂ©moire de pĂ©riphĂ©rique, en suivant l'utilisation de la mĂ©moire GPU pour le traitement des demandes. AresDB gĂšre les pĂ©riphĂ©riques GPU via un gestionnaire de pĂ©riphĂ©riques qui modĂ©lise les ressources des pĂ©riphĂ©riques GPU en deux dimensions (threads GPU et mĂ©moire des pĂ©riphĂ©riques) et suit l'utilisation de la mĂ©moire lors du traitement des demandes. AprĂšs avoir compilĂ© la demande, AresDB permet aux utilisateurs d'estimer la quantitĂ© de ressources nĂ©cessaires pour terminer la demande. Les besoins en mĂ©moire du pĂ©riphĂ©rique doivent ĂȘtre satisfaits avant que la demande ne soit rĂ©solue; s'il n'y a actuellement pas assez de mĂ©moire sur un pĂ©riphĂ©rique, la demande doit attendre. Actuellement, AresDB peut exĂ©cuter une ou plusieurs demandes sur le mĂȘme pĂ©riphĂ©rique GPU en mĂȘme temps si le pĂ©riphĂ©rique rĂ©pond Ă  toutes les exigences de ressources.


Dans l'implĂ©mentation actuelle, AresDB ne met pas en cache les entrĂ©es dans la mĂ©moire de l'appareil pour les rĂ©utiliser dans plusieurs requĂȘtes. AresDB vise Ă  prendre en charge les requĂȘtes sur des ensembles de donnĂ©es constamment mis Ă  jour en temps rĂ©el et mal mis en cache correctement. Dans les futures versions d'AresDB, nous avons l'intention d'implĂ©menter des fonctions de mise en cache des donnĂ©es dans la mĂ©moire du GPU, ce qui aidera Ă  optimiser les performances des requĂȘtes.


Exemple d'utilisation: tableau de bord de présentation d'Uber


Chez Uber, nous utilisons AresDB pour créer des tableaux de bord pour obtenir des informations commerciales en temps réel. AresDB est responsable du stockage des événements principaux avec des mises à jour constantes et du calcul des mesures critiques pour eux en une fraction de seconde grùce aux ressources GPU à faible coût, afin que les utilisateurs puissent utiliser les tableaux de bord de maniÚre interactive. Par exemple, les données de voyage anonymisées qui ont une longue période de validité dans l'entrepÎt de données sont mises à jour par plusieurs services, y compris notre systÚme d'expédition, nos systÚmes de paiement et de tarification. Pour utiliser efficacement les données de voyage, les utilisateurs divisent et décomposent les données en différentes dimensions pour mieux comprendre les solutions en temps réel.


Lorsque vous utilisez AresDB, le tableau de bord Uber est un tableau de bord d'analyse répandu qui est utilisé par les équipes de l'entreprise pour produire des mesures pertinentes et des réponses en temps réel pour améliorer l'expérience utilisateur.



14. Uber AresDB .


, , :


( )



( )



AresDB


, , AresDB :



, , , , , .


AresDB , Apache Kafka , , Apache Flink Apache Spark .


AresDB


, « » « ». , -. 24 AQL:



:
, , .



, AresDB , , . AresDB , , .



AresDB Uber , . , , AresDB .


:


  • : AresDB, , , .
  • : AresDB 2018 , , AresDB .
  • : , , , .
  • : , (LLVM) GPU.

AresDB Apache. AresDB .


, .


Remerciements


(Kate Zhang), (Jennifer Anderson), (Nikhil Joshi), (Abhi Khune), (Shengyue Ji), (Chinmay Soman), (Xiang Fu), (David Chen) (Li Ning) , !

Source: https://habr.com/ru/post/fr440072/


All Articles