Les coulisses techniques d'Uber

Les coulisses techniques d'Uber Le géant du VTC a opté pour une politique multicloud. Orientée micro-services, son architecture combine de nombreux langages de développement, bases de données, outils...

En huit ans, Uber est devenu la licorne la plus connue au monde. Sa dernière levée de fonds, intervenue en juin 2016, le valorise à 68 milliards de dollars. Ce succès, la plateforme de VTC le doit à une promesse : fournir une voiture avec chauffeur privé en moins de cinq minute, via un smartphone, dans les grandes villes. Pour offrir une expérience utilisateur la plus fluide possible, Uber a cherché à réduire les frictions de son application tout en la simplifiant au maximum. Mais derrière cette quête se cache une rare complexité en termes d'infrastructure.

En juillet dernier, Uber Engineering (le département R&D du transporteur) a dévoilé un certain nombre de ses choix techniques (lire le billet). Uber a notamment choisi de casser son architecture monolithique d'origine pour s'orienter vers un environnement plus flexible composé de centaines de micro-services interagissant entre eux.

Cloud hybride et bases NoSQL

Uber fonctionne sur un modèle de cloud hybride, combinant à la fois à des data centers maison et des infrastructures de cloud public. Dans un article paru il y a an, The Information déclarait que le géant américain faisait monter les enchères entre les grands fournisseurs de cloud que sont Amazon Web Services, Google, Microsoft, IBM et Aliyun (qui n'est autre que la division cloud d'Alibaba).

Plus de 100 milliards de messages échangés quotidiennement entre les différents systèmes

Pour restreindre sa dépendance aux fournisseurs de cloud, Uber se dit "neutre" en termes de clouds publics. Le choix de ces derniers est réalisé en fonction de l'emplacement des centres de données qui doivent se situer aux plus proches des quelque 500 villes couvertes par le service. Les données sont systématiquement répliquées sur un site distant. Pour gérer cette infrastructure multifournisseurs, Uber utilise Terraform, une solution open source dite d'"Infrastructure as code" permettant de faire cohabiter des instances d'AWS ou de Google Cloud Platform et une série d'outils internes.

Uber utilise une base dite "Schemaless" pour le stockage de données de longue durée. Cette infrastructure vient remplacer progressivement les instances MySQL et PostgreSQL utilisées historiquement. Pour répondre à ses exigences de haute disponibilité et de faible latence, le transporteur fait appel aux bases NoSQL Riak et Cassandra. Pour le stockage et l'analyse des données complexes, les ingénieurs d'Uber, basés à Seattle, ont bâti un entrepôt Hadoop. Enfin, ils utilisent la base de données en mémoire Redis et le proxy Twemproxy pour accélérer le requêtage des informations mises en cache.

Pour l'enregistrement des données et leur transfert entre ses différents systèmes, Uber s'appuie sur un bus de messages composé de plusieurs grappes de serveurs Kafka. Il gère plus de 100 milliards de messages par jour pour un volume quotidien supérieur à 100 To. L'ensemble de ces flux sont ingérés en temps réel et indexés via une pile "ELK" - qui combine le moteur de recherche distribué Elasticsearch, l'outil d'extraction, de transformation et de chargement de données (ETL) Logstash, et le visualiseur Kibana.

Des conteneurs Docker 

Pour gérer ses micro-services, Uber se sert de la technologie de conteneurisation Docker et de l'outil open source d'orchestration de conteneurs Mesos. Pour l'exécution automatique de tâches (ou cron jobs), il fait appel à un autre orchestrateur, Apache Aurora (une extension de Mesos). Uber a en outre créé une librairie de "templates" pour automatiser la création de services dans des images Docker.

Pour mettre en musique la couche réseau de son architecture orientée services (SOA), Uber a déployé deux répartiteurs de charge : HAProxy et Hyperbahn - qui, lui, est un outil maison qui a été versé en open source. Autre produit développé en interne, TChannel est un protocole réseau d'appel de procédures (ou RPC) permettant notamment d'acheminer des requêtes "Json over http" vers des services tiers. Dans un récent billet, l'ingénieure Emily Reinhold décrit l'ensemble des outils utilisés par Uber pour découper une API monolithique en une série de micro-services.

A chaque langage, son usage

En termes d'environnements de programmation, les ingénieurs d'Uber ont commencé historiquement par utiliser deux langages. Node.js pour développer la "marketplace" (c'est-à-dire le cœur de l'application) et Python pour les autres services. Depuis, les équipes techniques ont élargi le spectre à Java (notamment dans le cadre du déploiement d'Hadoop) et à Go pour "son efficacité, sa simplicité et sa vitesse d'exécution". Elles ont également recours à C et C ++ pour concevoir des outils maison. Côté front end, les ingénieurs iOS d'Uber privilégient sans surprise les langages Objective C et Swift, tandis que les développeurs Android codent en Java.

Pour l'analyse de code, la documentation ou l'automatisation des processus, Uber s'appuie sur une palette d'outils comme la suite Phabricator et OpenGrok. Pour orchestrer ses projets open source, le groupe passe par la célèbre plateforme d'hébergement de code GitHub. Dans l'optique d'accélérer le passage du développement à la production dans une logique DevOps, Uber fait par ailleurs appel à Jenkins pour l'intégration continue, Clusto pour la gestion de cluster, Puppet pour la gestion de configuration, ou encore Packer, Vagrant, Boto et Unison - pour la gestion de machines virtuelles.

Des outils maison pour le testing et le monitoring

En matière de testing, Uber a développé deux outils : Hailstorm pour les tests d'intégration et de simulation de charge informatique, et uDestroy pour la simulation de pannes. Les demandes de corrections remontent dans Phabricator. En termes d'A/B testing, Uber a recours à la plateforme Morpheus.

Pour monitorer la performance de ses systèmes, Uber passe par l'application Nagios ainsi qu'un outil maison, baptisé M3, qui collecte un certain nombre de métriques sur les serveurs et les applications. Pour visualiser ces données, des tableaux de bord sont générés à partir de la solution open source Grafana qu'Uber a enrichie pour ses propres besoins. Outil de détection d'anomalies développé en interne, Argos analyse, lui, des indicateurs de performance business et les compare à un historique afin de déterminer si le niveau de service correspond aux standards attendus. Il peut, par exemple, détecter que le nombre de déplacements de chauffeurs dans une ville est inférieur à la moyenne.

Une cartographie en temps réel

La cartographie est un élément clé du service de VTC. Les opérateurs locaux d'Uber doivent en effet pouvoir visualiser en temps réel les chauffeurs qui circulent dans leur ville sans avoir à passer par des requêtes SQL fastidieuses. Pour monter ce type de service, Uber s'est appuyé sur un environnement de programmation orienté objet en JavaScript (ES5 et ES6) et sur la bibliothèque JavaScript React. Pour obtenir une cartographie de type heatmap (ou carte thermique) indiquant par zones de couleur la densité de VTC, Uber a développé ses propres outils de visualisation basés sur la technologie web de rendu 3D WebGL.

Uber s'appuie sur le suivi par GPS pour détecter les comportements dangereux au volant

Un autre atout concurrentiel pour Uber, c'est sa capacité à indiquer à un client, avant que la course ne commence, l'heure estimée d'arrivée du chauffeur sur le lieu de prise en charge. Sur la base de cet ETA (Estimated time of arrival), le système d'information d'Uber prend en permanence un grand nombre de décisions - notamment en termes d'allocation de ressources - avec un délai de latence de l'ordre de 5 millisecondes. En 2014, Uber a développé son propre moteur de routage, baptisé Gurafu.

Reposant sur le principe du géocodage inversé, la géolocalisation de l'adresse du point de prélèvement est calculée par Uber en se basant sur la position GPS du smartphone du client. Côté VTC, un moteur de prédiction (basé sur des technologies de machine learning) oriente le chauffeur vers une destination plutôt qu'une autre en fonction notamment d'un historique clients. Enfin, Uber utilise aussi le suivi par GPS pour détecter les comportements dangereux au volant (notamment les excès de vitesse) et améliorer ainsi la sécurité routière.