Un ping vaut mille mots: dans nos notifications contextuelles

Co-écrit par Tom Lai et Bill Cauchois

Une partie de ce qui rend nos applications, Foursquare City Guide et Foursquare Swarm, si pris en charge par nos utilisateurs est la capacité de surprendre et de ravir notre communauté. L'une des nombreuses façons d'y parvenir est de fournir des notifications push opportunes et pertinentes telles que ce qu'il faut faire dans la ville où un utilisateur vient d'atterrir, une suggestion pour découvrir un joyau local dans un nouveau quartier, ou quels endroits un utilisateur pourrait apprécier en fonction sur un aliment pour lequel ils ont manifesté leur intérêt.

Nous envoyons des millions de ces notifications push ou «pings» chaque jour. Bien que nous ayons quelques mécanismes différents pour envoyer des pings basés sur divers déclencheurs (par exemple, lorsqu'un utilisateur a visité un lieu, nous enverrons des recommandations liées à cet endroit), ce message couvrira un système que nous appelons des recommandations push. Ce système génère des pings personnalisés à l'aide de Hadoop MapReduce, puis utilise cette sortie pour fournir des pings intéressants aux utilisateurs à des moments ciblés tout au long de la journée. Passons en revue le backend de cela ensemble.

La vie d'un ping

Le point d'entrée de tout cela est notre trésor de données sur le système de fichiers Hadoop (HDFS). Sur HDFS, nous avons des instantanés nocturnes de nos collections de bases de données ainsi que des données de journal qui sont collectées tout au long de la journée. En utilisant ces sources primaires, nous avons une série de travaux MapReduce «candidats» (écrits en Scalding) qui regroupent toutes ces informations et proposent une liste d'utilisateurs qui, selon nous, pourraient être intéressés par un ping. Chaque poste candidat correspond à un type de recommandation push. Par exemple, il pourrait y en avoir un dédié à la recherche d'utilisateurs qui ont indiqué un intérêt pour un type spécifique de nourriture, comme les hot-dogs ou les boulettes de soupe. Un autre exemple de jeu de candidats serait les utilisateurs qui vivent à proximité d'un restaurant qui a récemment ouvert.

À ce stade du processus, nous avons plusieurs listes d'utilisateurs correspondant à différents types de recommandations push. Comme mentionné précédemment, nous essayons de fournir des recommandations push à des moments précis de la journée. Par exemple, un ping sur les restaurants peut être approprié pour livrer à l'heure du dîner - chaque type de notification push a des dates et heures de livraison optimales. L'étape suivante consiste à convertir le mappage de ➔ [utilisateurs] dans une carte de ➔ [(type ping, utilisateur)]. Lorsque les données sont dans ce dernier format, nous avons un point de départ à partir duquel, étant donné une heure de la journée, nous saurons quels utilisateurs ping avec quel type de recommandation.

Maintenant que nous avons cette liste d'utilisateurs par heure de la journée dans HDFS, le prochain défi consiste à utiliser ces informations pour envoyer des pings en temps opportun. Pour cette tâche, nous devons quitter MapReduce-land et entrer dans le monde de nos microservices. La liste des utilisateurs / recommandations de base est chargée dans notre carquois de système de service à faible latence à partir de laquelle elle sera accessible par les services en ligne. Ensuite, nous avons un processus de planification qui se réveille toutes les heures, lit la liste des utilisateurs pour cette heure et envoie les recommandations push appropriées en utilisant une flotte de travailleurs.

Génération de contenu Ping

Lorsqu'une recommandation push arrive à un travailleur, il reste encore une logique nécessaire pour la convertir en un ping livrable. Souvent, les informations qui arrivent sont rares: juste un ID utilisateur et le type de recommandation que nous souhaitons fournir. Ensuite, nous allons récupérer les enregistrements de données appropriés et créer un message localisé pour l'utilisateur à l'aide de notre infrastructure i18n interne. Nous effectuons également des vérifications supplémentaires pour nous assurer que la recommandation est toujours d'actualité et pertinente.

Nous voulons mettre fin à l'envoi d'un ping pour tout type de raison d'échec. Si la condition préalable réelle dans laquelle nous générons la recommandation n'est plus vraie, par exemple, l'utilisateur n'a pas aimé le lieu pour lequel nous avons généré les recommandations ou le lieu est fermé, nous ne voulons pas envoyer de ping. De plus, nous enregistrons toutes les raisons spécifiques pour lesquelles une recommandation ne peut pas être envoyée, afin que nous puissions diagnostiquer les problèmes avec nos recommandations.

Après avoir généré le contenu ping, il est temps de l'empaqueter et de le livrer à nos utilisateurs. Afin de créer l'expérience la plus attrayante pour nos utilisateurs, nous essayons de rendre des notifications riches chaque fois que possible.

Afin de fournir les notifications les plus riches possibles, nous aurions besoin d'envoyer une tonne de données sur l'appareil de l'utilisateur, ce qui dépasse parfois la limite de données imposée par les plateformes mobiles. Pour contourner cet obstacle, nous enregistrons la charge utile excédentaire dans un cache en ligne et permettons aux appareils des utilisateurs de récupérer les données supplémentaires via un point de terminaison API. Avec notre dernière étape consistant à nous assurer que la sortie a une conception attrayante, le ping atteint enfin l'utilisateur.

Dernières pensées

Dans cet article, nous avons couvert notre pipeline hors ligne qui génère des utilisateurs «candidats» pour recevoir des recommandations push, ainsi que notre système en ligne qui génère des pings pour ces utilisateurs. La structuration du système hors ligne sous la forme d'une série de travaux candidats distincts qui alimentent une jointure centralisée (avec des dépendances modélisées à l'aide de Luigi) a permis à de nombreux ingénieurs de développer indépendamment de nouveaux types de recommandations push. Nous avons également expliqué comment nous développons des mécanismes de bout en bout en ligne pour fournir de manière efficace et fiable des contenus utilisateur agréables.

Si vous êtes intéressé à aider à offrir des expériences utiles aux consommateurs grâce à des données de localisation géo-contextuelles, nous recrutons! N'hésitez pas à consulter également nos projets open source pour un avant-goût de certains des projets impressionnants sur lesquels nous travaillons.