divergencia de datos

Una guía para resolver la divergencia de datos en SQL

La divergencia de datos, es decir, las diferencias en los resultados generados a partir de versiones antiguas y nuevas de la arquitectura de datos, es el resultado de una serie de problemas en curso. Afortunadamente, existe un método relativamente sencillo para resolver el problema.

En mi trabajo como ingeniero de datos, uno de los problemas más desafiantes e interesantes que he enfrentado es la cuestión de resolver la divergencia en los datos. La divergencia se refiere a las diferencias en los resultados de los datos generados a partir de versiones antiguas y nuevas de nuestra arquitectura de datos. Es una heurística simple que, cuando se aplica de manera inteligente, permite que las arquitecturas de datos migren rápidamente y con confianza.

Al resolver problemas antes de mi trabajo actual, como desarrollar aplicaciones CRUD o marcos ETL, trabajé principalmente con código. El código es bueno en algunos aspectos. Te da cosas. Apila seguimientos que señalan exactamente dónde cometiste un error. Registros que le indican la actividad histórica de un servicio. Primitivos de control para describir el flujo de control exactamente como lo desea. Pruebas unitarias y simulacros que le permiten evaluar de manera rápida y decisiva la lógica que está describiendo de manera efectiva antes de implementar un cambio. Todas estas características ayudan a crear productos de propósito general, escalables y confiables.

¿Qué es la divergencia de datos?

La divergencia se refiere a las diferencias en los resultados de los datos generados a partir de versiones antiguas y nuevas de la arquitectura de datos. Es una heurística simple que, cuando se aplica de manera inteligente, permite que las arquitecturas de datos migren rápidamente y con confianza.

Ahora, sin embargo, trato principalmente con datos, y estos conceptos se han desglosado un poco para mí. En el trabajo, uso principalmente GCP BigQuery y SQL, y los datos ingresan en diferentes puntos de nuestra pila tecnológica y a través de diferentes marcos. Nos hemos estandarizado en SQL por ahora porque varios departamentos pueden trabajar con él, lo que permite niveles más altos de colaboración. La creación de prototipos, al tiempo que permite plazos de entrega más cortos en el desarrollo, también es mucho más fácil de esta manera. 

Sin embargo, SQL viene con compensaciones. Como lenguaje específico de dominio, está estrechamente relacionado con los datos que debe representar, y eso dificulta la ejecución de pruebas de integración y casi imposible ejecutar pruebas unitarias, especialmente porque BigQuery es nativo de la nube. Si obtiene una consulta SQL incorrecta, no verá un mensaje de error, sino resultados defectuosos. Dado que no hay errores graves, me he encontrado a mí mismo confiando en los mensajes de registro para descifrar lo que sucedió más de lo que me gustaría.

Todavía estamos en los primeros días del diseño de nuestra arquitectura de datos, y estoy consciente de mantener la confianza de las partes interesadas en nuestros datos lo más alto posible mientras también desarrollamos esta arquitectura para satisfacer las necesidades del mañana. Por lo tanto, me he encargado de impulsar un modelo de » tic-tac » para el desarrollo de nuestra arquitectura de datos. En este enfoque, primero desarrollamos la arquitectura de datos mientras mantenemos exactamente los mismos resultados de datos («tick»), luego actualizamos los resultados de los datos para cumplir con los requisitos actualizados («tock»). Este enfoque equilibra las necesidades de las partes interesadas que obtienen información y otras solicitudes del equipo de ingeniería de datos, así como las necesidades internas de ingeniería en torno a la infraestructura y las operaciones.

Más en Ingeniería de Software: Ahórrese un dolor de cabeza y documente los criterios de aceptación de su proyecto desde el principio

Detectar divergencia

Ahora, entramos en el problema de la divergencia. En este contexto, uso la palabra «divergencia» para denotar las diferencias entre los resultados de los datos generados a partir de versiones antiguas y nuevas de nuestra arquitectura de datos. Por ejemplo, cuando migramos de una canalización de procesamiento por lotes a una versión de transmisión para permitir la lectura de datos en diferentes servicios de ingeniería, aún queremos preservar nuestra confiabilidad en el análisis por lotes para mantener un alto nivel de confianza de las partes interesadas y, por lo tanto, nuestra propia libertad de acción en haciendo mejoras confiables. Minimizar esta divergencia es nuestro objetivo para completar la parte de «tick» del desarrollo.

En mi experiencia, los datos siempre exhibirán al menos alguna divergencia, que es el resultado de múltiples factores. Los datos se actualizan a diferentes velocidades según las opciones de configuración del marco. También recopilamos datos en diferentes puntos de nuestra pila tecnológica, lo que significa que contiene información diferente según el estado de la aplicación. Finalmente, los datos pueden perderse si pasan por etapas con pérdidas de una canalización de datos. Por ejemplo, BigQuery SQL mantiene los valores de marca de tiempo con una precisión de seis microsegundos. Si los datos se canalizan a una lambda de JavaScript que mantiene tres microsegundos de precisión, el resultado tendrá una precisión de tres microsegundos, perdiendo los últimos tres dígitos de precisión.

Para documentar todo esto, escribimos informes de divergencia que detallan cuántos registros son diferentes entre los dos sistemas, qué columnas o campos se ven necesariamente afectados por esas diferencias y qué explicaciones podríamos brindar a las partes interesadas con respecto a estos cambios para su revisión y aprobación. Esto se adhiere a nuestra cultura interna de documentación, lo que permite a las partes interesadas revisar si los cambios en los resultados de los datos son aceptables para sus propósitos y proporciona una vía de comunicación y una plataforma para una mayor discusión y colaboración en torno a sus necesidades. En la práctica, el acto de crear estos informes ha mantenido nuestra divergencia en niveles bajos y comunica exactamente qué tan bajos son esos niveles.

Cálculo y resolución de la divergencia

Entonces, ¿cómo calculamos la divergencia? Este cálculo tiene tres pasos de preprocesamiento:

  • Seleccione una ventana de datos para comparar.

  • Seleccione los campos para la comparación.

  • Deduplicar cada registro, garantizando la unicidad.

Primero, es posible que deseemos obtener una ventana de datos de ambos conjuntos de datos para comparar las diferencias. Aunque esto puede no ser necesario si su conjunto de datos es lo suficientemente pequeño como para consultarlo en su totalidad, se vuelve más importante a medida que crece el conjunto de datos. Queremos que la lógica de comparación sea rápida o factible sin una configuración adicional en BigQuery. Ejecutar una consulta where sobre columnas de marca de tiempo seleccionadas en ambos conjuntos de resultados es fundamental para obtener estas ventanas. 

Las cosas simples, como la correlación de marcas de tiempo, pueden ser complicadas. Durante ciertos trabajos de reposición, cuando tuve que transformar datos de cadenas XML sin procesar almacenadas en la base de datos a JSON desnormalizado para volver a normalizar en nuestro almacén de datos, las marcas de tiempo para los objetos creados coincidieron con la hora del trabajo de reposición y no con la hora en que se recuperaron los datos. fue cargado por primera vez. Tuve que unir las marcas de tiempo originales a la tabla recién creada para proporcionar datos precisos. Las implicaciones de este problema, que incluyen poder unir estos datos a otros conjuntos de datos, habla de la importancia de otras prácticas recomendadas de ingeniería de datos como «añadir siempre campos, nunca sobrescribirlos» (para eliminar la ambigüedad de los tiempos de creación/actualización para el reabastecimiento y el original). ingesta), y cómo se cruzan con este tipo de trabajo.

No podemos comparar todas las columnas, ya que es casi seguro que algunos datos sean diferentes. Por ejemplo, descubrí que si ingiere datos con Stitch Data, se crearán columnas `_sdc_*` especiales dentro de su receptor de BigQuery. Este problema surge de la política de Stitch Data de copiar registros al menos una vez, pero no exactamente una vez, lo que le permite a la agencia deduplicar sus propios datos. Esto difiere de agregar la integración de BigQuery para Segment, donde la información se deduplica a través de la propia integración. Por lo tanto, podemos filtrar por el conjunto de columnas que queremos asegurarnos de que sean iguales.

Una de las claves para verificar si dos registros son iguales o diferentes es asegurarse de que está comparando un registro con otro, y no un grupo de registros con otro grupo ligeramente diferente. He encontrado que el concepto de unicidad es bastante poderoso para hacer que la comparación de registros sea simple y rápida de verificar. Mantener un índice único puede ser fácil o difícil según sus necesidades. Por ejemplo, al desduplicar tablas administradas por un ORM y copiadas a través de Stitch Data, se trata de identificar la clave de replicación, eliminar las columnas específicas de Stitch Data y ejecutar seleccionar distinto. Cuando se creaba un índice desde cero para que coincidiera con la lógica clave en un almacén de datos externo, la unicidad tenía que garantizarse a mano en todas las condiciones de combinación, lo que llevó mucho más tiempo y es más difícil de garantizar.

Una vez que se han completado estos pasos de procesamiento, el resto de la comparación es bastante fácil:

  • Ordene las columnas de la misma manera para ambos conjuntos de datos
  • Union distingue los dos conjuntos de datos

  • Ejecute un grupo agregado sobre el índice único y filtre los valores de índice que aparecen dos veces (lo que indica alguna diferencia en los siguientes valores) utilizando el recuento (*) > 1

  • Unir a la izquierda los conjuntos de datos antiguos y nuevos con la lista procesada de índices en dos tablas separadas

  • Una los dos conjuntos de datos y ordene todas las columnas para que los datos duplicados sean fáciles de identificar todos a la vez y a simple vista.

¡Y voilá! Su informe de divergencia, como SQL, está completo.

En última instancia, este proceso de cálculo de divergencia solo es relevante si está utilizando SQL. Si sus conjuntos de datos crecen hasta el punto en que lleva más tiempo ejecutar un comando de selección* que calentar una máquina virtual (según mi experiencia, alrededor de 25 minutos), o si está obteniendo fuentes de datos diversas como videos o archivos PDF, entonces puede considerar usar una solución completa como Apache Beam/GCP DataFlow u otra solución que incluya un lenguaje de propósito general con un SDK y un ecosistema de herramientas. Estoy seguro de que volveremos a evaluar nuestro enfoque a tiempo; en este momento, sin embargo, este enfoque funciona muy bien para mí.