Estaba pensando acerca de mi periodo en mi último trabajo, en una empresa donde proporcionan a los clientes un software basado en procesamiento diario ELT y ETL de las antenas para crear tanto ficheros avro en el landing stage de un cluster Hadoop como finalmente ficheros parquet ya consolidados y agregados con los que crear finalmente tablas en Apache Impala que luego sirven como fuente de la verdad u origen de datos para una serie de microservicios clásicos escritos con el clásico stack spring-boot sobre postgres.

Todo ello tras pasar por un proceso CICD donde aparece el stack clásico, git, maven, jenkins, tests de todo tipo, incluyendo regresión, ejecución sonarqube, creación y subida de la imagen docker a un registro interno, despliegue en entorno de preproducción, monitorización y finalmente envío de correos electrónicos para todas las personas involucradas.

Podemos hablar de ese proceso CICD, el cual a mi juicio está incompleto pues faltarían procesos para comprobar la integridad y seguridad de los contenedores creados, incluso un proceso en el que una IA RAG te envía pull requests con análisis del código donde se discutan problemas y mejoras, pero hoy prefiero centrarme en esta arquitectura clásica big data de recolección de datos.

Sé que esta configuración para procesamiento diario de información de antenas es un clásico pues ya me lo encontré en otro cliente, y ahora que sé algo más, me doy cuenta que esta propuesta no es la adecuada pues antetodo en los dashboards tienes que poder mostrar a ser posibles datos en tiempo real y a la vez tienen que ser datos consistentes, tolerante a fallas en las particiones y si es posible, que funcione incluso si algún nodo no está disponible, todo ello en un entorno distribuido porque estamos hablando de que tenemos ficheros muy grandes, potencialmente TB de datos diarios y por lo tanto necesitamos un cluster donde podamos distribuir la carga de procesamiento y los datos particionados.

La propuesta inicial clásica es antetodo procesamiento batch, es decir, del día anterior, o en el mejor de los casos de unas horas antes, nunca veíamos los datos de las antenas en tiempo real, más que nada porque antetodo la finalidad de esta solución es saber donde hay un problema, pero no es un imperativo saber en tiempo real donde está pasando ese problema.

Una propuesta:

En vez de guardar los datos procesados y agregados de las antenas mediante spark en Apache Impala, una posible mejor solución podría ser usar Spark streaming/Structured Streaming para agregar los datos provenientes de distintas antenas. Estos ficheros suelen estar ya en varios sistemas de ficheros previamente consolidados en algún sistema externo, por lo que idealmente yo trataría de cortar ese paso para conectar directamente el consumidor de Spark con ese productor de datos de antenas, para luego pasar por una serie de fases donde procesamiento de datos, agregación de datos para finalmente crear los ficheros parquets, de manera que así se crean las fuentes de la verdad para Delta Lake. Actualmente algo así funciona pero con Apache Impala, algo que en mi opinión es un error si quieres datos consistentes distribuidos, pero Apache Impala no está diseñado para ese fin. Delta Lake si lo está, permitiendo transacciones de lectura ACID distribuidas y al mismo tiempo usar Apache Hudi en el cluster hadoop para permitir inserciones, actualizaciones y borrados en dichas tablas creadas originalmente. De esa manera consigues lo mejor de todos los mundos, procesamiento en tiempo real mediante spark streaming, lectura de datos ACID distribuida mediante Delta Lake, actualización de datos en tiempo real ACID distribuido mediante Hudi.

Si en el proceso inicial de creación de ficheros parquet no se presentaran fallos de inconsistencia, algo como Apache Hudi no sería necesario, pero la verdad es que si ocurre, en mi opinión debido a la naturaleza distribuida del negocio y puede que debido también al relajamiento a la hora de seguir SOLID cuando construimos este software.
Hudi sería necesario para tratar de encontrar y actualizar dichas inconsistencias ya en el delta lake, en una fase de preparación.

En definitiva, pasar de una arquitectura batch a una arquitectura batch/tiempo real lambda, de manera que si es necesario volver a procesar datos de un día en específico, puedes hacerlo, pero el funcionamiento normal deberá estar basada en streaming de datos. Un estilo kappa en el que solo hay procesamiento en tiempo real nos quita la posibilidad de procesar datos del pasado, y eso es algo que normalmente no quieren las empresas.

Posibles ventajas Delta Lake y Hudi sobre Spark/Impala:

1) Procesamiento en tiempo real con Spark Streaming/structured streaming: Utilizar Spark Streaming nos permite procesar y agregar datos en tiempo real a medida que llegan desde diferentes antenas. Esto permite una respuesta rápida a los cambios en los datos y la capacidad de analizar y actuar sobre ellos de manera casi instantánea.

2) Almacenamiento eficiente con Parquet y Delta Lake: Almacenar los datos procesados en archivos Parquet proporciona eficiencia en el almacenamiento y la consulta de datos. Además, aprovechar Delta Lake para gestionar los archivos Parquet te permite obtener características adicionales, como transacciones ACID y versionado de datos, lo que garantiza la integridad y consistencia de los datos. Apache Impala no proporciona transacciones ACID, no garantiza que haya datos consistentes en las particiones de los ficheros parquet, por lo que es posible que haya consultas donde los datos sean inconsistentes. Esto provoca sorpresa y malestar en los operadores, de manera que se trataba de solventar en la parte de la creación de los ficheros parquet que a su vez están muy influenciados por la naturaleza dinámica del tráfico entre antenas. Se perdía mucho tiempo a la hora de encontrar posibles bugs en el código, pero el verdadero problema es haber elegido una herramienta que no está pensada para transacciones ACID. Delta Lake si lo está.

3) Gestión de datos cambiantes con Apache Hudi: Utilizar Apache Hudi para gestionar los datos permite realizar operaciones de inserción, actualización y eliminación de manera eficiente y consistente en un entorno distribuido. Esto es especialmente útil cuando necesitas manejar actualizaciones en tiempo real en tus datos almacenados. Viene a soportar de manera natural esos posibles datos inconsistentes dando soporte a Delta Lake. Es decir, dejamos a Delta Lake que se encargue de la transaccionalidad distribuida a la hora de hacer lecturas consistentes distribuidas y si tenemos que actualizar dichos datos, lo delegamos en hudi.

4) Flexibilidad y escalabilidad: Esta arquitectura proporciona una gran flexibilidad y escalabilidad para adaptarse a diferentes necesidades y cargas de trabajo. Puedes ajustar fácilmente el sistema para manejar mayores volúmenes de datos o agregar nuevas fuentes de datos sin modificar significativamente la arquitectura general.

Posibles mejoras:

Si necesito poder cambiar de esquema rápidamente y acceder a datos históricos podría usar tambien Apache Iceberg.

Apache Iceberg es una base de datos en código abierto diseñada para gestionar grandes conjuntos de datos, proporcionando un formato de archivo optimizado para consultas analíticas y soporte para esquemas evolutivos. Las consultas ACID me las proporciona Delta Lake, por lo que a mí me interesa más su capacidad avanzada para evolucionar esquemas, más avanzado que el que me permite Delta Lake de por sí.

Aquí hay algunas ventajas de incorporar Apache Iceberg a la arquitectura streaming:

1) Esquemas evolutivos: Iceberg permite cambios de esquema rápidos y controlados, lo que significa que puedes actualizar o modificar el esquema de tus datos sin interrumpir las operaciones de lectura y escritura existentes. Esto es crucial en entornos donde los esquemas de datos evolucionan con el tiempo.

2) Gestión de datos históricos: Iceberg incluye soporte integrado para el versionado de datos, lo que te permite acceder a versiones históricas de tus datos. Esto es útil para realizar análisis retrospectivos, depuración de problemas y cumplimiento de normativas que requieran un historial de datos.

3) Optimización de consultas: Iceberg está diseñado para proporcionar un rendimiento óptimo en consultas analíticas, utilizando técnicas como la poda de columnas y la indexación para acelerar las consultas. Esto te permite realizar análisis complejos de manera eficiente sobre grandes conjuntos de datos.

4) Integración con otros proyectos de ecosistema de Hadoop: Iceberg se integra bien con otros proyectos de big data como Apache Spark, Apache Hudi y Apache Parquet, lo que te permite aprovechar las ventajas de estas herramientas mientras aprovechas las características adicionales de Iceberg.

Cuales son las desventajas de usar esta conjunción de tecnologías en vez de una arquitectura en batch más tradicional y que no me garantiza procesamiento ACID distribuido en las lecturas de datos?

1) Complejidad de la arquitectura: La combinación de Spark Streaming, Delta Lake, Apache Hudi y Apache Iceberg puede resultar en una arquitectura más compleja en comparación con un enfoque de procesamiento en batch más tradicional. Esto puede aumentar la curva de aprendizaje y la complejidad operativa del sistema.

2) Más recursos requeridos: El uso de tecnologías de procesamiento en tiempo real como Spark Streaming puede requerir más recursos en términos de CPU, memoria y almacenamiento en comparación con un enfoque de procesamiento en batch. Esto puede aumentar los costos operativos y la complejidad de la gestión de la infraestructura.

3) Mayor riesgo de errores: Con una arquitectura más compleja y diversa, hay un mayor riesgo de errores en el desarrollo, la implementación y el mantenimiento del sistema. Esto puede requerir una mayor atención a la calidad del código, pruebas exhaustivas y una gestión cuidadosa de cambios y actualizaciones.

4) Menor rendimiento en algunas operaciones: Aunque las tecnologías que he propuesto están optimizadas para diferentes tipos de operaciones (por ejemplo, Spark Streaming para procesamiento en tiempo real, Delta Lake y Iceberg para almacenamiento y consulta eficientes, y Apache Hudi para operaciones de escritura ACID distribuidas), puede haber escenarios donde el rendimiento no sea óptimo en comparación con un enfoque de procesamiento en batch más tradicional. Esto podría deberse a la complejidad adicional de la arquitectura o a las características específicas de las tecnologías involucradas. Aunque estamos hablando básicamente de dejar atrás un tipo de tecnología como Apache Impala que de por sí es todo un cluster para si acaso delegar su uso en una versión de Spark más moderna como es Delta Lake, junto con una serie de añadidos en forma de librerias que dan ciertas características en mi opinión muy beneficiosas para el streaming consistente y distribuido en tiempo real.

Como en todo, al final se trata de probar y medir con respecto al pasado.

En principio, creo que esta aproximación tiene más ventajas que desventajas. La principal desventaja que yo veo es que el estado de la tecnología a lo mejor no está suficientemente maduro como para que las tres tecnologías trabajen bien en conjunto, por lo que no queda más remedio que crear prototipos.

La principal ventaja sin duda es conseguir todas las ventajas que dan estos tres frameworks que de por sí solos no pueden.

Me pregunto si alguien en el mundo tiene los recursos necesarios. A mí me encantaría montar un cluster de este tipo para hacer procesamiento en tiempo real.

Un saludo, Alonso

Deja un comentario