Skip to main content

¿Alguna vez te has preguntado cómo funcionan los sistemas con una alta ingesta de datos?

El avance de la tecnología en los últimos años nos ha proporcionado herramientas y servicios increíbles para procesar y realizar una ingesta masiva de datos de manera sencilla y ágil.

Introducción

En este artículo veremos una de las soluciones que nos ofrece Azure para gestionar una ingesta masiva de datos. Es crucial abordar este tipo de problemas con una metodología estructurada para garantizar la eficacia y estabilidad del sistema.

Medición

La medición precisa es fundamental para entender el rendimiento actual del sistema y detectar puntos de falla. Sin datos precisos, cualquier intento de optimización será como navegar a ciegas.

Análisis

Una vez tengamos visibilidad sobre las partes del sistema que hemos monitorizado y medido, debemos hacer un análisis para identificar el problema y ver qué opciones tenemos para solucionarlo.

Planificación

Planificar cuidadosamente las soluciones evita interrupciones mayores y asegura que los cambios se implementen de manera controlada. Es esencial tener una estrategia clara antes de realizar cualquier cambio significativo.

Implementación

La implementación debe ser gradual y controlada para minimizar el riesgo de interrupciones y permitir ajustes en tiempo real si surgen problemas no anticipados. Aplicar soluciones sin poder medir, analizar y planificar nos traerá problemas a corto y medio plazo. ¡Dicho esto, vamos con Azure!

¿Qué son las Azure Functions?

Azure Functions es un servicio de computación sin servidor (serverless) proporcionado por Microsoft Azure que permite ejecutar pequeñas piezas de código (funciones) en respuesta a eventos específicos sin necesidad de gestionar explícitamente la infraestructura subyacente.

¿Utilizas Azure Functions en tu proyecto?

Composición de una Azure Function

Azure Function Plan

El Azure Function Plan define cómo se ejecutarán las funciones, incluyendo la escalabilidad, costos y características disponibles. Los planes incluyen:

  • Plan de Consumo: Funciona en un entorno sin servidor, escalando automáticamente según la demanda. El costo se basa en el uso real (ejecuciones, memoria y tiempo de ejecución).
  • Plan Premium: Ofrece capacidades mejoradas como escalabilidad avanzada, soporte para redes virtuales (VNET) y tiempos de ejecución más largos.
  • Plan Dedicado (App Service Plan): Las funciones se ejecutan en el mismo entorno que las aplicaciones web del App Service.
  • Plan Kubernetes (AKS): Permite ejecutar funciones en un clúster de Kubernetes gestionado por Azure.

Desencadenadores (Triggers)

Los desencadenadores inician la ejecución de una función en respuesta a un evento específico. Algunos ejemplos:

  • HTTP Trigger: La función se ejecuta en respuesta a una solicitud HTTP. Ideal para crear APIs RESTful o endpoints web.
  • Timer Trigger: La función se ejecuta en un horario predefinido, útil para tareas programadas.
  • Blob Storage Trigger: La función se ejecuta cuando se crea o modifica un archivo en Azure Blob Storage, útil para el procesamiento de archivos.
  • Queue Storage Trigger: La función se ejecuta en respuesta a nuevos mensajes en una cola de Azure Queue Storage.
  • Event Hub Trigger: Ejecuta la función cuando se reciben eventos en Azure Event Hubs, ideal para la ingesta masiva de datos en tiempo real.
  • Service Bus Trigger: La función se ejecuta en respuesta a mensajes en Azure Service Bus (colas y temas).

Enlaces (Bindings)

Los bindings permiten que las funciones interactúen fácilmente con otros servicios y recursos de Azure sin escribir código adicional. Pueden ser de entrada o salida:

  • Bindings de Entrada: Permiten que una función reciba datos de recursos externos como colas, bases de datos o archivos.
  • Bindings de Salida: Permiten que una función envíe datos a recursos externos como bases de datos o colas.

Código de la Función

El código de la función se puede escribir en varios lenguajes como C#, JavaScript, Python, Java y PowerShell. Este código es responsable de procesar los datos de entrada y generar los resultados necesarios.

Ejemplo de Arquitectura

Entrada del Sistema

Nuestro sistema tendrá un punto de entrada a través de una API, en este caso la API está creada a partir de una Azure Function. En algunos casos es posible que necesitemos incorporar delante de nuestra Function un Api Management para poder tener una capa de configuración extra (seguridad, rate limit o cache).

Esta parte del sistema se encarga únicamente de recibir los datos externos y enviarlos a un Event hub (eventos), en esta parte no hacemos ningún procesado de los datos y evitamos hacer cualquier operación en la base de datos que no sea estrictamente necesaria. El Event hub es una pieza clave en este sistema ya que nos va a permitir:

  • Quitar presión en la entrada de nuestro sistema
  • Manejar como queremos procesar a posterior los datos (lectura de eventos de uno en uno o por batches)
  • Reducir la latencia, es una pieza de infraestructura con un tiempo de respuesta muy bajo

Procesado de datos

En esta parte del sistema tendremos una Azure function conectada mediante un binding y un trigger al event hub, esto quiere decir que cada vez que recibamos un mensaje del Event hub se ejecutará el código de nuestra Azure function.

¿Qué debemos tener en cuenta en este punto?

  • ¿Necesitamos limitar la velocidad de escritura a la base datos?
    • Te dejo por aquí un artículo donde hablamos de algunos de los problemas y soluciones relacionados con Mongodb
  • ¿Necesitamos hacer algún tipo de agregación sobre estos datos?
  • ¿Los datos (eventos) que tenemos dentro del event hub podemos consumirlos en batches?
  • ¿Podemos tener más de un consumidor procesando los datos?

En este caso quiero darte unos consejos de cómo deberíamos de gestionar para que nuestro proceso de consumo de datos sea lo más óptimo y rápido posible.

Recepción de eventos en batches

Configurar el binding de la Azure Function para poder recibir los eventos por batches. En este punto tendremos que ver cuál es el número óptimo de mensajes que podemos recibir.

Operaciones en batches

Si hacemos operaciones contra la base de datos en batches conseguiremos reducir las operaciones y el tiempo de procesamiento (tanto en la lectura como en escritura).

Ejemplo:

Recibo 5 eventos, de estos eventos cada uno tiene un User distinto asignado en el evento.  Si procesamos cada evento de forma separada conlleva (ejemplo de operaciones):

  • Lectura de un user
  • Escribir un nuevo registro

Esto nos da un total de 2 operaciones en la base de datos por evento, 10 operaciones en total por batch. En cambio si agrupamos las queries de lectura y de escritura hacemos en total solo 2 operaciones, una para traernos todos los users y otra para escribir todos los reportes.

Consumidores en paralelo

Una de las características del Event hub es que nos permite tener nuestros eventos divididos / agrupados (particiones). Tener más de una partición configurada en el Event hub lo que nos va a permitir es que en función del número de particiones que tengamos se ejecutará una instancia de la Azure function por cada partición (siempre que reciba eventos).

Conclusiones

  • Procesado de datos descentralizado: La entrada del sistema solo encola los datos y el procesado se realiza en otro punto del sistema.
  • Recepción y operaciones en batches: Configura adecuadamente el tamaño del lote para optimizar el rendimiento.
  • Configuración de Azure Function: Asegura que el tiempo de ejecución y la memoria sean los adecuados.
  • Paralelización y particiones: Optimiza el número de particiones en Event Hub para balancear la carga.
  • Monitoreo y escalado: Utiliza herramientas como Azure Monitor y Application Insights para rastrear el rendimiento y escalar según sea necesario.

Implementando estas estrategias se puede optimizar el proceso de consumo de datos con Azure Functions y Event Hub, asegurando un rendimiento eficiente y una mejor gestión de los recursos.

Enlaces de interés

¿Necesitas ayuda con Azure Functions?

Leave a Reply

Discover more from LambdaLoopers

Subscribe now to keep reading and get access to the full archive.

Continue reading