Chez Glean, nous explorons chaque jour des corpus de centaines de millions de documents. Une fois tous ces documents explorés, nous devons nous assurer qu'ils sont constamment analysés et traités afin de maintenir à jour leur contenu, leurs autorisations et leurs statistiques, et ainsi offrir la meilleure expérience de recherche possible.
L'exécution d'un travail par lots à cette fin était coûteuse, fragile et difficile à intégrer avec MySQL. Avec un travail en streaming, en revanche, nous avons pu retraiter chaque document au moins une fois par jour. Dans cet article de blog, nous décrivons comment nous y sommes parvenus à l'aide de Cloud SQL (MySQL) et d'Apache Beam sur Google Cloud Dataflow. Tous les pipelines décrits ci-après utilisent une configuration à worker unique et multi-cœurs sur Google Cloud Platform (GCP), qui offre une évolutivité verticale massive, suffisante pour nos cas d'usage.
Lors de l'exploration d'un nouveau document, le contenu brut est écrit dans une table MySQL. Nous maintenons également une file d'attente Pub/Sub qui est notifiée de l'identifiant unique du document nouvellement exploré. Ce document doit être traité pour analyser et extraire des informations structurées, qui sont réécrites dans la même table MySQL et indexées par notre système de recherche. La file d'attente Pub/Sub garantit que cela se fait en temps réel. Les documents doivent également être retraités périodiquement pour gérer les événements éventuellement perdus par la file d'attente Pub/Sub et pour recalculer toutes les statistiques qui évoluent à mesure que le corpus se transforme au fil du temps. Cela est réalisé en analysant et en retraitant en continu les données de la table MySQL. Dans la suite de cet article de blog, nous nous concentrerons principalement sur la manière dont le système lit et traite les données de MySQL.
Pour lire les documents de la table MySQL, nous utilisons un pipeline en streaming. Deux facteurs principaux ont motivé notre choix du streaming plutôt que du traitement par lots : l'évolutivité et le coût. Avec un corpus en constante croissance, un travail par lots hebdomadaire n'était pas évolutif, et l'utilisation d'un pipeline en streaming nous a permis de traiter chaque document au moins une fois par jour. Une part importante de cet avantage en termes de coût provient du fait que nous devions déjà maintenir un pipeline en streaming pour gérer la file d'attente Pub/Sub. Ces machines étaient sous-utilisées et pouvaient donc être exploitées pour effectuer une analyse en streaming de la base de données MySQL sans coût supplémentaire.


Pour mettre en place un pipeline en streaming (voir Figure 1), nous utilisons Apache Beam avec l'exécuteur Google Cloud Dataflow. Nous définissons une UnboundedSource personnalisée, dont chaque instance crée un UnboundedReader personnalisé qui interroge un cache de documents pour récupérer le prochain document à traiter. Ce cache de documents est maintenu par une instance statique d'un objet scanner. Plusieurs lectures parallèles de la base de données sont émises par ce scanner vers la table MySQL en fonction du nombre de cœurs du worker utilisé. Ces lectures récupèrent les documents par lots ordonnés par identifiant de document, afin de garantir que chaque document soit traité au plus une fois lors de chaque analyse complète du corpus. Avec cette configuration, nous atteignons des taux de traitement de l'ordre de centaines de documents par seconde sur un seul cœur (voir Figure 2).
Le scanner suit également l'état du cache : l'identifiant du dernier document lu, le nombre de documents restants dans le cache, etc. Il s'en sert pour déterminer quand récupérer des documents supplémentaires, ainsi que pour déterminer quand une analyse complète du corpus est terminée. Il réinitialise ensuite son état et recommence à analyser le corpus depuis le début. Ainsi, cela met en place une file d'attente infinie de données pour notre pipeline en streaming.
Cette conception et ce processus d'optimisations nous ont permis de garantir évolutivité et rentabilité, de nos plus petits à nos plus grands clients. Nous itérons en permanence pour nous assurer que nos utilisateurs puissent trouver les documents dont ils ont besoin, au moment où ils en ont besoin, pour accomplir leur travail.
Nous entrerons dans les détails des requêtes SQL supplémentaires et des optimisations dans un prochain article de blog, alors restez à l'écoute ! Si cet article de blog vous a intéressé et que vous souhaitez travailler sur de tels systèmes, contactez-nous !






