Système d'Orchestration LMVI.IO
Architecture Réelle et Fonctionnement Détaillé pour récuperer les annonces de Meta (Facebook & Instagram) et d'autres régies.
Présentation Générale du Système
Loading...
Le système d'orchestration LMVI représente une solution technique sophistiquée conçue pour surmonter les limitations inhérentes aux APIs publicitaires. Cette architecture avancée permet la gestion efficace de la collecte de données à grande échelle, essentielle pour l'analyse publicitaire multiplateforme.
Une présentation vidéo est disponible pour comprendre visuellement le fonctionnement global du système. Elle illustre les interactions entre les différents composants et les flux de données qui caractérisent cette architecture distribuée.
Aperçu Architectural
LMVI.IO utilise une architecture distribuée qui permet de répartir intelligemment la charge des requêtes API sur l'ensemble de la journée. Cette conception répond aux limitations strictes imposées par les plateformes publicitaires tout en garantissant une collecte de données exhaustive et fiable.
Le système s'appuie sur trois couches de collecte complémentaires qui fonctionnent en synergie pour assurer l'intégrité des données et optimiser l'utilisation des ressources disponibles.
Structure Modulaire du Système
Vue d'ensemble du système réel
Architecture en 3 couches avec orchestration Airflow et base PostgreSQL
Architecture en 3 phases de collecte
Inventory, Compliant et Detail fonctionnant en séquence coordonnée
Base de données PostgreSQL
Système de minutes et stockage optimisé pour le load balancing
PostGraphile & GraphQL
Interface API avec deux mutations distinctes pour les différentes phases
Problématique Réelle de la Collecte Publicitaire
Défis Techniques
  • APIs fortement limitées (75 000 req/jour Facebook, 50 000 TikTok)
  • Risque de perte de données lors du timing variable de découverte
  • Nécessité de scalabilité pour gérer 10 000+ page_ids actifs
  • Exigence d'équilibrage de charge pour éviter les pics d'utilisation API
Solutions Apportées
  • Triple couverture de collecte (Inventory, Compliant, Detail)
  • Répartition sur 1440 minutes (24h) pour distribution optimale
  • Système de Page ID de secours pour prévenir toute perte
  • Load balancing intelligent via db_minutes_load
  • Auto-correction avec réconciliation des données
Architecture Réelle - Trois Systèmes de Collecte
INVENTORY
Découvre les page_ids et attribue les minutes
  • Exécution à 05:05 quotidiennement
  • Recherche avec search: *
  • Collecte de 3 champs seulement (id, page_name, page_id)
COMPLIANT
Sécurité anti-perte avec page_id temporaire
  • Exécution à 06:05 quotidiennement
  • Recherche globale avec search: *
  • Collecte d'un seul champ (id)
  • Utilisation de page_id par défaut si nécessaire
DETAIL
Collecte intensive distribuée sur 24h
  • Exécution à la minute attribuée pour chaque page_id
  • Recherche ciblée par page_id spécifique
  • Collecte complète avec 30+ champs
  • Distribution optimale pour éviter les surcharges API
Cette architecture en trois couches assure une couverture complète tout en optimisant l'utilisation des quotas API disponibles. Les trois collecteurs travaillent en synergie pour garantir l'intégrité des données.
Technologies et Tables Clés
Les tables critiques incluent db_network (réseaux), db_advertiser_id (Page IDs et minutes), db_ad_id (ads individuelles) et db_minutes_load (charge par minute). Cette structure permet une gestion précise et efficace des données publicitaires.
Structure de la Base de Données PostgreSQL
La base de données PostgreSQL constitue le cœur du système LMVI.IO, avec une structure relationnelle optimisée pour la gestion des données publicitaires. Les tables sont conçues pour maintenir l'intégrité référentielle tout en permettant une récupération efficace des informations.
Les relations entre les tables permettent de naviguer facilement des réseaux publicitaires jusqu'aux annonces individuelles, en passant par les annonceurs et leurs attributs spécifiques. Cette conception facilite également le système de distribution temporelle essentiel au bon fonctionnement de la plateforme.
Système de Minutes - Le Cœur du Load Balancing
Table db_minutes_load
CREATE TABLE db_minutes_load ( id_db_network bigint, -- 1=FB, 2=TikTok, 3=Google minute_fetch integer, -- 0 à 1439 (00:00 à 23:59) qty_ad_id_fetchs bigint, -- Charge actuelle is_active boolean );
Cette table contient 1440 slots (un par minute de la journée) pour chaque réseau publicitaire, permettant une distribution optimale des requêtes API sur 24 heures.
Calcul intelligent de minute
La fonction calcul_minute_fetch_from_ad_id() attribue intelligemment une minute optimale à chaque page_id :
  1. Calcul de la minute actuelle + 10 min (sécurité)
  1. Recherche d'une minute disponible au-dessus d'un seuil
  1. Tri par qty_ad_id_fetchs ASC (sélection de la minute la moins chargée)
  1. Sélection et incrémentation du compteur
Résultat : chaque page_id reçoit une minute optimale minimisant les surcharges API.
PostGraphile - Deux Mutations Distinctes
Mutation fUpsertAdvLot (Inventory)
Utilisée par le collecteur Inventory pour traiter les page_ids :
  • Reçoit id, page_name, page_id (3 champs)
  • Calcule une nouvelle minute pour les nouveaux page_id
  • Réutilise la minute existante pour les page_id connus
  • Crée ou met à jour les enregistrements dans db_advertiser_id
Mutation fUpsertAdidLot (Compliant + Detail)
Utilisée par les collecteurs Compliant et Detail :
  • Reçoit id seulement (Compliant) ou id + 30 champs (Detail)
  • Utilise 'AAAAAAAAAAAAAAAAAAAAAAAAAA' comme page_id temporaire si inconnu
  • Implémente la correction automatique lorsque le page_id réel est découvert
  • Assure qu'aucune donnée n'est perdue, même si découverte dans le désordre
Ces deux mutations GraphQL forment l'interface principale pour l'insertion et la mise à jour des données dans le système, avec des mécanismes robustes pour gérer les différents scénarios de collecte.
Gestion des Tokens - Rotation Multi-Réseau
Problème résolu : Limites par réseau
  • Facebook : 75 000 requêtes/jour/token
  • TikTok : 50 000 requêtes/jour/token
  • Google : Variable selon quotas
Sans gestion intelligente des tokens, ces limites deviendraient rapidement un goulot d'étranglement pour la collecte de données à grande échelle.
Solution : Rotation par réseau + usage
-- Fonction z_db_get_best_token_network() SELECT x_id, token, nb_fetch, max_use FROM db_token t INNER JOIN db_network n ON t.id_db_network = n.x_id WHERE n.surname_network = 'FB' -- Spécifique au réseau AND t.status = 'active' AND t.nb_fetch < t.max_use ORDER BY t.nb_fetch ASC, -- Moins utilisé en premier t.last_use ASC -- Plus ancien en priorité LIMIT 1;
Après chaque utilisation, le compteur du token est incrémenté : UPDATE db_token SET nb_fetch = nb_fetch + :count, last_use = NOW() WHERE x_id = :token_id;
Flux Détaillé - Jour 1 d'une Nouvelle Ad
1
05:05 - Inventory découvre nouveau page_id
API Call: search_terms=* fields=id,page_name,page_id
Résultat: page_id 123456789 + ad_id 987654321
Action: Attribution minute 847 (14:07) au page_id
2
06:05 - Compliant scan autonome
API Call: search_terms=* fields=id unmask_removed_content=false
Résultat: Peut découvrir d'autres ads avant inventory
Action: Stockage avec page_id 'AAAAAAAAAAAAAAAAAAAAAAAAAA'
3
14:07 - Detail collect (minute 847)
Requête: SELECT advertiser_id FROM db_advertiser_id WHERE fetch_time_minute = 847
API Call: search_page_ids=123456789 fields=30+_champs
Résultat: Toutes les métriques de ce page_id
Action: Stockage complet des données
Page ID par Défaut - Système Anti-Perte
Problème : Timing de découverte variable
Les annonces publicitaires peuvent être découvertes dans un ordre non prévisible :
  • Scénario A: Inventory trouve d'abord → Processus normal
  • Scénario B: Compliant trouve d'abord → Problème potentiel de perte de données
Sans système de secours, les données découvertes par Compliant avant Inventory pourraient être perdues ou mal associées.
Solution : Page ID temporaire
-- Dans f_upsert_adid_lot ligne 348 : PERFORM f_upsert_adv_unit( v_ad->>'id', -- ad_id trouvé '', -- nom vide 'AAAAAAAAAAAAAAAAAAAAAAAAAA', -- PAGE_ID PAR DÉFAUT ! ... );
Toutes les annonces découvertes par Compliant avant Inventory sont temporairement associées à ce page_id par défaut, garantissant leur stockage.
L'auto-correction intelligente est ensuite appliquée lorsque le véritable page_id est découvert par Inventory, assurant l'intégrité des données sans aucune perte possible.
Configuration Dynamique - Trois Types de Fetch
FB_INVENTORY_CONFIG
Configuration pour la découverte des page_ids :
  • Champs : id, page_name, page_id (3 seulement)
  • Recherche : globale avec search_terms="*"
  • Date : ad_delivery_date_min="$DATENOW-1"
  • Mutation : fUpsertAdvLot
FB_COMPLIANT_CONFIG
Configuration pour le scan de sécurité :
  • Champs : id (1 seul)
  • Recherche : globale avec search_terms="*"
  • Option : unmask_removed_content=false
  • Mutation : fUpsertAdidLot
FB_DETAIL_CONFIG
Configuration pour la collecte détaillée :
  • Champs : 30+ (métriques complètes)
  • Recherche : ciblée par search_page_ids="$advertiser_id"
  • Date : ad_delivery_date_min="$DATENOW-2"
  • Mutation : fUpsertAdidLot
Cette approche de configuration dynamique permet de modifier les paramètres de collecte sans redéploiement du code, offrant une grande flexibilité pour s'adapter aux changements d'API.
Airflow DAGs - Architecture par Régie
Structure modulaire
/dags/facebook/ ├── facebook_fetchs_inventory.py # 05:05 quotidien ├── facebook_fetchs_compliant.py # 06:05 quotidien ├── facebook_fetchs_unit.py # Manuel └── facebook_logic.py # Logique commune /dags/tiktok/ # Structure identique /dags/google/ # Structure identique
Cette organisation modulaire permet une maintenance simplifiée et une isolation claire entre les différentes régies publicitaires.
DAG Detail - Le plus complexe
Le DAG Detail est généré dynamiquement par minute :
# Génération dynamique pour les 1440 minutes for minute in range(1440): # 0 à 1439 # À chaque minute, vérifier s'il y a des page_ids page_ids = query_page_ids_for_minute(minute) if page_ids: # Lancer fetch detail pour ces page_ids fetch_detail_for_page_ids(page_ids)
Cette approche permet d'exécuter les collectes Detail exactement au moment prévu pour chaque page_id, assurant une distribution optimale des requêtes API.
Cas Concret - Page ID 123456789
Jour 1
  • 05:05 → Inventory découvre page_id → Attribution minute 847 (14:07)
  • 06:05 → Compliant scan → Aucun nouvel ID
  • 14:07 → Detail collect → Données complètes récupérées
Jour 2
  • 05:05 → Inventory → Vérification, page_id existe déjà
  • 06:05 → Compliant → Scan de sécurité
  • 14:07 → Detail collect → Mise à jour métriques
Jour 3
  • 05:05 → Inventory → Nouvelle ad 987654322 du même page_id !
  • 06:05 → Compliant → Validation
  • 14:07 → Detail collect → Les 2 ads récupérées ensemble
Répartition dans db_minutes_load :
  • Page_id 123456789 → minute 847 → 14:07 → 7 ads
  • Page_id 555666777 → minute 1203 → 20:03 → 12 ads
  • Page_id 888999000 → minute 127 → 02:07 → 3 ads
Le système assure ainsi une répartition automatique selon la charge, évitant les pics d'utilisation API.
Extensibilité - Ajouter une Nouvelle Régie
1
Module Python
Création d'un nouveau répertoire avec les fichiers nécessaires :
/dags/linkedin/ ├── linkedin_share.py # Constantes adaptées ├── token_utils.py # OAuth2 LinkedIn ├── config_loader.py # Configuration ├── linkedin_logic.py # Logique principale └── linkedin_logic_unitaire.py
2
DAGs Airflow
Création des 3 DAGs avec la même structure que les régies existantes :
  • linkedin_fetchs_inventory.py
  • linkedin_fetchs_compliant.py
  • linkedin_fetchs_detail.py
3
Configuration PostgreSQL
Insertion du nouveau réseau et des paramètres de configuration :
INSERT INTO db_network (surname_network) VALUES ('LINKEDIN'); INSERT INTO tb_config_params VALUES ('LINKEDIN_INVENTORY_CONFIG', '{ API config }'), ('LINKEDIN_COMPLIANT_CONFIG', '{ API config }'), ('LINKEDIN_DETAIL_CONFIG', '{ API config }');
4
Minutes load
Génération automatique des 1440 slots pour le nouveau réseau :
INSERT INTO db_minutes_load (id_db_network, minute_fetch, qty_ad_id_fetchs) SELECT 4, minute, 0 FROM generate_series(0, 1439) minute;
Avantages Techniques Réels
Performance
  • Répartition optimale sans pic API
  • Load balancing intelligent 24h/7j
  • Distribution intelligente des requêtes
Maintenance
  • Configuration dynamique sans redéploiement
  • Modulaire avec chaque réseau indépendant
  • Traçabilité complète dans CouchDB
Scalabilité
  • Extension horizontale pour ajouter de nouveaux réseaux
  • Augmentation verticale des slots de minutes si besoin
  • Gestion de milliers de page_ids simultanément
Fiabilité
  • Auto-réparation avec correction page_id automatique
  • Triple couverture de découverte
  • Aucune perte grâce au page_id par défaut
  • Monitoring intégré en temps réel
Foire Aux Questions
Que se passe-t-il si une minute est surchargée ?
Le système sélectionne automatiquement la minute suivante la moins chargée, garantissant une répartition optimale même en cas de forte charge.
Comment gérer les fuseaux horaires ?
Tout est en UTC. Les minutes sont absolues depuis minuit UTC, assurant une cohérence globale indépendamment de l'emplacement des serveurs ou des utilisateurs.
Peut-on forcer une minute spécifique ?
Non, le load balancing est automatique pour optimiser la répartition. Forcer une minute spécifique compromettrait l'équilibrage de charge du système.
Que devient un page_id sans ads actives ?
Il conserve sa minute attribuée mais ne sera plus interrogé par le fetch detail, préservant ainsi les ressources API pour les page_ids actifs.
Pour déboguer un problème de collecte, suivez cette méthodologie :
  1. Vérifier la minute attribuée au page_id dans la base de données
  1. Consulter les logs du DAG à cette heure précise
  1. Tester la requête API manuellement pour identifier d'éventuelles erreurs
  1. Vérifier le statut des tokens utilisés pour les requêtes
Ressources et Documentation
Documentation technique
  • Formation complète : FORMATION_ORCHESTRATION_LMVI.md
  • Flux détaillé : theRealStoryOfANewIdFromAPageId_FINAL.md
  • Template nouveau réseau : TEMPLATE_INTEGRATION_NOUVELLE_REGIE.md
Outils de développement
  • GraphQL Playground : https://graphile-11.lmvi.io/graphql
  • Airflow UI : http://localhost:8080
  • pgAdmin : Interface base de données
  • CouchDB Fauxton : http://localhost:5984/_utils
Contacts équipe
Pour toute question technique ou assistance, n'hésitez pas à contacter :
  • Architecture : [Lead Architect]
  • DevOps : [DevOps Engineer]
  • Support : [Support Team]
Conclusion
3
Systèmes de collecte
Inventory, Compliant et Detail fonctionnant en synergie pour une couverture complète
1440
Minutes de distribution
Répartition optimale sur 24h pour maximiser l'utilisation des quotas API
0
Perte de données
Aucune perte grâce au système anti-perte et à la triple couverture
Le système d'orchestration LMVI.IO représente une solution technique sophistiquée pour surmonter les limitations des APIs publicitaires. Son architecture distribuée, ses mécanismes de sécurité et sa capacité d'auto-correction en font une plateforme robuste pour la collecte de données à grande échelle.
Pour toute question supplémentaire ou pour une démonstration pratique du système, n'hésitez pas à contacter l'équipe technique.