A medida que el análisis de datos tiene cada vez más impacto, los equipos de datos crecen y los conjuntos de datos se vuelven más numerosos. Esto implica nuevos desafíos de colaboración y eficiencia, así como de calidad y capacidad de descubrimiento.

En Nubank, el banco digital más grande del mundo con 40 millones de clientes, los datos son el centro de nuestro negocio, desde la toma de decisiones automáticas de suscripción de crédito hasta el envío de comunicaciones personalizadas o la generación de informes regulatorios. Contamos con una plataforma de datos de autoservicio donde todos pueden consultar cualquier dato no restringido (como datos no identificables personalmente), crear tablas y agregarlas a nuestras canalizaciones. En 8 años crecimos hasta alcanzar alrededor de 800 contribuyentes que agregaron 40,000 tablas a nuestras canalizaciones de datos.

Para seguir utilizando los datos de una manera ágil y productiva con el crecimiento de los usuarios y usos de datos, hemos visto que dos factores son clave: la organización del equipo y los estándares de ingeniería para hacer cumplir las buenas prácticas de colaboración. 

En términos de organización del equipo, creamos el rol de Ingeniería de Análisis, una función dedicada a la estrategia y gestión de datos, en términos de calidad, privacidad, confiabilidad, arquitectura y costos. Los ingenieros de análisis están distribuidos en la mayoría de los equipos multifuncionales y de productos. Trabajan en estrecha colaboración con un equipo de plataforma de datos centrado en infraestructura y herramientas.

En términos de estándares de ingeniería, hemos creado herramientas y procesos técnicos que nos permiten hacer que la organización prospere, permitiendo a los contribuyentes de datos trabajar de forma autónoma y productiva, aprovechando el trabajo de otros a lo largo del tiempo.

¿Cuáles son esos estándares de ingeniería que permiten trabajar con datos de manera más eficiente y colaborativa?

En este artículo, te explicaremos cómo utilizamos los estándares de ingeniería de software para:

  • Parte 1: Permitir contribuciones autónomas y estructuradas
  • Parte 2: Aprovechar el trabajo en equipo y la colaboración
  • Parte 3: Simplificar la propiedad del ciclo de vida de los datos 
Software engineering best practices making data work more efficient and collaborative
Mejores prácticas de ingeniería de software que hacen que el trabajo de datos sea más eficiente y colaborativo

Check our job opportunies

Parte 1:  Permitiendo contribuciones autónomas y estructuradas

Para ampliar nuestro proceso de contribución a los canales de datos, intentamos encontrar el equilibrio adecuado entre libertad total y un marco tedioso. Hoy en día, cualquier Nubanker capacitado puede crear una tabla y agregarla al proceso en un par de horas o menos, casi de forma totalmente autónoma, con un proceso de revisión por pares simplificado. Nos permite iterar rápidamente en el trabajo de datos.

Objetos estructurados estandarizados

Todo nuestro sistema de datos se basa en muchos componentes estandarizados en Scala. Cada tabla se crea a través de un objeto estandarizado específico con atributos estructurados. 

Un objeto de tabla de datos en nuestro sistema se compone actualmente de tres tipos principales de atributos:

  • La consulta que declara la transformación
  • La lista de entradas de tabla utilizadas en la consulta
  • Metadatos estructurados como el nombre del conjunto de datos resultante, la descripción del conjunto de datos y de cada columna, el propietario del conjunto de datos, las autorizaciones de protección de datos, a qué capa de calidad pertenece este conjunto de datos, etc.

La lista de entradas nos permite agregar automáticamente la tabla que se ejecutará en la canalización en el lugar correcto del gráfico de dependencia.

En cuanto a los metadatos, dependiendo de la capa de calidad de esta tabla, se requerirán todos o solo parte de los atributos de los metadatos, para asegurarnos de obtener buena documentación para conjuntos de datos de alta calidad, como conjuntos de datos básicos, y limitar la fricción para crear conjuntos de datos experimentales. Los metadatos de autorización requeridos también nos permiten configurar fácilmente la gestión de acceso granular.

Convenciones de nomenclatura, reutilización de métricas y organización de archivos

Para facilitar el descubrimiento de datos y fomentar la coherencia y consistencia de las métricas, implementamos convenciones de nomenclatura no solo para las tablas en sí sino también para las métricas.

También creamos marcos que nos permiten definir una métrica una vez (tanto su código de cálculo como sus metadatos) y reutilizarla en múltiples conjuntos de datos. 


Finalmente, definimos una organización de estructura de archivos específica en nuestro repositorio para asegurarnos de que el descubrimiento de código sea fácil, que todo el código que nuestro canal de datos debe ejecutar esté en el lugar correcto, y que tengamos los accesos adecuados y cumplamos con los requisitos para la gestión de cambios.

Proceso de Prueba de Calidad

Para permitir que cualquiera pueda escribir cualquier consulta y agregarla al proceso, debemos asegurarnos de que se realicen algunos controles de calidad.

Realizamos pruebas de calidad a dos niveles: transformaciones de la propia consulta (pruebas unitarias) y ajuste general con el resto del sistema (pruebas de integración).

En primer lugar, existen múltiples pruebas pequeñas llamadas pruebas unitarias, escritas por los contribuyentes de datos, que verifican que los resultados sean los esperados por las transformaciones.

Escribimos nuestras consultas en Scala, lo que nos permite dividir nuestras transformaciones en pequeñas funciones que pueden (y deben) probarse unitariamente. Para probar las transformaciones de Spark, utilizamos el conjunto de pruebas de Holdenkarau que nos brinda las clases base necesarias para ejecutar consultas de Spark. Una prueba unitaria suele tener este aspecto:

Unit test with Spark
Prueba unitaria con Spark

En segundo lugar, debemos comprobar que si agregamos esta tabla al flujo de datos, encaja bien con el resto del sistema y nada más se verá afectado negativamente. Se llaman pruebas de integración. Para publicar una nueva tabla o realizar cambios en una existente, deben pasar todas las pruebas de integración. Verifican que todas las entradas existan, ya sea otra tabla o una columna de tabla, o que no puedan surgir inconsistencias en el momento de la compilación. Estas pruebas de integración las escribe el equipo de la plataforma central y no es necesario reescribirlas para cada nueva tabla o cambio.  

Parte 2: Aprovechando el trabajo en equipo y la colaboración 

Intercambio de conocimientos en revisiones de código

La revisión por pares finaliza el proceso de contribución a nuestra cartera de datos. Ayuda a garantizar que el código sea de buena calidad y siga las mejores prácticas, además de brindar comentarios prácticos asíncronos al colaborador y capacitar al revisor para que explique sus comentarios. En general, el conocimiento se difunde sin problemas a través de esas revisiones.

Hay dos revisiones para agregar un nuevo objeto a nuestro repositorio de datos: una para verificar la lógica de negocios y otra para verificar las mejores prácticas de Scala, Spark y pruebas.

Los Ingenieros de Analítica y otros colaboradores senior se turnan para dividir las responsabilidades de revisión técnica. Una buena parte de la revisión se centra en garantizar que el código sea claro y legible, dividido en pequeñas funciones y con pruebas unitarias claras. Por lo general, podemos revisar cada solicitud de extracción en el plazo de un día.

Reutilizando código con bibliotecas

Otro estándar para trabajar en grandes proyectos de ingeniería es asegurarse de que los contribuyentes se basen en lo que los demás ya han hecho, para ser más productivos y centrarse en las nuevas incorporaciones.

Una de las razones por las que elegimos tener nuestra base de código de datos en Scala es permitir a los usuarios de datos crear y desarrollar bibliotecas que contengan funciones desarrolladas por otros en el pasado. Los equipos usan, crean y contribuyen a las bibliotecas para reutilizar las mismas estructuras y definiciones en múltiples conjuntos de datos, además de generar series de conjuntos de datos similares mediante programación y agregarlos al proceso ETL. 

Por ejemplo, nuestra plataforma de experimentación genera automáticamente conjuntos de datos con muchas métricas para cada prueba A/B, de modo que se puedan tomar decisiones muy rápidamente sin cuellos de botella en el análisis. 

Esto aumenta la velocidad de entrega de nuevos conjuntos de datos y también simplifica la mantenibilidad y la coherencia, ya que la lógica centralizada se mantiene una vez para múltiples conjuntos de datos. En general, aumenta la eficiencia y la calidad de los análisis.

Documentación y descubribilidad

Una parte clave para colaborar eficazmente es permitir que cualquiera encuentre la información correcta de una manera sencilla. Trabajamos en tener documentación disponible en diferentes niveles: en el proceso de contribución y nuestra plataforma de datos, en el objetivo y propietarios de los conjuntos de datos, y en todas las columnas y métricas de cada tabla.

Estamos creando herramientas y paneles internos para que esta documentación y metadatos sean fácilmente detectables y navegables para que los Nubankers puedan ser más efectivos con el trabajo con datos. Un ejemplo es Compass, nuestro motor de búsqueda de datos interno que obtiene información de los metadatos que generamos. 

Compass, our internal data search engine
Compass, nuestro buscador de datos interno

Parte 3: Simplificando la propiedad del ciclo de vida de los datos

Monitoreo usando metadatos

Necesitamos asegurarnos de que el sistema funcione en su conjunto. El monitoreo nos permite tener planes de gobernanza de datos y OKR, y asegurarnos de que todo sea consistente y de buena calidad con el tiempo. 

En general, monitoreamos la calidad de los datos generados por la consulta, la optimización de la consulta, la experiencia del usuario y los aspectos de gobernanza relacionados con la propiedad de los datos, las dependencias de linaje y las restricciones de acceso. Nuestro monitoreo se basa en nuestros metadatos declarados de nuestros objetos estructurados, así como en métricas calculadas automáticamente como el recuento de filas, el valor promedio de una columna, el horario disponible o el tiempo para ejecutar una consulta.

Mostramos esta información en paneles, así como alertas que envían directamente un mensaje en Slack a las personas responsables activadas por algunas reglas de importancia.

Manteniendo conjuntos de datos a lo largo del tiempo

Los usuarios normalmente esperan que las tablas en la canalización de datos se mantengan correctas con el tiempo. Sin embargo, la innovación iterativa de productos a menudo se correlaciona con cambios en los datos recopilados o en su estructura. Las necesidades de mantenimiento pueden surgir de forma proactiva debido al desarrollo de nuevos productos y la refactorización de servicios, o de forma reactiva a través de alertas de nuestro monitoreo.

Necesitamos asegurarnos de que cuando los productos evolucionen, tengamos las herramientas adecuadas para mantener las tablas afectadas en el futuro.

Al igual que en la ingeniería de software, la documentación, las pruebas unitarias, las pruebas de integración y las comprobaciones de monitoreo son barreras de seguridad para garantizar que cualquier persona pueda actualizar el cálculo del conjunto de datos sin causar problemas ni cambiar el objetivo principal definido por el creador inicial de la tabla. Aunque tenemos propietarios de datos para todos nuestros objetos de datos, este sistema nos permite tener eficiencia operativa, ya que cualquiera puede turnarse para solucionar problemas de datos confiando en la seguridad que brindan las barreras de seguridad.

Gracias a los metadatos utilizados para clasificar tablas en diferentes categorías (conjuntos de datos básicos, conjuntos de datos críticos, entradas de modelos, etc.), tenemos diferentes expectativas con respecto a qué tan rápido se debe resolver un problema y quién debe validar los cambios.

Control de Versiones

Las transformaciones de datos definidas por el usuario, así como las bibliotecas compartidas, se administran en un repositorio git centralizado. Como usamos git, también obtenemos capacidades de control de versiones, así como interfaces simples para revisiones por pares. Eso significa que tenemos un historial rastreable de cambios en la definición de un conjunto de datos. Con este historial, podemos revertir los cambios si es necesario, comprender cómo se generaron estos datos en el pasado o incluso ejecutar una versión anterior de nuestras transformaciones de datos. Esta capacidad de control de versiones ha demostrado ser una de las partes más importantes de nuestro sistema, para retroceder fácilmente cuando algo sale mal y con fines de auditoría.

Conclusión

Cada vez más empresas están invirtiendo en plataformas de autoservicio para eliminar el cuello de botella de un equipo de datos único. Si bien esas plataformas definitivamente fomentan una cultura de datos en toda la empresa, este sistema también plantea muchos desafíos de gobernanza en la práctica. Una organización de personas con responsabilidades claras es clave para abordar esos desafíos. Esos equipos de datos pueden tener un impacto aún mayor con herramientas y prácticas que les permitan colaborar de manera eficiente.

Crear una plataforma modular con objetos estructurados, convenciones de nomenclatura, bibliotecas y prácticas de prueba; hacer cumplir la revisión por pares y la documentación; asegurarnos de que pudiéramos monitorear, mantener y revertir fue crucial para escalar nuestro equipo de datos y aprovechar las oportunidades. 

Los datos han desempeñado un papel clave en el crecimiento de Nubank y probablemente no hubiéramos podido lograr tanto y tan rápido sin este sistema.

Por supuesto, invertir en este tipo de herramientas tiene un costo – tiempo invertido al principio para diseñar e implementar el sistema, más tiempo para que los nuevos miembros avancen, y un aumento marginal del tiempo dedicado a algunos requisitos adicionales (pruebas, documentación, revisión) al contribuir. Descubrimos que esta inversión valió la pena rápidamente ya que nuestros equipos crecieron muy rápidamente (de 0 a 800 contribuyentes de plataforma de datos en 8 años). No hubiéramos podido tener tantas contribuciones individuales en tan poco tiempo sin romper el sistema y hubiera sido mucho más complicado monitorear la calidad.

Capacitar a los usuarios para que innoven de forma autónoma y colaborativa es clave para el éxito de los equipos de datos. Encontrar la cantidad adecuada de herramientas y requisitos para brindar la máxima flexibilidad a los usuarios y al mismo tiempo tener barreras de seguridad de gobernanza es fundamental para escalar el análisis de manera eficiente y confiable, y hay mucho que aprender de las mejores prácticas de ingeniería de software.

Check our job opportunies