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.
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) , !