Cómo recopilamos datos sobre campañas publicitarias de sitios en línea (el espinoso camino hacia el producto)

Parece que el campo de la publicidad online debería ser lo más avanzado tecnológicamente y automatizado posible. Por supuesto, porque allí trabajan gigantes y expertos en su campo como Yandex, Mail.Ru, Google y Facebook. Pero resultó que no hay límites para la perfección y siempre hay algo que automatizar.

Cómo recopilamos datos sobre campañas publicitarias de sitios en línea (el espinoso camino hacia el producto)
fuente

grupo de comunicaciones Red Dentsu Aegis Rusia es el actor más grande en el mercado de la publicidad digital y está invirtiendo activamente en tecnología, tratando de optimizar y automatizar sus procesos comerciales. Uno de los problemas no resueltos del mercado de la publicidad online es la tarea de recopilar estadísticas sobre las campañas publicitarias de diferentes plataformas de Internet. La solución a este problema finalmente resultó en la creación de un producto. D1.Digital (léase DiVan), de cuyo desarrollo queremos hablar.

¿Por qué?

1. En el momento del inicio del proyecto, no existía en el mercado ni un solo producto preparado que resolviera el problema de automatizar la recopilación de estadísticas sobre campañas publicitarias. Esto significa que nadie excepto nosotros mismos podrá satisfacer nuestras necesidades.

Servicios como Improvado, Roistat, Supermetrics, SegmentStream ofrecen integración con plataformas, redes sociales y Google Analitycs, y también permiten crear paneles analíticos para un análisis y control convenientes de las campañas publicitarias. Antes de comenzar a desarrollar nuestro producto, intentamos utilizar algunos de estos sistemas para recopilar datos de los sitios, pero, desafortunadamente, no pudieron resolver nuestros problemas.

El principal problema fue que los productos probados se basaban en fuentes de datos, mostraban estadísticas de ubicación por sitio y no ofrecían la posibilidad de agregar estadísticas sobre campañas publicitarias. Este enfoque no nos permitió ver estadísticas de diferentes sitios en un solo lugar y analizar el estado de la campaña en su conjunto.

Otro factor fue que en las etapas iniciales los productos estaban dirigidos al mercado occidental y no soportaban la integración con sitios rusos. Y para aquellos sitios con los que se implementó la integración, no siempre se descargaron todas las métricas necesarias con suficiente detalle, y la integración no siempre fue conveniente y transparente, especialmente cuando era necesario obtener algo que no está en la interfaz del sistema.
En general, decidimos no adaptarnos a productos de terceros, sino que comenzamos a desarrollar los nuestros propios...

2. El mercado de la publicidad online crece año tras año y en 2018, en términos de presupuestos publicitarios, superó al mercado de publicidad televisiva tradicionalmente más grande. Entonces hay una escala.

3. A diferencia del mercado de publicidad televisiva, donde la venta de publicidad comercial está monopolizada, hay muchos propietarios individuales de inventario publicitario de diversos tamaños que operan en Internet con sus propias cuentas publicitarias. Dado que una campaña publicitaria, por regla general, se ejecuta en varios sitios a la vez, para comprender el estado de la campaña publicitaria, es necesario recopilar informes de todos los sitios y combinarlos en un informe grande que mostrará la imagen completa. Esto significa que existe potencial de optimización.

4. Nos pareció que los propietarios de inventario publicitario en Internet ya cuentan con la infraestructura para recopilar estadísticas y mostrarlas en cuentas publicitarias, y podrán proporcionar una API para estos datos. Esto significa que es técnicamente posible implementarlo. Digamos de inmediato que resultó no ser tan simple.

En general, todos los requisitos previos para la implementación del proyecto eran obvios para nosotros, y corrimos para darle vida al proyecto...

Gran Plan

Para empezar, nos formamos una visión de un sistema ideal:

  • Las campañas publicitarias del sistema corporativo 1C deben cargarse automáticamente con sus nombres, períodos, presupuestos y ubicaciones en varias plataformas.
  • Para cada colocación dentro de una campaña publicitaria, se deben descargar automáticamente todas las estadísticas posibles de los sitios donde se está realizando la colocación, como el número de impresiones, clics, visualizaciones, etc.
  • Algunas campañas publicitarias se rastrean mediante supervisión de terceros mediante los llamados sistemas de publicidad, como Adriver, Weborama, DCM, etc. En Rusia también existe un medidor de Internet industrial: la empresa Mediascope. Según nuestro plan, los datos del seguimiento independiente e industrial también deberían cargarse automáticamente en las campañas publicitarias correspondientes.
  • La mayoría de las campañas publicitarias en Internet están dirigidas a determinadas acciones específicas (comprar, llamar, registrarse para una prueba de manejo, etc.), que se rastrean mediante Google Analytics y cuyas estadísticas también son importantes para comprender el estado de la campaña y debe cargarse en nuestra herramienta.

El primer panqueque es abultado

Dado nuestro compromiso con los principios flexibles del desarrollo de software (ágil, todo), decidimos desarrollar primero un MVP y luego avanzar hacia el objetivo previsto de forma iterativa.
Decidimos construir MVP basado en nuestro producto. DANBo (Junta de la red Dentsu Aegis), que es una aplicación web con información general de las campañas publicitarias de nuestros clientes.

Para MVP, el proyecto se simplificó al máximo en términos de implementación. Hemos seleccionado una lista limitada de plataformas para la integración. Se trataba de las principales plataformas, como Yandex.Direct, Yandex.Display, RB.Mail, MyTarget, Adwords, DBM, VK, FB y los principales sistemas de publicidad Adriver y Weborama.

Para acceder a las estadísticas de los sitios a través de la API, utilizamos una única cuenta. Un administrador de grupo de clientes que quería utilizar la recopilación automática de estadísticas en una campaña publicitaria tenía que primero delegar el acceso a las campañas publicitarias necesarias en los sitios a la cuenta de la plataforma.

El siguiente es el usuario del sistema. DANBO debía cargar en el sistema Excel un archivo de cierto formato, que contenía toda la información sobre la colocación (campaña publicitaria, plataforma, formato, período de colocación, indicadores planificados, presupuesto, etc.) e identificadores de las campañas publicitarias correspondientes en el sistema Excel. sitios y mostradores en sistemas de publicidad.

Francamente, parecía aterrador:

Cómo recopilamos datos sobre campañas publicitarias de sitios en línea (el espinoso camino hacia el producto)

Los datos descargados se guardaron en una base de datos y luego servicios separados recopilaron identificadores de campaña en los sitios y descargaron estadísticas sobre ellos.

Para cada sitio, se escribió un servicio de Windows separado, que una vez al día iba a una cuenta de servicio en la API del sitio y descargaba estadísticas para ID de campaña específicas. Lo mismo sucedió con los sistemas de publicidad.

Los datos descargados se mostraban en la interfaz en forma de un pequeño panel personalizado:

Cómo recopilamos datos sobre campañas publicitarias de sitios en línea (el espinoso camino hacia el producto)

Inesperadamente para nosotros, MVP empezó a funcionar y empezó a descargar estadísticas actuales sobre campañas publicitarias en Internet. Implementamos el sistema en varios clientes, pero al intentar escalar, encontramos serios problemas:

  • El principal problema fue la complejidad de preparar los datos para cargarlos en el sistema. Además, los datos de ubicación debían convertirse a un formato estrictamente fijo antes de cargarlos. Fue necesario incluir identificadores de entidades de diferentes sitios en el archivo de descarga. Nos enfrentamos al hecho de que es muy difícil para los usuarios sin formación técnica explicar dónde encontrar estos identificadores en el sitio y en qué parte del archivo deben introducirse. Teniendo en cuenta la cantidad de empleados en los departamentos que realizan campañas en los sitios y el volumen de negocios, esto resultó en una gran cantidad de apoyo de nuestra parte, con lo cual no estábamos del todo contentos.
  • Otro problema era que no todas las plataformas publicitarias contaban con mecanismos para delegar el acceso a campañas publicitarias a otras cuentas. Pero incluso si estuviera disponible un mecanismo de delegación, no todos los anunciantes estaban dispuestos a otorgar acceso a sus campañas a cuentas de terceros.
  • Un factor importante fue la indignación que despertó entre los usuarios el hecho de que todos los indicadores planificados y detalles de ubicación que ya ingresan en nuestro sistema de contabilidad 1C, deben volver a ingresar DANBO.

Esto nos dio la idea de que la fuente principal de información sobre la colocación debería ser nuestro sistema 1C, en el que todos los datos se ingresan con precisión y a tiempo (el punto aquí es que las facturas se generan en base a los datos de 1C, por lo tanto, la entrada correcta de datos en 1C es una prioridad para todos (KPI). Así surgió un nuevo concepto del sistema...

Concepto

Lo primero que decidimos hacer fue separar el sistema de recopilación de estadísticas sobre campañas publicitarias en Internet en un producto separado: D1.Digital.

En el nuevo concepto, decidimos cargar en D1.Digital información sobre campañas publicitarias y ubicaciones dentro de ellas desde 1C, y luego obtener estadísticas de sitios y sistemas AdServing para estas ubicaciones. Se suponía que esto simplificaría significativamente la vida de los usuarios (y, como siempre, agregaría más trabajo a los desarrolladores) y reduciría la cantidad de soporte.

El primer problema que encontramos fue de carácter organizativo y estaba relacionado con el hecho de que no pudimos encontrar una clave o signo mediante el cual pudiéramos comparar entidades de diferentes sistemas con campañas y ubicaciones de 1C. El hecho es que el proceso en nuestra empresa está diseñado de tal manera que las campañas publicitarias son ingresadas en diferentes sistemas por diferentes personas (planificadores de medios, compras, etc.).

Para resolver este problema, tuvimos que inventar una clave hash única, DANBoID, que vincularía entidades en diferentes sistemas y que podría identificarse de manera bastante fácil y única en conjuntos de datos descargados. Este identificador se genera en el sistema interno 1C para cada ubicación individual y se transfiere a campañas, ubicaciones y contadores en todos los sitios y en todos los sistemas AdServing. Implementar la práctica de colocar DANBoID en todas las ubicaciones tomó algo de tiempo, pero logramos hacerlo :)

Luego descubrimos que no todos los sitios tienen una API para recopilar estadísticas automáticamente, e incluso aquellos que la tienen, no devuelve todos los datos necesarios.

En esta etapa, decidimos reducir significativamente la lista de plataformas para la integración y centrarnos en las principales plataformas que participan en la gran mayoría de las campañas publicitarias. Esta lista incluye a los principales actores del mercado publicitario (Google, Yandex, Mail.ru), redes sociales (VK, Facebook, Twitter), los principales sistemas de análisis y AdServing (DCM, Adriver, Weborama, Google Analytics) y otras plataformas.

La mayoría de los sitios que seleccionamos tenían una API que proporcionaba las métricas que necesitábamos. En los casos en los que no existía API o no contenía los datos necesarios, utilizamos informes enviados diariamente al correo electrónico de nuestra oficina para cargar datos (en algunos sistemas es posible configurar dichos informes, en otros acordamos el desarrollo de dichos informes). para nosotros).

Al analizar datos de diferentes sitios, descubrimos que la jerarquía de entidades no es la misma en diferentes sistemas. Además, la información debe descargarse con distintos detalles desde distintos sistemas.

Para solucionar este problema, se desarrolló el concepto SubDANBoID. La idea de SubDANBoID es bastante simple: marcamos la entidad principal de la campaña en el sitio con el DANBoID generado y cargamos todas las entidades anidadas con identificadores de sitio únicos y formamos SubDANBoID de acuerdo con el principio DANBoID + identificador de primer nivel. entidad anidada + identificador de la entidad anidada de segundo nivel +... Este enfoque nos permitió conectar campañas publicitarias en diferentes sistemas y descargar estadísticas detalladas sobre ellas.

También tuvimos que solucionar el problema del acceso a campañas en diferentes plataformas. Como escribimos anteriormente, el mecanismo de delegar el acceso a una campaña a una cuenta técnica separada no siempre es aplicable. Por lo tanto, tuvimos que desarrollar una infraestructura para la autorización automática vía OAuth utilizando tokens y mecanismos para actualizar estos tokens.

Más adelante en el artículo intentaremos describir con más detalle la arquitectura de la solución y los detalles técnicos de la implementación.

Arquitectura de solución 1.0

Al iniciar la implementación de un nuevo producto, entendimos que inmediatamente necesitábamos brindar la posibilidad de conectar nuevos sitios, por lo que decidimos seguir el camino de la arquitectura de microservicios.

Al diseñar la arquitectura, separamos los conectores de todos los sistemas externos (1C, plataformas publicitarias y sistemas de publicidad) en servicios separados.
La idea principal es que todos los conectores a sitios tengan la misma API y sean adaptadores que lleven la API del sitio a una interfaz que nos resulte conveniente.

En el centro de nuestro producto hay una aplicación web, que es un monolito diseñado de tal manera que se puede desmontar fácilmente en servicios. Esta aplicación es responsable de procesar los datos descargados, recopilar estadísticas de diferentes sistemas y presentarlas a los usuarios del sistema.

Para comunicarnos entre los conectores y la aplicación web, tuvimos que crear un servicio adicional, al que llamamos Connector Proxy. Realiza las funciones de descubrimiento de servicios y programador de tareas. Este servicio ejecuta tareas de recopilación de datos para cada conector todas las noches. Escribir una capa de servicio fue más fácil que conectar un intermediario de mensajes y para nosotros era importante obtener el resultado lo más rápido posible.

Por simplicidad y velocidad de desarrollo, también decidimos que todos los servicios serán API web. Esto hizo posible armar rápidamente una prueba de concepto y verificar que todo el diseño funciona.

Cómo recopilamos datos sobre campañas publicitarias de sitios en línea (el espinoso camino hacia el producto)

Una tarea separada, bastante compleja, fue configurar el acceso para recopilar datos de diferentes cuentas, que, como decidimos, los usuarios deberían realizar a través de la interfaz web. Consta de dos pasos separados: primero, el usuario agrega un token para acceder a la cuenta a través de OAuth y luego configura la recopilación de datos para el cliente desde una cuenta específica. Es necesario obtener un token a través de OAuth porque, como ya hemos escrito, no siempre es posible delegar el acceso a la cuenta deseada en el sitio.

Para crear un mecanismo universal para seleccionar una cuenta de los sitios, tuvimos que agregar un método a la API de conectores que devuelva el esquema JSON, que se representa en un formulario utilizando un componente JSONEditor modificado. De esta forma, los usuarios podían seleccionar las cuentas desde las que descargar datos.

Para cumplir con los límites de solicitudes que existen en los sitios, combinamos solicitudes de configuración dentro de un token, pero podemos procesar diferentes tokens en paralelo.

Elegimos MongoDB como almacenamiento de datos cargados tanto para la aplicación web como para los conectores, lo que nos permitió no preocuparnos demasiado por la estructura de datos en las etapas iniciales de desarrollo, cuando el modelo de objetos de la aplicación cambia cada dos días.

Pronto descubrimos que no todos los datos encajan bien en MongoDB y, por ejemplo, es más conveniente almacenar estadísticas diarias en una base de datos relacional. Por lo tanto, para los conectores cuya estructura de datos es más adecuada para una base de datos relacional, comenzamos a utilizar PostgreSQL o MS SQL Server como almacenamiento.

La arquitectura y las tecnologías elegidas nos permitieron construir y lanzar el producto D1.Digital con relativa rapidez. Durante dos años de desarrollo de productos, desarrollamos 23 conectores para sitios, adquirimos una experiencia invaluable trabajando con API de terceros, aprendimos a evitar los obstáculos de diferentes sitios, cada uno de los cuales tenía el suyo, contribuimos al desarrollo de API de al menos 3 sitios, descargó automáticamente información sobre casi 15 campañas y para más de 000 ubicaciones, recopiló una gran cantidad de comentarios de los usuarios sobre el funcionamiento del producto y logró cambiar el proceso principal del producto varias veces, basándose en estos comentarios.

Arquitectura de solución 2.0

Han pasado dos años desde el inicio del desarrollo. D1.Digital. El aumento constante de la carga en el sistema y la aparición de cada vez más fuentes de datos nuevas revelaron gradualmente problemas en la arquitectura de la solución existente.

El primer problema está relacionado con la cantidad de datos descargados de los sitios. Nos enfrentamos al hecho de que recopilar y actualizar todos los datos necesarios de los sitios más grandes empezó a llevar demasiado tiempo. Por ejemplo, la recopilación de datos del sistema de servidor de anuncios AdRiver, con el que realizamos un seguimiento de las estadísticas de la mayoría de las ubicaciones, tarda unas 12 horas.

Para solucionar este problema, comenzamos a utilizar todo tipo de informes para descargar datos de los sitios, estamos tratando de desarrollar su API junto con los sitios para que la velocidad de su funcionamiento satisfaga nuestras necesidades y paralelizar la descarga de datos tanto como sea posible.

Otro problema está relacionado con el procesamiento de los datos descargados. Ahora, cuando llegan nuevas estadísticas de ubicación, se inicia un proceso de varias etapas para recalcular métricas, que incluye cargar datos sin procesar, calcular métricas agregadas para cada sitio, comparar datos de diferentes fuentes entre sí y calcular métricas resumidas para la campaña. Esto provoca mucha carga en la aplicación web que realiza todos los cálculos. Varias veces, durante el proceso de recálculo, la aplicación consumió toda la memoria del servidor, entre 10 y 15 GB, lo que tuvo el efecto más perjudicial en el trabajo de los usuarios con el sistema.

Los problemas identificados y los ambiciosos planes para un mayor desarrollo del producto nos llevaron a la necesidad de reconsiderar la arquitectura de la aplicación.

Empezamos con los conectores.
Notamos que todos los conectores funcionan según el mismo modelo, por lo que construimos un marco de tubería en el que para crear un conector solo había que programar la lógica de los pasos, el resto era universal. Si algún conector requiere mejora, lo transferimos inmediatamente a un nuevo marco al mismo tiempo que se mejora el conector.

Al mismo tiempo, comenzamos a implementar conectores para Docker y Kubernetes.
Planeamos el cambio a Kubernetes durante bastante tiempo, experimentamos con la configuración de CI/CD, pero comenzamos a movernos solo cuando un conector, debido a un error, comenzó a consumir más de 20 GB de memoria en el servidor, prácticamente matando otros procesos. . Durante la investigación, el conector se trasladó a un clúster de Kubernetes, donde finalmente permaneció, incluso después de que se solucionó el error.

Rápidamente nos dimos cuenta de que Kubernetes era conveniente y en seis meses transferimos 7 conectores y Connectors Proxy, que consumen la mayor cantidad de recursos, al clúster de producción.

Siguiendo los conectores, decidimos cambiar la arquitectura del resto de la aplicación.
El principal problema fue que los datos provienen de los conectores a los servidores proxy en grandes lotes, luego llegan al DANBoID y se envían a la aplicación web central para su procesamiento. Debido a la gran cantidad de recálculos de métricas, existe una gran carga en la aplicación.

También resultó bastante difícil monitorear el estado de los trabajos de recopilación de datos individuales e informar los errores que ocurrían dentro de los conectores a una aplicación web central para que los usuarios pudieran ver qué estaba sucediendo y por qué no se estaban recopilando datos.

Para resolver estos problemas, desarrollamos la arquitectura 2.0.

La principal diferencia entre la nueva versión de la arquitectura es que en lugar de la API web, utilizamos RabbitMQ y la biblioteca MassTransit para intercambiar mensajes entre servicios. Para hacer esto, tuvimos que reescribir casi por completo Connectors Proxy, convirtiéndolo en Connectors Hub. El nombre se cambió porque la función principal del servicio ya no es reenviar solicitudes a los conectores y viceversa, sino gestionar la recopilación de métricas de los conectores.

Desde la aplicación web central, separamos la información sobre ubicaciones y estadísticas de los sitios en servicios separados, lo que permitió deshacerse de recálculos innecesarios y almacenar solo estadísticas ya calculadas y agregadas a nivel de ubicación. También reescribimos y optimizamos la lógica para calcular estadísticas básicas basadas en datos sin procesar.

Al mismo tiempo, estamos migrando todos los servicios y aplicaciones a Docker y Kubernetes para que la solución sea más fácil de escalar y más cómoda de administrar.

Cómo recopilamos datos sobre campañas publicitarias de sitios en línea (el espinoso camino hacia el producto)

Donde nos encontramos ahora

Producto de arquitectura 2.0 de prueba de concepto D1.Digital listo y funcionando en un entorno de prueba con un conjunto limitado de conectores. Todo lo que queda por hacer es reescribir otros 20 conectores a una nueva plataforma, probar que los datos se cargan correctamente y que todas las métricas se calculan correctamente y implementar todo el diseño en producción.

De hecho, este proceso se producirá de forma gradual y tendremos que dejar la compatibilidad con versiones anteriores de las API antiguas para que todo siga funcionando.

Nuestros planes inmediatos incluyen el desarrollo de nuevos conectores, la integración con nuevos sistemas y la adición de métricas adicionales al conjunto de datos descargados de los sitios conectados y los sistemas de publicidad.

También planeamos transferir todas las aplicaciones, incluida la aplicación web central, a Docker y Kubernetes. Combinado con la nueva arquitectura, esto simplificará significativamente la implementación, el monitoreo y el control de los recursos consumidos.

Otra idea es experimentar con la elección de la base de datos para almacenar estadísticas, que actualmente se almacena en MongoDB. Ya hemos transferido varios conectores nuevos a las bases de datos SQL, pero allí la diferencia es casi imperceptible, y para las estadísticas agregadas por día, que se pueden solicitar durante un período arbitrario, la ganancia puede ser bastante importante.

En general, los planes son grandiosos, sigamos adelante :)

Autores del artículo I+D Dentsu Aegis Network Rusia: Georgy Ostapenko (shmiigaa), Mijaíl Kotsik (hitexx)

Fuente: habr.com

Añadir un comentario