Portada » Ingeniería de datos != ingeniería de software

Ingeniería de datos != ingeniería de software

by Donal Sandro Noblejas Huaman
Ingeniería de datos != ingeniería de software

En los últimos años, hemos visto cómo la ingeniería de datos se fusiona cada vez más con la industria DevOps. Ambas direcciones usan infraestructura en la nube, contenedorización, CI/CD y GitOps para entregar productos digitales confiables a los clientes. Esta convergencia en términos de usar el mismo conjunto de herramientas ha llevado a muchos a pensar que la ingeniería de datos no es significativamente diferente de la ingeniería de software. Como resultado, el primero resulta ser “imperfecto”, ya que los ingenieros de datos se están quedando atrás en la implementación de prácticas efectivas de desarrollo de software.

Pero tal evaluación es incorrecta. Aunque existen muchas herramientas y prácticas comunes en el procesamiento de datos y el desarrollo de software, existen varias diferencias significativas entre ellas. Ignorar estas diferencias y gestionar un equipo de ingeniería de datos como un equipo de desarrollo de software es un error. Entonces, el propósito de este artículo es resaltar algunos de los desafíos únicos en la ingeniería de datos y explicar por qué esta área a veces requiere un enfoque especial.

Las canalizaciones de datos no son aplicaciones

El desarrollo de software significa crear aplicaciones. En el contexto de este artículo, el término aplicación tendrá un significado muy amplio, es decir, tanto un sitio web como una aplicación de escritorio, una API, un juego, un microservicio, una biblioteca, etc. Lo que une a todos estos tipos de aplicaciones es que:

  • Aportar valor a los usuarios ofreciendo un nuevo modelo de interacción. El juego se puede jugar, el sitio se puede ver, la API se puede usar en otro software.
  • Tienen una serie de características en su mayoría independientes. El sitio puede crecer en páginas, el juego puede aumentar la cantidad de niveles o personajes disponibles y se pueden agregar nuevos puntos finales a la API. La conclusión es que una aplicación nunca está realmente completa.
  • Pocos trabajan con los estados que crean. El estado está destinado a respaldar la aplicación y, por lo general, lo administra un sistema externo. El punto es que la mayor parte del software funciona sin el uso de estados. La aplicación web se puede cerrar y reiniciar en cualquier momento: su estado lo administra una base de datos que se ejecuta en un proceso separado.
  • Débilmente conectado con otro software y servicios. Un buen software debería funcionar de forma independiente en cualquier entorno, lo que explica la popularidad de los microservicios y los contenedores.

Si hablamos de ingenieros de datos, entonces se dedican a construir canalizaciones de datos. Dichos pipelines reciben datos de su creador, transforman estos datos y los transfieren al consumidor. Por lo general, el objetivo es automatizar la operación de estas canalizaciones según un cronograma para que los conjuntos de datos se actualicen periódicamente con nuevos datos. Al igual que las aplicaciones, los conductos suelen ser programas, pero se diferencian de ellos en los siguientes aspectos:

  • No proporciona ningún valor inmediato. La canalización no tiene usuarios. Los usuarios finales solo necesitan los conjuntos de datos que producen. Si estos datos llegan a su destino a través de algún intrincado esquema de copiado, entonces esta opción se adaptará al consumidor.
  • Solo tienen un aspecto de importancia para el consumidor, a saber, crean el conjunto de datos solicitado. Por lo tanto, existe un punto de terminación explícito, aunque la tubería en sí requiere un mantenimiento continuo debido a los cambios en los requisitos del usuario en el sistema aguas arriba.
  • Administrar una gran cantidad de estados. La tubería está diseñada para procesar el estado existente de otro software que no está controlado por él y transformarlo en uno controlado. Muchas canalizaciones construyen conjuntos de datos en etapas, introduciendo nuevos datos en ellos con cada paso. En este sentido, pueden verse como procesos muy largos, creando continuamente más y más estados.
  • Inevitablemente tener un agarre fuerte. El propósito de una canalización es vincularse a una fuente de datos. Como resultado, su estabilidad y confiabilidad siempre dependerán de la estabilidad y confiabilidad de esta fuente.

Estas diferencias fundamentales plantean desafíos únicos para los ingenieros de datos que a menudo no son bien entendidos por los propietarios de negocios, la administración de TI e incluso los desarrolladores de software.

Hablaremos de estos desafíos más adelante.

La canalización está completa o es inútil

Hoy en día, muchas organizaciones administran sus equipos de desarrollo de software utilizando uno de los marcos Agile. La filosofía principal de esta metodología es maximizar la velocidad de entrega de valor al consumidor mediante la creación y liberación de elementos de software en ciclos a corto plazo. El objetivo es entregar un producto mínimo viable (MVP) a los clientes lo más rápido posible y proporcionar comentarios rápidos que permitan a los desarrolladores trabajar continuamente en las funciones que tienen la máxima prioridad.

Pero estos principios ya no se aplican a la ingeniería de datos.

La tubería de datos no se puede desarrollar en pequeñas iteraciones con un valor creciente para el cliente. La canalización no tiene un equivalente de MVP: crea el conjunto de datos necesario para el consumidor o no.

Por lo tanto, el diseño de una canalización de datos no se ajusta a los esquemas ágiles. Una canalización compleja corresponde a una sola historia de usuario, pero normalmente requiere varios sprints para completarse. La gestión no técnica rara vez considera este matiz sutil y trata de todos modos de encajar a los ingenieros de datos en los equipos de scrum. Como resultado, las historias de usuario se reemplazan con tareas como “crear un conector API” y “construir lógica de consumo”, lo que inevitablemente convierte al tablero Scrum en una herramienta de microgestión.

La falta de comprensión por parte de los líderes de los conceptos básicos de lo que administran a menudo conduce a decisiones ineficientes e incluso que no funcionan. Una vez, un gerente, enojado con el lento progreso de la creación de una canalización, exigió que un ingeniero de nuestro equipo creara un conjunto de datos de forma iterativa, columna por columna, para que el cliente “tuviera al menos algunos datos para comenzar a trabajar”. Los ingenieros con experiencia práctica en canalizaciones complejas y los analistas de datos que han tenido un conjunto de datos inútil comprenderán lo ridículo de esta situación. Para aquellos lectores que no tengan tal experiencia, daré tres razones por las que este enfoque no funcionará:

▍ 1. El valor de un conjunto de datos parcial no se calcula proporcionalmente

Si un conjunto de datos tiene 9 columnas de 10, ¿eso significa que es útil en un 90 %? Todo depende de qué columna falta. Si el analista va a construir un modelo predictivo basado en estos datos, pero la columna que falta representa etiquetas o valores predichos, entonces el beneficio del conjunto de datos será del 0 %. Si esta columna contiene algunos metadatos aleatorios que no están asociados con las etiquetas, dicho conjunto de datos puede ser 100 % útil.

La mayoría de las veces, una columna representa un campo que puede o no estar asociado con etiquetas. Averiguar si está realmente conectado con ellos es el objetivo de los experimentos del analista de datos. Por eso necesita el conjunto de datos más completo, sobre la base del cual puede comenzar a estudiar los datos y optimizar el modelo. Como resultado de proporcionar un conjunto de datos parcial, los experimentos y la optimización deberán realizarse nuevamente a medida que aparezcan los campos restantes.

▍ El tiempo de desarrollo de la tubería no se correlaciona con el tamaño del conjunto de datos

Incluso si el cliente está satisfecho con la mitad del conjunto de datos, la creación de esta mitad no llevará ni la mitad de tiempo de lo que podría pensar. La canalización de datos no consta de tareas independientes, cada una de las cuales crearía una columna. Se pueden relacionar varias columnas si provienen de la misma fuente, en cuyo caso incluir al menos una o varias de ellas en el conjunto de datos final supondrá la misma cantidad de trabajo.

Sin embargo, la lógica para fusionar estas columnas con columnas en otra tabla puede ser tan simple como unir o requerir una serie compleja de funciones de ventana. Además, la canalización para generar datos procesados puede requerir escribir una gran cantidad de código repetitivo, por ejemplo, un cliente para acceder a una API o un analizador para procesar datos no estructurados.

Después de escribir un componente de este tipo, lo más probable es que sea fácil ampliar la lógica para manejar campos adicionales. Por lo tanto, la cantidad de columnas en el conjunto de datos final es completamente inapropiada como métrica para evaluar su complejidad, al igual que la cantidad de líneas de código escritas no es adecuada para evaluar la productividad.

El tamaño del conjunto de datos también puede referirse al número de filas/registros. Una canalización bien construida debe poder procesar cualquier cantidad de registros, por lo que este criterio no afectará el tiempo de desarrollo. Aunque en su proceso puede haber “saltos” provocados por condiciones específicas como:

  • ¿Con qué frecuencia se debe actualizar el conjunto de datos? Es decir, ¿necesita implementar una actualización por lotes o secuencia?
  • ¿Cuántos datos esperamos ya qué velocidad?
  • ¿Estos datos caben en la RAM?

Todos estos puntos deben conocerse de antemano, ya que afectarán toda la estructura de la tubería.

▍ 3. Los costos de tiempo y recursos se correlacionan con el tamaño del conjunto de datos

Cuantas más filas y columnas haya en el conjunto de datos, más tiempo llevará construirlo y actualizarlo. Editar un solo registro en una base de datos enorme es fácil y rápido, pero en conjuntos de datos para análisis, tales casos, por regla general, no ocurren. Cambiar un conjunto de datos de este tipo generalmente significa agregar/ajustar columnas enteras (lo que resulta en cambios en todos los registros) o actualizar miles/millones de filas. La corrección de datos se puede manejar de dos maneras, ninguna de las cuales es barata.

Desde la perspectiva de un desarrollador, la forma más fácil de cambiar un conjunto de datos es actualizar la canalización y volver a ejecutarla. Sin embargo, esta resulta ser la opción más costosa en términos de costos computacionales y el tiempo requerido para actualizar el conjunto de datos. Diseñar una tubería para reescribir correctamente el estado de ejecuciones pasadas (ser idempotente) tampoco es siempre una tarea fácil y, a menudo, requiere una planificación adecuada por adelantado.

Alternativamente, la lógica para actualizar el conjunto de datos se puede codificar en una canalización separada que tomará el conjunto de datos antiguo como entrada. Este enfoque será más económico en términos de computación y velocidad, pero requerirá más tiempo de desarrollo y agregará una carga de trabajo mental adicional. Las canalizaciones que usan deltas no son , por lo que realizar un seguimiento del estado actual también es importante cuando se realizan operaciones específicas. Incluso entonces, las canalizaciones más antiguas deben actualizarse para adaptarse a los cambios en las versiones más nuevas.

Sea como fuere, la tarea resulta difícil, ya que la inercia es inherente a los conjuntos de datos: cuanto mayor sea su tamaño, más tiempo, esfuerzo y dinero se requieren para realizar cambios.

▍ Conclusión: no tiene sentido desplegar un pipeline parcial en producción

La implementación de una tubería parcialmente terminada en producción no beneficiará al cliente, pero desperdiciará recursos informáticos y dificultará la vida de los ingenieros, ya que tendrán que trabajar adicionalmente con el estado anterior. Inyectar ciegamente DevOps y Agile en el desarrollo de canalizaciones de datos, donde se fomentan los cambios incrementales y las implementaciones frecuentes, simplemente significa ignorar la inercia de datos descrita.

Cualquier ingeniero preferiría “hacerlo bien la primera ” y minimizar el número de implementaciones en producción. La implementación frecuente de la canalización indica que el cliente no sabe lo que quiere o que la fuente de datos es muy inestable y la canalización debe actualizarse constantemente. A diferencia de las aplicaciones sin estado, donde la actualización suele ser comparable en complejidad a la eliminación de un par de contenedores y el lanzamiento de dos nuevos, actualizar un conjunto de datos no es lo mismo que volver a implementar el código de canalización. Y empaquetar este código en un contenedor y luego ejecutarlo en Kubernetes no compensa esta brecha.

Los bucles de retroalimentación en el desarrollo de tuberías son muy largos

Para crear rápidamente una nueva funcionalidad o corregir errores en el software, los desarrolladores necesitan comentarios para asegurarse de que el código que escriben dirija el programa en la dirección correcta.

En el desarrollo de software, esta relación se suele lograr a través de pruebas unitarias que el programador ejecuta localmente para verificar que cada componente funciona correctamente. Las pruebas unitarias deben ser rápidas, no estar conectadas a ningún sistema externo y no depender de ningún estado. Deben probar funciones, métodos y clases de forma independiente. En este caso, el programador recibe retroalimentación rápida durante el desarrollo y puede estar seguro de que en el momento de la solicitud de extracción, su código funcionará correctamente. Si es necesario probar la interoperabilidad con otros sistemas, la canalización de CI también puede incluir pruebas de integración más lentas.

Permítanme compartir un secreto de los ingenieros de datos: las canalizaciones de datos rara vez se ejecutan a través de pruebas unitarias (¡sorpresa!). Por lo general, ya se prueban durante la implementación; por regla general, primero en el entorno de desarrollo. Esto requiere una fase de construcción e implementación, después de la cual el ingeniero debe monitorear la tubería durante algún tiempo, asegurándose de que funcione correctamente. Si la canalización no es idempotente, es posible que volver a implementar primero requiera una intervención manual para restablecer el estado dejado por la implementación anterior. Este ciclo de retroalimentación es muy lento en comparación con las pruebas unitarias.

Entonces, ¿por qué no simplemente escribir pruebas unitarias?

▍ 1. Las canalizaciones de datos son vulnerables en lugares que no se pueden verificar mediante pruebas unitarias

La lógica autónoma que se puede probar mediante pruebas unitarias suele estar limitada en las canalizaciones de datos. La mayor parte de su código es “acoplar componentes y muletas”, por lo que casi todas las fallas ocurren en interfaces torpes entre sistemas o cuando ingresan datos inesperados en la tubería.

Las interfaces entre sistemas no se pueden probar mediante pruebas unitarias porque estas pruebas no se realizan de forma aislada. Se pueden simular sistemas externos, pero esto solo confirmará el correcto funcionamiento del transportador con el sistema actuando como imagina el ingeniero. En realidad, un ingeniero rara vez conoce todos los detalles.

Tomemos un ejemplo de la vida real: para evitar ataques DDOS, una API pública puede tener un límite oculto en la cantidad de solicitudes permitidas desde una IP en un cierto período de tiempo. Es poco probable que el diseño de dicha API tenga en cuenta este matiz, pero el hecho de que exista en un sistema real puede romper la tubería en producción. Además, los sistemas externos rara vez son estables. De hecho, las canalizaciones de datos generalmente se crean porque las personas quieren mover datos de sistemas inestables a otros más confiables. El diseño no podrá reflejar un posible cambio en el sistema, lo que provocará una falla en la tubería.

Al mismo tiempo, es bien sabido que es raro que un proveedor de datos pueda proporcionarlos consistentemente en una forma de alta calidad. La canalización necesariamente debe tener en cuenta qué datos se le pueden transferir. El contenido o la estructura inesperados, en el mejor de los casos, conducirán a un resultado incorrecto y, en el peor de los casos, harán que falle. La validación de esquemas en lectura se usa normalmente para proteger contra fuentes de datos inestables.

Pero esto no protegerá contra el contenido de datos erróneos y los “errores” sutiles. Por ejemplo, ¿se tiene en cuenta correctamente el período de ahorro de luz en la serie temporal? ¿Hay filas en la columna que no encajan en el patrón esperado? ¿Los valores en la columna de unidades numéricas tienen significado físico? Ninguno de estos ejemplos implica una lógica de canalización que pueda probarse con pruebas unitarias.

▍ 2. Las pruebas unitarias son más complejas que la lógica de tubería

Las pruebas unitarias requeridas para probar la lógica de transformación limitada e independiente son más complejas que el código en sí, ya que el desarrollador debe crear datos de prueba representativos, así como el resultado esperado. Este es mucho trabajo que no aumentará significativamente la confianza en el correcto funcionamiento de la tubería. También reemplaza la pregunta “¿Funciona esta característica como se esperaba?” a “¿Estos datos de prueba representan adecuadamente los datos reales?” Las pruebas unitarias cubren idealmente un buen subconjunto de combinaciones de parámetros de entrada, pero en funciones que convierten un conjunto de datos, por ejemplo, en un marco de datos, el argumento del conjunto de datos en sí mismo representa un espacio de parámetros casi infinito.

▍ Conclusión: los oleoductos tardan en desarrollarse

La mejor manera de obtener comentarios confiables de una canalización de datos es implementarla y ejecutarla. Esta opción siempre será más lenta que ejecutar pruebas localmente, lo que significa que tomará mucho más tiempo recibir comentarios. Como resultado, el desarrollo de canalizaciones, especialmente en la fase de depuración, se mueve con una lentitud molesta.

Aquí puede considerar las pruebas de integración que se ejecutan más rápido que toda la canalización. Sin embargo, por lo general no se pueden ejecutar en la máquina del desarrollador debido a la falta de acceso directo a los sistemas de origen de datos relevantes. Debido a esto, dichas pruebas solo se pueden ejecutar en el mismo entorno que la canalización, lo que, nuevamente, requiere implementación. Resulta que el punto de escribir pruebas para obtener comentarios rápidos desaparece en general.

Ahora está de moda utilizar “contratos de datos” como medio para combatir a los proveedores de datos poco fiables. La confianza en los datos recibidos por los oleoductos eliminaría una gran cantidad de incertidumbre del proceso de desarrollo y los haría menos frágiles. Sin embargo, existe un problema con la aprobación de este tipo de contratos, ya que los proveedores de datos no están interesados en seguir los términos que aprueban. Además, la organización también querrá utilizar datos obtenidos de fuentes externas como las API públicas. ¿Te imaginas también la necesidad de negociar un contrato con estos terceros?

El desarrollo de la tubería no se puede paralelizar

Descubrimos que las canalizaciones de datos son una historia de usuario y se desarrollan lentamente debido al largo ciclo de retroalimentación. Pero dado que la tubería consta de varias tareas, algunos administradores intentan distribuirlas entre varios desarrolladores en un intento de acelerar el proceso.

Desafortunadamente, este enfoque no funciona. Las tareas de procesamiento de datos en una canalización son secuenciales. Para construir el segundo paso, es necesario lograr una salida estable del primero. Por el contrario, los hallazgos del desarrollo del segundo paso permiten realizar mejoras en el primero. En este contexto, la canalización como un todo debe considerarse como una característica que el desarrollador refina iterativamente.

Algunos gerentes creen que esto simplemente significa que la canalización no estuvo bien planificada en primer lugar. Hay datos al principio y está bastante claro qué datos se deben obtener al final. ¿No es obvio entonces lo que se necesita construir en el medio? Paradójicamente, los mismos gerentes que piensan de esta manera defenderán activamente los beneficios de los métodos ágiles.

La planificación de toda la canalización no funciona hasta que la fuente de datos se caracterice correctamente. En ausencia de contratos y documentación, el ingeniero de datos se ve obligado a especular, tratando de descubrir características particulares de los datos. Y este proceso de búsqueda define la arquitectura del pipeline. En cierto sentido, resulta ser flexible. Es solo que esta opción no se adapta a las partes interesadas.

Conclusiones generales y recomendaciones

Las canalizaciones de datos están relacionadas con el software, pero no son productos de software. Son una fábrica que solo monta el coche solicitado por el cliente. Son solo un medio para un fin, una forma de automatizar la creación de un conjunto de datos de fácil consumo a partir de fuentes de datos engorrosas. Los oleoductos son una muleta para vincular sistemas que no interactúan entre sí. Son soluciones torpes, frágiles y costosas para el problema de la última milla de datos. Su único trabajo es administrar el estado, lo que hace que su desarrollo sea lento, impredecible y, a menudo, el mayor cuello de botella en los proyectos de análisis de datos.

No importa lo que afirmen las autoridades de datos, imponiendo alguna herramienta siguiente, no importa cuántas capas de abstracción se superpongan, los datos son fundamentalmente diferentes del software. Negarse a reconocer estas diferencias e intentar imponer procesos Agile en un equipo de datos solo porque trabajan en un equipo de desarrollo de software solo resultará contraproducente.

¿Qué se puede hacer para aumentar el éxito y la productividad de los ingenieros de datos?

  • Reconocer que una forma ligera de modelo en cascada (Cascada, generalmente considerada como un mal enfoque en el desarrollo de software) en los proyectos de canalización de datos es inevitable. Antes de comenzar el desarrollo, es necesario discutir cuidadosamente con los clientes los requisitos para el conjunto de datos que necesitan, así como discutir con los proveedores de datos la transferencia de información sobre las API no documentadas y la conexión al sistema de origen. No dedique mucho tiempo al desarrollo hasta llegar a un acuerdo con sus clientes y proveedores de datos. Reconozca que una vez que la tubería esté en producción, cualquier cambio adicional será costoso.
  • Permita que los ingenieros de datos experimenten con las fuentes de datos. Reconocer que todas las estimaciones aproximadas del tiempo de preparación del conjunto de datos serán erróneas.
  • No divida el trabajo de canalización entre varios desarrolladores. En su lugar, deje que dos o más personas trabajen juntas. Las técnicas de programación de pares/extremas/grupos dentro de la rama principal permitirán la máxima productividad, ya que este enfoque elimina la confusión en la bifurcación de git, las solicitudes de extracción y las revisiones de código. La inspección regular del código con doble ojo es excelente para detectar problemas, lo que es especialmente valioso para las canalizaciones con bucles de retroalimentación muy lentos.
  • Los estaré esperando

Autor Donal Sandro Noblejas Huaman

Lima Perú 

You may also like

Leave a Comment

Are you sure want to unlock this post?
Unlock left : 0
Are you sure want to cancel subscription?
-
00:00
00:00
Update Required Flash plugin
-
00:00
00:00