Cum am colectat date despre campaniile de publicitate de pe site-urile online (calea spinoasă către produs)

Se pare că domeniul publicității online ar trebui să fie cât mai avansat și automatizat din punct de vedere tehnologic. Desigur, pentru că astfel de giganți și experți în domeniul lor precum Yandex, Mail.Ru, Google și Facebook lucrează acolo. Dar, după cum s-a dovedit, nu există nicio limită pentru perfecțiune și întotdeauna există ceva de automatizat.

Cum am colectat date despre campaniile de publicitate de pe site-urile online (calea spinoasă către produs)
Sursă

Grupul de comunicare Dentsu Aegis Network Rusia este cel mai mare jucător de pe piața de publicitate digitală și investește activ în tehnologie, încercând să-și optimizeze și să automatizeze procesele de afaceri. Una dintre problemele nerezolvate ale pieței de publicitate online este sarcina de a colecta statistici privind campaniile de publicitate de pe diferite platforme de internet. Soluția la această problemă a avut ca rezultat crearea unui produs D1.Digital (a se citi DiVan), despre a cărui dezvoltare vrem să vorbim.

De ce?

1. La momentul demarării proiectului nu exista pe piață un singur produs gata făcut care să rezolve problema automatizării colectării statisticilor privind campaniile publicitare. Aceasta înseamnă că nimeni, în afară de noi înșine, nu ne va satisface nevoile.

Servicii precum Improvado, Roistat, Supermetrics, SegmentStream oferă integrare cu platforme, rețele sociale și Google Analitycs și, de asemenea, fac posibilă construirea de tablouri de bord analitice pentru analiza și controlul convenabil al campaniilor publicitare. Înainte de a începe dezvoltarea produsului nostru, am încercat să folosim unele dintre aceste sisteme pentru a colecta date de pe site-uri, dar, din păcate, nu au putut rezolva problemele noastre.

Problema principală a fost că produsele testate se bazau pe surse de date, afișând statistici de plasare pe site și nu oferă posibilitatea de a agrega statistici privind campaniile publicitare. Această abordare nu ne-a permis să vedem statistici de pe diferite site-uri într-un singur loc și să analizăm starea campaniei în ansamblu.

Un alt factor a fost acela că în fazele inițiale produsele erau orientate spre piața occidentală și nu au susținut integrarea cu site-urile rusești. Iar pentru acele site-uri cu care a fost implementată integrarea, toate metricile necesare nu au fost întotdeauna descărcate cu suficient detaliu, iar integrarea nu a fost întotdeauna convenabilă și transparentă, mai ales când a fost necesar să obținem ceva care nu se află în interfața sistemului.
În general, am decis să nu ne adaptăm la produse terțe, ci am început să dezvoltăm propriile noastre...

2. Piața de publicitate online este în creștere de la an la an, iar în 2018, din punct de vedere al bugetelor de publicitate, a depășit cea mai mare piață de publicitate TV în mod tradițional. Deci există o scară.

3. Spre deosebire de piața de publicitate TV, unde vânzarea de publicitate comercială este monopolizată, există o mulțime de proprietari individuali de inventar publicitar de diferite dimensiuni care operează pe Internet cu propriile conturi de publicitate. Deoarece o campanie de publicitate, de regulă, rulează pe mai multe site-uri simultan, pentru a înțelege starea campaniei de publicitate, este necesar să colectați rapoarte de pe toate site-urile și să le combinați într-un singur raport mare, care va arăta întreaga imagine. Aceasta înseamnă că există potențial de optimizare.

4. Ni s-a părut că proprietarii de inventar publicitar pe Internet au deja infrastructura pentru colectarea statisticilor și afișarea lor în conturile de publicitate și vor putea furniza un API pentru aceste date. Aceasta înseamnă că este posibil din punct de vedere tehnic să o implementăm. Să spunem imediat că s-a dovedit a nu fi atât de simplu.

În general, toate condițiile prealabile pentru implementarea proiectului ne-au fost evidente și am alergat să aducem proiectul la viață...

Plan măreț

Pentru început, ne-am format o viziune asupra unui sistem ideal:

  • Campaniile de publicitate din sistemul corporativ 1C ar trebui să fie încărcate automat în acesta cu numele, perioadele, bugetele și destinațiile de plasare pe diferite platforme.
  • Pentru fiecare plasare din cadrul unei campanii de publicitate, toate statisticile posibile ar trebui să fie descărcate automat de pe site-urile pe care are loc plasarea, cum ar fi numărul de afișări, clicuri, vizionări etc.
  • Unele campanii de publicitate sunt urmărite utilizând monitorizarea terțelor părți prin așa-numitele sisteme de adserving precum Adriver, Weborama, DCM etc. Există și un contor de internet industrial în Rusia - compania Mediascope. Conform planului nostru, datele din monitorizarea independentă și industrială ar trebui, de asemenea, să fie încărcate automat în campaniile de publicitate corespunzătoare.
  • Majoritatea campaniilor de publicitate de pe Internet vizează anumite acțiuni țintă (cumpărare, apelare, înscriere pentru un test drive etc.), care sunt urmărite folosind Google Analytics, iar statisticile pentru care sunt, de asemenea, importante pentru înțelegerea stării campaniei și ar trebui să fie încărcat în instrumentul nostru.

Mai întâi nenorocitule

Având în vedere angajamentul nostru față de principiile flexibile ale dezvoltării software (agile, toate lucrurile), am decis să dezvoltăm mai întâi un MVP și apoi să ne îndreptăm spre obiectivul dorit în mod iterativ.
Am decis să construim MVP pe baza produsului nostru DANBo (Dentsu Aegis Network Board), care este o aplicație web cu informații generale despre campaniile publicitare ale clienților noștri.

Pentru MVP, proiectul a fost simplificat pe cât posibil din punct de vedere al implementării. Am selectat o listă limitată de platforme pentru integrare. Acestea au fost principalele platforme, cum ar fi Yandex.Direct, Yandex.Display, RB.Mail, MyTarget, Adwords, DBM, VK, FB și principalele sisteme de publicitate Adriver și Weborama.

Pentru a accesa statisticile de pe site-uri prin intermediul API-ului, am folosit un singur cont. Un manager de grup de clienți care dorea să folosească colectarea automată a statisticilor asupra unei campanii de publicitate a trebuit mai întâi să delege accesul la campaniile publicitare necesare de pe site-uri în contul platformei.

Următorul este utilizatorul sistemului DANBo trebuia să încarce în sistemul Excel un fișier cu un anumit format, care conținea toate informațiile despre plasare (campanie publicitară, platformă, format, perioada de plasare, indicatori planificați, buget etc.) și identificatorii campaniilor de publicitate corespunzătoare pe site-uri și contoare în sistemele de anunțuri.

Arăta, sincer, terifiant:

Cum am colectat date despre campaniile de publicitate de pe site-urile online (calea spinoasă către produs)

Datele descărcate au fost salvate într-o bază de date, iar apoi serviciile separate au colectat identificatori de campanie pe site-uri de pe acestea și au descărcat statistici despre acestea.

Pentru fiecare site, a fost scris un serviciu Windows separat, care o dată pe zi trecea sub un cont de serviciu în API-ul site-ului și descărca statistici pentru ID-urile de campanie specificate. Același lucru s-a întâmplat cu sistemele de anunțuri.

Datele descărcate au fost afișate pe interfață sub forma unui mic tablou de bord personalizat:

Cum am colectat date despre campaniile de publicitate de pe site-urile online (calea spinoasă către produs)

În mod neașteptat pentru noi, MVP a început să lucreze și a început să descarce statistici actuale despre campaniile de publicitate de pe Internet. Am implementat sistemul pe mai mulți clienți, dar când am încercat să scalam, am întâmpinat probleme serioase:

  • Problema principală a fost complexitatea pregătirii datelor pentru încărcare în sistem. De asemenea, datele de plasare trebuiau convertite într-un format strict fix înainte de încărcare. A fost necesar să se includă în fișierul de descărcare identificatori de entități de pe site-uri diferite. Ne confruntăm cu faptul că este foarte dificil pentru utilizatorii nepregătiți din punct de vedere tehnic să explice unde pot găsi acești identificatori pe site și unde în fișier trebuie introduși. Având în vedere numărul de angajați din departamentele care desfășoară campanii pe site-uri și cifra de afaceri, acest lucru a dus la un sprijin uriaș din partea noastră, de care nu am fost absolut mulțumiți.
  • O altă problemă a fost că nu toate platformele de publicitate au avut mecanisme de delegare a accesului la campaniile publicitare către alte conturi. Dar chiar dacă era disponibil un mecanism de delegare, nu toți agenții de publicitate erau dispuși să acorde acces la campaniile lor conturilor terță parte.
  • Un factor important a fost indignarea care a stârnit în rândul utilizatorilor de faptul că toți indicatorii planificați și detaliile de plasare pe care le introduc deja în sistemul nostru de contabilitate 1C, trebuie să reintră în DANBo.

Acest lucru ne-a dat ideea că sursa principală de informații despre plasare ar trebui să fie sistemul nostru 1C, în care toate datele sunt introduse cu acuratețe și la timp (ici este că facturile sunt generate pe baza datelor 1C, deci introducerea corectă a datelor în 1C este o prioritate pentru toată lumea KPI). Așa a apărut un nou concept de sistem...

Concept

Primul lucru pe care am decis să-l facem a fost să separăm sistemul de colectare a statisticilor privind campaniile publicitare de pe Internet într-un produs separat - D1.Digital.

În noul concept, am decis să ne încărcăm în D1.Digital informații despre campaniile publicitare și destinațiile de plasare din cadrul acestora din 1C, apoi extrageți statistici de pe site-uri și sisteme de AdServing către aceste destinații de plasare. Acest lucru trebuia să simplifice semnificativ viața utilizatorilor (și, ca de obicei, să adauge mai multă muncă dezvoltatorilor) și să reducă cantitatea de asistență.

Prima problemă pe care am întâlnit-o a fost de natură organizatorică și a fost legată de faptul că nu am putut găsi o cheie sau semn prin care să putem compara entități din diferite sisteme cu campanii și plasamente din 1C. Cert este că procesul din compania noastră este conceput în așa fel încât campaniile de publicitate să fie introduse în sisteme diferite de către diferiți oameni (planificatori media, cumpărături etc.).

Pentru a rezolva această problemă, a trebuit să inventăm o cheie hashed unică, DANBoID, care să lege între ele entitățile din diferite sisteme și care ar putea fi identificată destul de ușor și unic în seturile de date descărcate. Acest identificator este generat în sistemul intern 1C pentru fiecare destinație de plasare individuală și este transferat în campanii, destinații de plasare și contoare de pe toate site-urile și în toate sistemele AdServing. Implementarea practicii de a pune DANBoID în toate plasamentele a durat ceva timp, dar am reușit să o facem :)

Apoi am aflat că nu toate site-urile au un API pentru colectarea automată a statisticilor, iar chiar și cele care au un API, acesta nu returnează toate datele necesare.

În această etapă, am decis să reducem semnificativ lista de platforme pentru integrare și să ne concentrăm pe principalele platforme care sunt implicate în marea majoritate a campaniilor de publicitate. Această listă include toți cei mai mari jucători de pe piața de publicitate (Google, Yandex, Mail.ru), rețelele sociale (VK, Facebook, Twitter), sistemele majore de AdServing și de analiză (DCM, Adriver, Weborama, Google Analytics) și alte platforme.

Majoritatea site-urilor pe care le-am selectat aveau un API care ne furniza valorile de care aveam nevoie. În cazurile în care nu exista API sau nu conținea datele necesare, am folosit rapoarte trimise zilnic pe e-mailul biroului nostru pentru a încărca date (în unele sisteme este posibil să se configureze astfel de rapoarte, în altele am convenit asupra dezvoltării unor astfel de rapoarte pentru noi).

La analizarea datelor de pe site-uri diferite, am aflat că ierarhia entităților nu este aceeași în sisteme diferite. Mai mult, informațiile trebuie descărcate în diferite detalii din diferite sisteme.

Pentru a rezolva această problemă, a fost dezvoltat conceptul SubDANBoID. Ideea de SubDANBoID este destul de simplă, marchem principala entitate a campaniei pe site cu DANBoID generat și încărcăm toate entitățile imbricate cu identificatori unici de site și formăm SubDANBoID conform principiului DANBoID + identificatorul de primul nivel. entitate imbricată + identificatorul entității imbricate de nivel al doilea +... Această abordare ne-a permis să conectăm campanii de publicitate în diferite sisteme și să descarcăm statistici detaliate despre acestea.

A trebuit să rezolvăm și problema accesului la campanii pe diferite platforme. După cum am scris mai sus, mecanismul de delegare a accesului la o campanie către un cont tehnic separat nu este întotdeauna aplicabil. Prin urmare, a trebuit să dezvoltăm o infrastructură pentru autorizarea automată prin OAuth folosind token-uri și mecanisme de actualizare a acestor token-uri.

Mai târziu în articol vom încerca să descriem mai detaliat arhitectura soluției și detaliile tehnice ale implementării.

Arhitectura soluției 1.0

Când am început implementarea unui nou produs, am înțeles că trebuie imediat să asigurăm posibilitatea conectării de noi site-uri, așa că am decis să mergem pe calea arhitecturii microservicii.

La proiectarea arhitecturii, am separat conectorii la toate sistemele externe - 1C, platforme de publicitate și sisteme de publicitate - în servicii separate.
Ideea principală este că toți conectorii la site-uri au același API și sunt adaptoare care aduc API-ul site-ului la o interfață convenabilă pentru noi.

În centrul produsului nostru se află o aplicație web, care este un monolit care este proiectat în așa fel încât să poată fi dezasamblat cu ușurință în servicii. Această aplicație este responsabilă pentru procesarea datelor descărcate, culegerea statisticilor din diferite sisteme și prezentarea acestora utilizatorilor sistemului.

Pentru a comunica între conectori și aplicația web, a trebuit să creăm un serviciu suplimentar, pe care l-am numit Connector Proxy. Îndeplinește funcțiile Service Discovery și Task Scheduler. Acest serviciu execută sarcini de colectare a datelor pentru fiecare conector în fiecare noapte. Scrierea unui nivel de servicii a fost mai ușor decât conectarea unui broker de mesaje și pentru noi a fost important să obținem rezultatul cât mai repede posibil.

Pentru simplitate și viteza de dezvoltare, am decis, de asemenea, că toate serviciile vor fi API-uri web. Acest lucru a făcut posibilă asamblarea rapidă a unei probe de concept și verificarea faptului că întregul proiect funcționează.

Cum am colectat date despre campaniile de publicitate de pe site-urile online (calea spinoasă către produs)

O sarcină separată, destul de complexă, a fost configurarea accesului pentru a colecta date din diferite conturi, care, după cum am decis, ar trebui să fie efectuate de utilizatori prin interfața web. Acesta constă din doi pași separați: mai întâi, utilizatorul adaugă un token pentru a accesa contul prin OAuth și apoi configurează colectarea de date pentru client dintr-un anumit cont. Obținerea unui token prin OAuth este necesară deoarece, așa cum am scris deja, nu este întotdeauna posibilă delegarea accesului la contul dorit de pe site.

Pentru a crea un mecanism universal pentru selectarea unui cont de pe site-uri, a trebuit să adăugăm la API-ul conectorilor o metodă care returnează schema JSON, care este redată într-un formular folosind o componentă JSONEditor modificată. În acest fel, utilizatorii au putut selecta conturile din care să descarce datele.

Pentru a respecta limitele de solicitare care există pe site-uri, combinăm solicitările de setări într-un singur token, dar putem procesa diferite token-uri în paralel.

Am ales MongoDB ca stocare pentru datele încărcate atât pentru aplicația web, cât și pentru conectori, ceea ce ne-a permis să nu ne îngrijorăm prea mult cu privire la structura datelor în fazele inițiale de dezvoltare, când modelul obiect al aplicației se schimbă din două în două zile.

Am aflat curând că nu toate datele se potrivesc bine în MongoDB și, de exemplu, este mai convenabil să stocați statisticile zilnice într-o bază de date relațională. Prin urmare, pentru conectorii a căror structură de date este mai potrivită pentru o bază de date relațională, am început să folosim PostgreSQL sau MS SQL Server ca stocare.

Arhitectura și tehnologiile alese ne-au permis să construim și să lansăm produsul D1.Digital relativ rapid. Pe parcursul a doi ani de dezvoltare a produsului, am dezvoltat 23 de conectori la site-uri, am câștigat o experiență neprețuită de lucru cu API-uri terțe, am învățat să evităm capcanele diferitelor site-uri, care aveau fiecare site-uri, au contribuit la dezvoltarea API-ului a cel puțin 3. site-uri, au descărcat automat informații despre aproape 15 de campanii și pentru peste 000 de plasări, au colectat o mulțime de feedback de la utilizatori cu privire la funcționarea produsului și au reușit să schimbe de mai multe ori procesul principal al produsului, pe baza acestui feedback.

Arhitectura soluției 2.0

Au trecut doi ani de la începutul dezvoltării D1.Digital. Creșterea constantă a încărcării sistemului și apariția a tot mai multe surse de date noi au dezvăluit treptat probleme în arhitectura soluției existente.

Prima problemă este legată de cantitatea de date descărcate de pe site-uri. Ne-am confruntat cu faptul că colectarea și actualizarea tuturor datelor necesare de pe cele mai mari site-uri a început să dureze prea mult timp. De exemplu, colectarea datelor din sistemul de difuzare a anunțurilor AdRiver, cu ajutorul căruia urmărim statistici pentru majoritatea destinațiilor de plasare, durează aproximativ 12 ore.

Pentru a rezolva această problemă, am început să folosim tot felul de rapoarte pentru a descărca date de pe site-uri, încercăm să dezvoltăm API-ul acestora împreună cu site-urile astfel încât viteza de funcționare a acesteia să răspundă nevoilor noastre și să paralelizăm cât mai mult descărcarea datelor.

O altă problemă se referă la procesarea datelor descărcate. Acum, când sosesc noi statistici de plasare, este lansat un proces în mai multe etape de recalculare a valorilor, care include încărcarea datelor brute, calcularea valorilor agregate pentru fiecare site, compararea datelor din diferite surse între ele și calcularea valorilor rezumative pentru campanie. Acest lucru determină o încărcare mare a aplicației web care face toate calculele. De câteva ori, în timpul procesului de recalculare, aplicația a consumat toată memoria de pe server, aproximativ 10-15 GB, ceea ce a avut cel mai dăunător efect asupra lucrului utilizatorilor cu sistemul.

Problemele identificate și planurile ambițioase de dezvoltare ulterioară a produsului ne-au condus la necesitatea reconsiderării arhitecturii aplicației.

Am început cu conectori.
Am observat că toți conectorii funcționează după același model, așa că am construit un cadru pipeline în care pentru a crea un conector trebuia doar să programați logica pașilor, restul era universal. Dacă un conector necesită îmbunătățire, îl transferăm imediat într-un cadru nou, în același timp în care conectorul este îmbunătățit.

În același timp, am început să implementăm conectori pentru Docker și Kubernetes.
Am planificat mutarea la Kubernetes destul de mult timp, am experimentat cu setările CI/CD, dar am început să ne mișcăm doar atunci când un conector, din cauza unei erori, a început să consume mai mult de 20 GB de memorie pe server, ucigând practic alte procese. . În timpul investigației, conectorul a fost mutat într-un cluster Kubernetes, unde a rămas în cele din urmă, chiar și după ce eroarea a fost remediată.

Destul de repede ne-am dat seama că Kubernetes este convenabil și în șase luni am transferat 7 conectori și Connectors Proxy, care consumă cele mai multe resurse, către clusterul de producție.

În urma conectorilor, am decis să schimbăm arhitectura restului aplicației.
Problema principală a fost că datele vin de la conectori la proxy în loturi mari, apoi lovesc DANBoID și sunt trimise la aplicația web centrală pentru procesare. Datorită numărului mare de recalculări de metrici, aplicația are o sarcină mare.

De asemenea, s-a dovedit destul de dificil să monitorizezi starea lucrărilor individuale de colectare a datelor și să raportezi erorile apărute în conectori către o aplicație web centrală, astfel încât utilizatorii să poată vedea ce se întâmplă și de ce nu se colectează datele.

Pentru a rezolva aceste probleme, am dezvoltat arhitectura 2.0.

Principala diferență dintre noua versiune a arhitecturii este că, în loc de API-ul Web, folosim RabbitMQ și biblioteca MassTransit pentru a face schimb de mesaje între servicii. Pentru a face acest lucru, a trebuit să rescriem aproape complet Connectors Proxy, făcându-l Connectors Hub. Denumirea a fost schimbată deoarece rolul principal al serviciului nu mai este în transmiterea cererilor către conectori și înapoi, ci în gestionarea colecției de metrici de la conectori.

Din aplicația web centrală, am separat informațiile despre plasări și statistici de pe site-uri în servicii separate, ceea ce a făcut posibil să scăpăm de recalculări inutile și să stocăm doar statistici deja calculate și agregate la nivel de plasare. De asemenea, am rescris și optimizat logica pentru calcularea statisticilor de bază pe baza datelor brute.

În același timp, migrăm toate serviciile și aplicațiile către Docker și Kubernetes pentru a face soluția mai ușor de scalat și mai convenabil de gestionat.

Cum am colectat date despre campaniile de publicitate de pe site-urile online (calea spinoasă către produs)

Unde suntem acum

Produs cu arhitectură 2.0 dovadă de concept D1.Digital gata și lucrează într-un mediu de testare cu un set limitat de conectori. Tot ce rămâne de făcut este să rescrieți alți 20 de conectori pe o nouă platformă, să testați dacă datele sunt încărcate corect și că toate valorile sunt calculate corect și să lansați întregul design în producție.

De fapt, acest proces se va întâmpla treptat și va trebui să părăsim compatibilitatea cu vechile API-uri pentru a menține totul să funcționeze.

Planurile noastre imediate includ dezvoltarea de noi conectori, integrarea cu noi sisteme și adăugarea de valori suplimentare la setul de date descărcate de pe site-urile conectate și sistemele de adserving.

De asemenea, intenționăm să transferăm toate aplicațiile, inclusiv aplicația web centrală, în Docker și Kubernetes. Combinat cu noua arhitectură, acest lucru va simplifica semnificativ implementarea, monitorizarea și controlul resurselor consumate.

O altă idee este de a experimenta alegerea bazei de date pentru stocarea statisticilor, care este stocată în prezent în MongoDB. Am transferat deja câțiva conectori noi la bazele de date SQL, dar acolo diferența este aproape de neobservat, iar pentru statisticile agregate pe zi, care pot fi solicitate pentru o perioadă arbitrară, câștigul poate fi destul de serios.

În general, planurile sunt grandioase, să mergem mai departe :)

Autorii articolului R&D Dentsu Aegis Network Russia: Georgy Ostapenko (shmiigaa), Mihail Kotsik (hitexx)

Sursa: www.habr.com

Adauga un comentariu