Cómo armamos una pila tecnológica de 12 pisos y no nos volvimos locos

Appodeal es una compañía de ~ 100 personas que trabajan en Moscú, San Francisco, Barnaul, Lutsk, Kirov, Barcelona y, desde junio de 2018, también en Minsk.

Monetizamos las aplicaciones móviles mostrando anuncios a los usuarios. Comenzamos con la mediación publicitaria, pero la pila de tecnología está en constante crecimiento, por lo que otros productos de la industria de Ad Tech también se han agregado a la mediación.

imagen

Para aquellos que no están familiarizados con Ad Tech, esta es el área de trabajo de las empresas de tecnología que trabajan en el campo de la publicidad. Cuando le dices a alguien que trabajas en el campo de la publicidad móvil, la gente a menudo reacciona con escepticismo; aparentemente, el molesto anuncio "Azino Three Axes" viene a la mente. De hecho, esto es solo la punta del iceberg, y toda esta publicidad "salvaje" no tiene nada que ver con el negocio publicitario real. Y el segmento móvil en el que estamos involucrados ha superado durante mucho tiempo el segmento de publicidad en la web:

imagen

¿Por qué integrar anuncios en aplicaciones?


Por supuesto, se gastan muchos recursos en la creación de aplicaciones, y los creadores / propietarios quieren que el tiempo y el esfuerzo gastados valgan la pena. Los propietarios de aplicaciones móviles que publican su aplicación en la tienda de aplicaciones / Google Play se denominan editores o editores. Los editores aplican diferentes modelos de monetización, desde compras en la aplicación hasta monetización publicitaria. Pero de todos estos métodos, solo el último permite al usuario no pagar por usar la aplicación, y esto brinda la mayor cobertura de audiencia.

Sí, si hay demasiada publicidad, molestará a todos y afectará negativamente la retención de usuarios. Que, por supuesto, nadie necesita. Por lo tanto, siempre intentan integrar la publicidad sabiamente para ganar el máximo dinero en su aplicación y, al mismo tiempo, no tomar un centavo de los usuarios.

Como funciona


Tan pronto como el editor decide monetizar a través de la publicidad, acude a la compañía que puede hacer que esta tarea sea lo más fácil posible para él. ¿Cómo sucede esto con Appodeal? Después de registrarse en el sitio, integramos su aplicación con nuestro servicio. Esto se realiza a través del SDK del cliente, que conecta la aplicación a la parte del servidor y se comunica con la parte del servidor a través de la API.

Si minimiza los detalles, el objetivo de la interacción se reduce a dos etapas:

a. Determine qué anuncio mostrar en este momento;
b. Envíe información sobre qué anuncio se mostró y cuál no, y muéstrelo en las estadísticas.

Actualmente, Appodeal atiende a varios miles de aplicaciones activas que proporcionan aproximadamente 400-450 millones de impresiones de anuncios por día, recibidas en respuesta a cerca de mil millones de solicitudes a redes publicitarias (que son los proveedores de publicidad). Para que esto funcione, nuestros servidores atienden alrededor de 125 mil solicitudes por segundo, es decir aproximadamente 10.8 mil millones de consultas por día.

imagen

¿En qué se basa todo esto?


Utilizamos varias tecnologías para proporcionar velocidad, confiabilidad y al mismo tiempo flexibilidad de desarrollo y soporte. Por el momento, estamos escribiendo código en los siguientes idiomas:

  • / Ruby / Ruby on Rails + React.JS (front-end) /: Todavía hay una gran parte de la API y todo el elemento web que los usuarios y nuestros empleados ven
  • / GoLang /: Procesando grandes cantidades de datos estadísticos y no solo
  • / Scala /: solicitudes de procesamiento en tiempo real para trabajar con intercambios de intercambio de tráfico utilizando el protocolo RTB (lea más al respecto al final del artículo)
  • / Elixir / Phoenix /: Más bien, la parte experimental. Creación de algunos microservicios para manejar algunas estadísticas y API.

imagen

¿Por qué es originalmente Ruby y Ruby on Rails?


Appodeal compite en su segmento con jugadores muy grandes, por lo que debe adaptarse rápidamente a los cambios del mercado. A menudo esto se siente como un cambio en las ruedas de un automóvil a una velocidad de 100 km / h. Ruby on Rails nos permitió resistir la carrera y ganar un punto de apoyo en el mercado lo suficiente como para ser un líder en su segmento. Las principales ventajas de Rails en nuestra opinión:

  • Un gran número de desarrolladores calificados.
  • Gran comunidad Una gran cantidad de soluciones y bibliotecas listas para usar
  • La velocidad de introducir nuevas funciones y cambiar / eliminar las antiguas

imagen

De los inconvenientes obvios:

  • El rendimiento general es pobre. También afecta la falta de JIT (en este momento), la falta de la capacidad de paralelizar el código (si no tiene en cuenta JRuby). Hasta cierto punto, esto sigue siendo soportable porque el cuello de botella suele ser la base de datos y el caché. Lo que vemos en la imagen de NewRelic:

imagen

  • Los monolitos ferroviarios no se cortan muy bien en microservicios: se ven afectados por un alto grado de conectividad entre la lógica empresarial y la lógica de acceso a datos (ActiveRecord).

¿Cómo se almacenan los datos?


Tenemos muchos datos. Muy Estamos hablando de miles de millones / decenas / cientos de miles de millones de registros. Dado que los datos son completamente diferentes, los almacenamos de diferentes maneras. Nunca debe limitarse en arquitectura a ninguna solución, que supuestamente es universal. La práctica muestra que, en primer lugar, en Highload prácticamente no hay soluciones universales. Universalidad significa indicadores promedio (o significativamente más bajos que el promedio) para el acceso / velocidad de lectura / tamaño de almacenamiento de datos como una tarifa por esta versatilidad. En segundo lugar, debe probar algo nuevo todo el tiempo, experimentar y buscar soluciones no triviales para las tareas. Total:

  • / PostgreSQL /: Nos encanta Postgre. Lo consideramos la mejor solución de almacenamiento OLTP en este momento. Allí se almacenan datos sobre usuarios, aplicaciones, campañas publicitarias, etc. Usamos replicación de réplica primaria. Hacemos copias de seguridad solo en las vacaciones de Navidad, porque esto es para los débiles (una broma).
  • / VerticaDB /: base de datos orientada a columnas. Utilizamos para almacenar miles de millones de registros estadísticos. En resumen, Vertika fue considerada por algún tiempo la mejor solución OLAP para almacenar análisis. La principal desventaja es el enorme precio (individual) de la licencia.
  • / ClickHouse /: también una base de datos orientada a columnas. Cambie gradualmente a él con VerticaDB. Consideramos la mejor solución OLAP en este momento. No vale un centavo. Funciona de manera muy rápida y confiable. El principal inconveniente es que los datos no se pueden eliminar y actualizar (hablaremos de esto en un artículo separado, si alguien está interesado).

imagen

Nada! ¿Cómo es imposible eliminar y modificar datos?

  • / Aerospike /: El almacenamiento de valor-clave NoSQL más rápido en nuestra opinión. Hay una serie de inconvenientes, pero en general estamos satisfechos. Incluso hay una tabla de comparación para Aerospike en su sitio de rendimiento con otras soluciones: [Cuándo usar la base de datos Aerospike NoSQL vs. Redis] (https://www.aerospike.com/when-to-use-aerospike-vs-redis/)
  • / Redis /: Sobre "Rábano", creo, no tiene sentido contar por separado. Paradójicamente, su principal ventaja es la facilidad de uso y el enhebrado único, lo que evita las condiciones de carrera, por ejemplo, cuando se trabaja con contadores comunes.
  • / Druid /: Usamos para grandes conjuntos de datos en el trabajo con intercambios RTB. De hecho, en su mayor parte, juega en el mismo campo con ClickHouse, pero históricamente, todavía no hemos podido cambiar a ningún instrumento.

imagen

Tal conjunto puede parecer sobrecargado, pero en primer lugar, Appodeal es un gran conglomerado de varios equipos de desarrollo y varios proyectos dentro de uno. Y en segundo lugar, estas son las duras realidades de la tecnología publicitaria: no somos los únicos que usamos una pila de varios pisos dentro de una empresa.

¿Cómo sigues esto?



Debido a que los flujos de datos son grandes, deben estar en cola para procesarlos. Como cola usamos Kafka. Esta es una gran solución confiable escrita en Scala que nunca nos ha fallado todavía.

imagen


El único requisito para el usuario en este caso es que tenga tiempo de rastrear la cola cada vez más rápida de lo que crece. Una regla simple y obvia. Por lo tanto, para estos fines, utilizamos principalmente GoLang. Sin embargo, esto no niega el hecho de que la RAM en este servidor debería ser abundante.

Para monitorear toda esta economía, debe monitorear y delegar literalmente todo en una fila. Para esto usamos:

  • / NewRelic /: una solución probada en el tiempo que se integra perfectamente con Ruby on Rails y los micro servicios GoLang. El único inconveniente de NewRelic es su precio. Por lo tanto, NewRelic no está en todas partes con nosotros. En su mayor parte, intentamos reemplazarlo con nuestras propias métricas recopiladas a mano: las colocamos en Grafana.
  • / Statsd + Grafana /: algo bueno para recopilar sus métricas. Con el único inconveniente de que tiene que configurar todo usted mismo y "repetir" la funcionalidad NewRelic de fábrica.
  • / ElasticSearch + Fluentd + Kibana /: En los registros colocamos todo en una fila. Desde consultas lentas de PostgreSQL hasta algunos mensajes del sistema Rails. En realidad, una solución como Kibana basada en ElasticSearch le permite recopilar convenientemente todos los registros en un solo lugar y luego buscar los mensajes necesarios en ellos.
  • / Airbrake /: obligatorio en este proceso de recopilación de errores junto con el mensaje stacktrace'ami. Actualmente nos estamos mudando con Airbrake a una de las soluciones gratuitas. Por una razón, de nuevo, los precios.

imagen

Debe comprender que el monitoreo adecuadamente construido es sus ojos y oídos. Ciegamente imposible de trabajar. Debe ver lo que sucede en sus servidores en un momento determinado, por lo que la estabilidad y la confiabilidad de su producto dependerán en gran medida de qué tan competente sea para construir un sistema para recopilar y mostrar métricas.

Por cierto, hablando de confiabilidad, contamos con varios servidores de preparación para el despliegue previo y la verificación de versiones, que mantenemos estables bajo carga, duplicando parte del tráfico real allí. Cada semana sincronizamos bases de datos entre producción y puesta en escena. Esto nos da una especie de "espejo" que nos permite probar aquellas cosas que no se pueden verificar localmente, así como identificar problemas a nivel de pruebas de carga.

¿Es realmente tan complicado?


Resulta de esa manera. Como escribió Elon Musk en su libro: "Las mejores mentes de mi generación están ocupadas haciendo que la gente haga clic en los anuncios", me dijo Jeff Hammerbacher, un ingeniero de Facebook. "Horror ..." Una breve lista de lo que hace Appodeal:

  • Estamos integrados con dos docenas de redes y agencias de publicidad. En modo automático, registramos aplicaciones en estas redes, así como configuramos varios parámetros para que estas redes funcionen al máximo rendimiento. No todas las redes tienen API correspondientes, en algún lugar hay que hacerlo con robots.
  • Cada red paga a los usuarios ingresos por impresiones, que deben recibirse, desglosarse por varios parámetros y procesarse. Esto se hace sin parar. En algún lugar, de nuevo, por robots.
  • Para proporcionar al usuario un ingreso máximo, "hacemos" que las cuadrículas compitan entre sí, construyendo la llamada "cascada" a partir de ofertas publicitarias. La cascada se basa en varios indicadores, por ejemplo, eCPM (precio promedio por 1000 impresiones), que predecimos de varias maneras. Cuanto mayor sea la oferta publicitaria en la cascada, mayor será la predicción del precio. Esta cascada se ofrece en el dispositivo tantas veces como sea necesario. Como habrás adivinado, un anuncio en el que nadie hace clic y que solo molestará a todos no interesa a nadie. La excepción es solo la llamada. Anuncios publicitarios "de marca" de Coca-Cola, Pepsi y otros gigantes corporativos que están acostumbrados a hablar de sí mismos siempre y en todas partes.
  • Parte de esta interacción se basa en el llamado protocolo RTB (Real-Time Bidding):

imagen


En este caso, los llamados oferentes se intercambian entre sí en línea en una subasta por el derecho a mostrar sus anuncios en el dispositivo seleccionado. Un punto muy interesante digno de un artículo separado. Muchos intercambios, como Google AdExchange, establecen un marco estricto para el tiempo de respuesta del servidor (por ejemplo, 50 ms), lo que plantea un problema de rendimiento de punta. En caso de desobediencia, una multa de miles de dólares. Esto es exactamente lo que hace el núcleo escrito en Scala junto con Druid.

Cada cazador quiere saber dónde se encuentra el faisán, y nuestros clientes (como nosotros) quieren saber a quién se le mostró el anuncio, cuándo y por qué. Por lo tanto, tenemos que poner en cola (Kafka) todo el montón de datos que tenemos, procesar y agregar gradualmente a la base de datos OLAP (ClickHouse). Muchas personas piensan que PostgreSQL hará frente a esta tarea no peor que cualquier solución "hipster", pero esto no es así. PostgreSQL es bueno, pero la solución clásica para construir índices para la velocidad de acceso a los datos deja de funcionar cuando el número de campos para filtrar y ordenar supera los 10, y la cantidad de datos almacenados se acerca a mil millones de registros. Simplemente no tiene suficiente memoria para almacenar todos estos índices o tendrá problemas para actualizar estos índices. En cualquier caso, no podrá lograr el mismo rendimiento que las soluciones orientadas a columnas para consultas analíticas.

Conclusión


En este artículo, traté de describir al menos brevemente lo que hacemos, cómo almacenamos y procesamos los datos. Díganos en los comentarios qué pila usa, haga preguntas y solicite nuevos artículos; estaremos encantados de compartir nuestra experiencia.

Source: https://habr.com/ru/post/es425357/


All Articles