Tema representativo de entrevista

Entrevista de Ingeniería de Datos: ¿Cómo realizar un backfill seguro de datos históricos a gran escala?

DatosDifícil
Equipo editorial de Offer.ccPublicado Actualizado

Pregunta

Un pipeline de datos de pedidos procesa 2 TB de datos sin procesar (raw) inmutables por día. Un defecto de transformación afectó las 90 particiones de business_date anteriores, por lo que se deben recalcular 180 TB en un plazo de 5 días. El pipeline diario debe mantener la frescura P95 en 45 minutos o menos, mientras que correcciones tardías pueden actualizar los mismos pedidos que el backfill. Diseñe un backfill histórico repetible, pausible, reanudable y reversible. Explique el presupuesto de capacidad, el aislamiento entre el trabajo activo y el histórico, la validación de datos y la publicación segura.

Prompt y contexto aplicable

Un pipeline de datos de pedidos lee diariamente 2 TB de datos sin procesar inmutables desde un almacenamiento de objetos y genera una tabla orders_daily particionada por business_date. El equipo descubre un defecto en la transformación de impuestos que afecta a 90 particiones. Por lo tanto, debe recalcular 180 TB en un plazo de 5 días. El pipeline incremental diario no puede detenerse; su frescura P95 debe mantenerse en 45 minutos o menos. Además, reembolsos tardíos y correcciones de pedidos pueden actualizar las mismas claves de negocio que el backfill.

Diseñe un backfill que sea repetible, reanudable tras una pausa, auditable y reversible. Explique cómo fijar las versiones de entrada y de código, dividir y programar las particiones, evitar que el trabajo histórico consuma capacidad de producción, resolver la superposición entre el backfill y los incrementos en vivo, definir validaciones que bloqueen la publicación y restaurar la última versión confiable tras un fallo.

El material público reciente para entrevistas de ingeniería de datos aborda explícitamente los backfills históricos, las reejecuciones idempotentes y la preservación del procesamiento en tiempo real como cuestiones de confiabilidad del pipeline. Los escenarios públicos también piden a los candidatos gestionar entradas a escala de terabytes, reprocesamiento de particiones, validación y rollback. La documentación oficial de pipelines expone ejecuciones históricas, políticas de reprocesamiento y límites de concurrencia separados. La intención de búsqueda es concreta: el candidato necesita un plan de producción ejecutable que vaya más allá del simple punto de entrada de programación de “reejecutar los últimos 90 días en Airflow”.

Qué evalúa el entrevistador

La primera señal es si el candidato define una versión de datos reproducible. Una respuesta sólida fija el intervalo del backfill, la fecha lógica, la instantánea (snapshot) o versión de origen, el código de transformación, las versiones de las dimensiones dependientes y el esquema de destino. Si dos intentos leen entradas distintas, o si el código depende de now(), valores aleatorios o búsquedas externas mutables, “seguro para reejecutar” carece de significado comprobable.

La segunda señal es separar el éxito de la orquestación de la corrección de los datos. Un orquestador puede crear ejecuciones para fechas lógicas históricas y limitar la concurrencia. No hace que las escrituras de negocio sean idempotentes ni resuelve un conflicto de escritura entre un incremento en vivo y un backfill histórico. El candidato debe elegir el reemplazo de particiones, un MERGE con clave estable o un destino con control de versiones, y explicar las condiciones previas.

La tercera señal es la capacidad y el aislamiento. Para finalizar 180 TB en 5 días, la tasa promedio mínima de lectura de datos sin procesar es:

text
180 TB / (5 × 24 h) = 1.5 TB/h ≈ 417 MB/s

Ese es un límite inferior para una ejecución continua sin reintentos. Excluye la amplificación de escaneo, el shuffle, las escrituras en destino, la validación y los recálculos fallidos. Una buena respuesta primero evalúa una partición como prueba de referencia (benchmark), mide el rendimiento y los picos de recursos por etapa, y luego establece una cola o grupo de cómputo independiente, límites de concurrencia y prioridad de producción. La frescura del pipeline activo se convierte en una señal de retroalimentación para reducir la tasa del backfill.

La cuarta señal es el límite de publicación y recuperación. Noventa tareas exitosas no hacen que una nueva versión sea segura para los consumidores. Antes de la publicación, el sistema debe demostrar la completitud de las particiones, la unicidad de las claves, los invariantes del negocio, la conciliación con el origen y diferencias consistentes con el defecto. La publicación debe ser una transición de versiones (cutover) controlada. Conserve la versión anterior durante el período de observación para que un rollback consista en cambiar un puntero y no en recalcular nuevamente 180 TB.

Preguntas a aclarar antes de responder

  • ¿La entrada sin procesar es verdaderamente inmutable? Obtenga versiones de objetos, un ID de snapshot o una posición de log reproducible. Si el origen muta datos in situ, cree primero una versión de entrada referenciable.
  • ¿Qué reloj define el intervalo de 90 días? Alinee business_date, la hora del evento, la hora de ingesta y la zona horaria. Además, defina qué partición es propietaria de un reembolso tardío.
  • ¿Cuál es la granularidad de destino y la clave estable? Establezca si una fila representa un pedido, un ítem de pedido o un agregado diario, y si existen order_id, source_version y un orden determinista de resolución de conflictos.
  • ¿De qué datos mutables depende la transformación? Tipos de cambio, reglas impositivas, dimensiones SCD y registros de eliminación deben leerse a la fecha/hora histórica del evento, sin reemplazarse silenciosamente por los valores de hoy.
  • ¿Qué particiones puede actualizar el incremento en vivo? Si solo escribe en los últimos 7 días, el backfill puede ser propietario de las particiones anteriores. Si cualquier pedido histórico puede cambiar, se requiere ordenamiento por versión o nivelación de deltas (delta catch-up).
  • ¿Qué funciones de aislamiento y publicación atómica existen? Un data warehouse separado, un pool de recursos, una cola de prioridad, transacciones de partición, clonación de tablas, cambio de vistas (view cutover) o punteros de catálogo modifican el diseño.
  • ¿Son los 5 días un plazo estricto o un objetivo? Obtenga el objetivo de frescura P95 en vivo, la cuota de lectura del origen, el límite de costos y cualquier ventana breve permitida para el cutover.
  • ¿Quién aprueba? Las aserciones técnicas, la conciliación financiera, el muestreo aguas abajo y el período de observación necesitan cada uno un responsable y un umbral de bloqueo.

Estructura de respuesta de 30 segundos

“Fijaría las 90 fechas de negocio, el snapshot de entrada y la versión del código, y luego escribiría cada partición de fecha lógica en un área de staging aislada con un manifiesto. Procesar 180 TB en 5 días requiere al menos unos 417 MB/s, por lo que primero haría un benchmark y aplicaría limitación (throttling) cuando el P95 en vivo se acerque a los 45 minutos. Tras el backfill de W0, nivelaría los cambios hasta W1 y haría el cutover solo tras validar el 100 % (90/90) de las particiones, la conciliación y los controles de negocio. La versión anterior se mantiene disponible para rollback”.

Análisis detallado paso a paso

Paso 1: Definir el backfill como una especificación de ejecución inmutable

Cree un backfill_id y registre lo siguiente:

CampoEjemploPropósito
Rango[2026-04-01, 2026-06-29], 90 particionesEvitar que los límites varíen durante la ejecución
Entradaraw_snapshot=s_1042, watermark W0Garantizar que cada intento lea los mismos hechos
Lógicacode_sha=abc123, tax_rules=v17Fijar versiones de transformación y dependencias
Salidaorders_daily__bf_20260718Aislar el resultado candidato de la versión de confianza
RecursosPool de backfill, concurrencia máxima, cuotas de lectura/escrituraProteger el SLO de producción
CompuertasClave única, delta de importes, completitud, aprobadorHacer que 'terminado' sea un estado determinable

Pase business_date a cada ejecución de partición. No sustituya la hora real del reloj por la hora lógica dentro de la transformación. Cuando los tipos de cambio históricos o las dimensiones SCD sean dependencias, realice un join 'as-of' al momento del evento. Un cambio en la entrada, el código o cualquier versión de dependencia crea un nuevo backfill_id; no mezcle dos versiones de resultados dentro de una misma ejecución.

Genere un plan sin escribir en el destino de producción. Liste las 90 particiones, el orden de dependencias, los bytes de entrada estimados, la concurrencia propuesta y las rutas de destino. Detecte brechas, fechas duplicadas, particiones fuera de la retención de origen y efectos secundarios aguas abajo. Deshabilite efectos no relacionados con datos como correos electrónicos, facturación y llamadas a API externas, o rediríjalos a modo de auditoría, para que la reproducción histórica no vuelva a disparar acciones de negocio reales.

Paso 2: Utilizar un manifiesto de particiones para pausar, reanudar y auditar

Trate cada business_date como una unidad de trabajo delimitada. El manifiesto debe registrar como mínimo:

text
backfill_id, business_date, input_snapshot, code_sha,
state, attempt, input_rows, output_rows, output_checksum,
staging_location, published_version, started_at, completed_at

Un modelo de estados útil es PENDING → RUNNING → VALIDATED → PUBLISHED, pasando los fallos a FAILED. Reclame una unidad mediante una actualización condicional o concesión (lease) para que una partición tenga solo un ejecutor activo. Un lease expirado puede volver a reclamarse. Reintente únicamente la partición fallida y escriba otro intento aislado en staging para esa partición; nunca realice un append ciego a la tabla final.

Si una partición de fecha está completamente cerrada, la escritura idempotente más simple es construir la partición completa y luego reemplazarla transaccionalmente. Si un pedido puede corregirse a través de distintas fechas, use una clave de negocio estable y una versión de origen en un MERGE. Defina un criterio de desempate explícito, como source_updated_at seguido de un source_sequence monotónico en caso de empate. Un MERGE evita que un registro histórico antiguo reemplace una corrección reciente solo si la clave primaria, la versión y la semántica de eliminación son totalmente confiables.

Paso 3: Deducir la concurrencia a partir de mediciones en lugar de adivinar el recuento de hilos

El requisito de 180 TB en 5 días impone un límite inferior de lectura sin procesar de aproximadamente 417 MB/s. Ejecute una prueba canaria en 1 partición representativa y mida bytes, duración, CPU, memoria, tiempo en cola del warehouse y espacio temporal para lectura, descompresión, shuffle, transformación, escritura y validación. Si una partición ofrece r MB/s de rendimiento efectivo, el límite inferior teórico de concurrencia es de aproximadamente ceil(417/r). Las cuotas de origen, los picos de shuffle, la capacidad de commit en destino y los límites de costos restringen aún más el valor real.

Asigne al backfill un pool de cómputo o cola independiente con menor prioridad que el incremento diario. Limite en conjunto la concurrencia del programador, las lecturas de origen, las escrituras en destino y el costo total; limitar solo uno suele ser insuficiente. Un controlador supervisa la frescura P95 del pipeline en vivo, las colas del data warehouse y la limitación (throttling) del origen. Cuando la frescura se acerca a los 45 minutos, deja de reclamar nuevas particiones o reduce la concurrencia. Vuelve a aumentarla gradualmente solo después de que el pipeline en vivo regrese a un rango seguro. No fuerce la interrupción abrupta (hard-kill) de particiones que ya están haciendo commit para no dejar salidas parciales. Una señal de cancelación debe evitar nuevos reclamos y permitir que el trabajo activo termine o haga rollback seguro en staging.

Tras validar la prueba canaria, escale en lotes: por ejemplo, primero 1 partición, luego 3, y después a la concurrencia segura medida. Observe un ciclo incremental completo en vivo en cada nivel. Si la capacidad no permite cumplir con la fecha límite, ajuste el plazo, la capacidad temporal o el alcance de forma anticipada. No oculte un error de estimación sacrificando la frescura de los datos en vivo.

Paso 4: Definir la propiedad de escritura entre los pipelines histórico y en vivo

Primero recalcule el intervalo histórico desde la instantánea de origen o watermark de log W0 hacia una nueva versión. Si el pipeline en vivo solo corrige los últimos 7 días, asigne al backfill la propiedad exclusiva de los 83 días anteriores. Mantenga los últimos 7 bajo propiedad en vivo y luego recalcule o fusione esa ventana superpuesta en la nueva versión al finalizar.

Si las correcciones en vivo pueden alterar cualquier pedido histórico, utilice un flujo de instantánea más captura de deltas (snapshot-plus-delta-catch-up):

  1. Registre W0; el backfill lee únicamente entradas deterministas no posteriores a W0.
  2. El pipeline en vivo sigue atendiendo la versión anterior, mientras que los cambios posteriores a W0 se mantienen en un log reproducible.
  3. Una vez validadas las 90 particiones históricas, registre W1 y aplique los cambios en (W0, W1] a la nueva versión con la misma regla de versiones.
  4. Cuando el retraso esté dentro del margen del cutover, congele brevemente el puntero de publicación o adquiera un bloqueo de escritura (write fence) y aplique el delta final.
  5. Mueva atómicamente a los consumidores a la nueva versión y luego conviértala en el destino de escritura del pipeline en vivo.

Este diseño requiere un log de cambios completo, ordenamiento estable y una primitiva de cutover genuinamente atómica. Si la plataforma no dispone de un cambio atómico de vista o catálogo, utilice una ventana de mantenimiento explícita o un reemplazo transaccional de particiones con copias de seguridad de las particiones antiguas. Documente el estado intermedio visible; no prometa verbalmente un cutover sin interrupciones.

Paso 5: Validar por capas y establecer compuertas estrictas antes de la publicación

Ejecute tres capas de comprobaciones tras finalizar cada partición en staging:

  • Estructura y completitud: esquema compatible, campos obligatorios presentes, claves de negocio únicas, límites de fecha correctos y ninguna partición faltante o duplicada entre las 90.
  • Conciliación con el origen: compare recuentos de filas de entrada y salida, pedidos distintos, importe antes de impuestos, impuestos e importe neto por fecha, región, moneda y estado. Para los agregados, conserve las diferencias a nivel de registro que puedan investigarse.
  • Reglas de negocio y diferencias: conservación de importes, reembolsos dentro del importe reembolsable y transiciones de estado válidas. Las diferencias entre la versión nueva y la anterior deben concentrarse en los pedidos afectados por el defecto; las secciones no afectadas no deben cambiar sin justificación.

La igualdad en el recuento de filas es una evidencia débil: un join defectuoso puede agregar y omitir filas al mismo tiempo. Calcule también checksums por bloques (bucketed checksums) por clave estable, inspeccione muestras de defectos conocidos, fechas límite, correcciones tardías y eliminaciones, y haga que el responsable financiero o del producto de datos confirme la dirección de la corrección. Controle las versiones de las consultas de validación y conserve los umbrales, los valores reales y los resultados.

La compuerta global de publicación debe exigir al menos: 90/90 VALIDATED en el manifiesto; ninguna partición activa o fallida; versiones consistentes de snapshot de entrada, código y dependencias; catch-up hasta W1; cumplimiento de todas las aserciones estrictas; mantenimiento de la frescura P95 de 45 minutos en el pipeline diario durante el backfill; y aprobación del responsable. Cualquier fallo mantiene visible la versión anterior.

Paso 6: Hacer el cutover de una sola vez, observar continuamente y hacer rollback rápidamente

Guarde el puntero de lectura anterior y la versión de salida antes de la publicación. El cutover cambia únicamente una vista estable o un puntero de catálogo; no traslada 180 TB durante el proceso. Ejecute de inmediato una suite de consultas de consumidores en los dashboards críticos y trabajos aguas abajo, y verifique la latencia de las consultas y la escritura incremental más reciente. Continúe comparando las métricas importantes entre las versiones antigua y nueva durante el período de observación.

Si la unicidad de claves, la conciliación de importes, la frescura en vivo o las consultas de consumidores fallan, detenga la publicación hacia la nueva versión y revierta el puntero. Conserve la versión fallida, el manifiesto y la evidencia de validación para la investigación; no la edite in situ presentándola como la misma versión. Tras corregir la entrada o el código, cree una nueva especificación de ejecución. Reutilice las particiones comprobadas como confiables y compatibles en versión; recalcule aquellas cuya versión difiera.

La vista de monitoreo debe mostrar los TB procesados y restantes, el recuento de particiones por estado, el rendimiento, el tiempo estimado de finalización, los reintentos y fallos de validación, la limitación del origen, las colas del pool de cómputo, la latencia de commit en destino y la frescura P50/P95 del pipeline en vivo. Las alertas deben incluir backfill_id, partición, versión del código, compuerta fallida y responsable, para que un operador pueda decidir si reduce la concurrencia, reintenta una partición o detiene la publicación por completo.

Ejemplo de respuesta de alta calidad

“Primero congelaría este backfill como una ejecución versionada: 90 valores de business_date, snapshot sin procesar y watermark W0, SHA del código, versión de la dimensión de impuestos, versión de la tabla de destino y umbrales de aceptación. Cada día representa una tarea que escribe una salida de staging aislada. Un manifiesto registra PENDING/RUNNING/VALIDATED/PUBLISHED y cada intento. Las transformaciones utilizan únicamente tiempo lógico. Las particiones cerradas se construyen por completo y se reemplazan; los pedidos que puedan recibir correcciones tardías utilizan una clave primaria estable y la versión de origen en un MERGE, de modo que una versión antigua no pueda sobrescribir una más reciente”.

“Procesar 180 TB en 5 días requiere un promedio mínimo de lectura de datos sin procesar de unos 417 MB/s, antes de reintentos y validaciones. Evaluaría una partición representativa mediante benchmark, mediría el rendimiento de extremo a extremo y el pico de cada etapa, y luego aumentaría la concurrencia gradualmente. El backfill recibe un pool de recursos aislado de baja prioridad con límites en lecturas de origen, escrituras en destino y concurrencia del programador. El controlador protege la frescura P95 en vivo: deja de reclamar nuevas particiones a medida que el retraso se acerca a los 45 minutos y la restablece lentamente tras la recuperación”.

“Para garantizar la consistencia concurrente, construyo la nueva versión a partir de la instantánea W0 mientras el pipeline en vivo sigue atendiendo la versión antigua. Cuando finalizan las particiones históricas, registro W1, aplico las correcciones de (W0, W1] en la nueva versión, utilizo un breve bloqueo (fence) para la nivelación final y muevo atómicamente el puntero. La publicación requiere el 100 % (90/90) de las particiones, claves únicas, conciliación de importes de origen, invariantes de negocio, diferencias explicables entre versiones y una frescura saludable en producción. Mantengo la versión antigua durante la observación. Si una compuerta estricta o una consulta de consumidor falla, se revierte el puntero y se preserva la versión fallida para su investigación”.

Errores comunes

  • Fijar la concurrencia del orquestador al máximo → El origen, el shuffle, los commits de destino o los trabajos diarios se convierten en el cuello de botella real → Deduzca la concurrencia a partir del benchmark de una partición, el límite inferior de rendimiento y el SLO de producción, y luego aplique limitación dinámica.
  • Confundir el reintento de tareas con idempotencia → El orquestador solo vuelve a ejecutar la tarea; los appends ciegos siguen duplicando datos → Utilice entradas deterministas y tiempo lógico, y luego reemplace la partición o use merge por clave estable y versión.
  • Permitir que los trabajos histórico y en vivo escriban en la misma partición → Un cómputo antiguo que finalice tarde puede sobrescribir una corrección reciente → Asigne la propiedad de las particiones o use la captura de deltas W0/W1 y un ordenamiento explícito de versiones.
  • Publicar tras el éxito de 90 tareas → Los estados exitosos no prueban registros completos, importes correctos ni diferencias coherentes → Establezca compuertas basadas en particiones, origen, reglas de negocio, diferencias y verificaciones de consumidores.
  • Sobrescribir la tabla en línea antes de la validación → Una validación fallida deja otro gran recálculo como única vía de recuperación → Escriba una salida versionada, valídela, haga el cutover en un solo paso y conserve el puntero anterior.
  • Comparar únicamente recuentos totales de filas → Los duplicados y las omisiones pueden cancelarse mutuamente → Compare también claves únicas, checksums por bloques, importes, distribuciones de estado y diferencias a nivel de registro.
  • Llamar a now() en una transformación histórica → Dos intentos generarán semánticas de partición diferentes → Pase la fecha lógica, la instantánea de entrada y las versiones de dependencias como parámetros de ejecución.
  • Reejecutar los 180 TB completos tras un fallo → Esto eleva el costo y el riesgo, y descarta el progreso ya validado → Reanude las unidades fallidas desde el manifiesto de particiones; recalcule las particiones afectadas solo si cambia una versión.

Preguntas de seguimiento y respuestas

Pregunta de seguimiento 1: ¿Cómo puede ser repetible el backfill si el origen no tiene una instantánea inmutable?

Opte por una exportación histórica versionada creada antes de la ejecución, o registre una posición de instantánea de base de datos, posición de log CDC y los ID de versión de los objetos. Si el único origen es una tabla mutable, registre en el manifiesto la hora de lectura, la marca de agua y el checksum por partición, y capture continuamente los cambios durante la ejecución para su posterior nivelación. Si no es posible reconstruir la entrada original, declare la limitación de reproducibilidad; no afirme que dos intentos serán idénticos.

Pregunta de seguimiento 2: Una dimensión SCD corregida alimenta la tabla de hechos. ¿Cuál debe recalcularse primero?

Construya el subgrafo del linaje afectado y procéselo en orden topológico. Cree primero la nueva versión de la dimensión, luego una la tabla de hechos a esa versión a la fecha del evento ('as-of') y, por último, reconstruya los agregados y data marts. Cada capa comparte un mismo identificador de versión de backfill; no publique una dimensión antigua con una tabla de hechos nueva. Valide las claves de negocio de la dimensión, los intervalos de vigencia sin solapamiento, la tasa de coincidencia de claves foráneas en los hechos y los agregados críticos.

Pregunta de seguimiento 3: ¿Cómo realizar la publicación si la plataforma no admite el intercambio atómico de tablas?

Se recomienda escribir una tabla de versión independiente y enrutar a los consumidores mediante una vista estable. Si la definición de la vista se puede reemplazar de forma atómica, cambie únicamente la vista. Si esto tampoco es viable, use reemplazos transaccionales en lotes pequeños con copias de seguridad de las particiones antiguas o una ventana de mantenimiento explícita que pause lecturas y escrituras relacionadas durante el cutover y la aceptación. Especifique los estados intermedios visibles y el tiempo de rollback; no describa una sobrescritura de múltiples pasos como atómica.

Pregunta de seguimiento 4: Las versiones antigua y nueva tienen recuentos de filas e importes totales idénticos. ¿Qué más se debe comprobar?

Calcule checksums por bloques basados en la clave de negocio estable e inspeccione las diferencias a nivel de registro. Compare las distribuciones por región, moneda, estado del pedido, tramo impositivo y fecha límite. Confirme que los casos erróneos conocidos hayan cambiado y que los no afectados permanezcan intactos. Verifique claves primarias, integridad referencial, transiciones de estado y límites máximos de reembolso. Los totales idénticos pueden ocultar un exceso que cancela una omisión.

Pregunta de seguimiento 5: ¿Debe iniciarse la ejecución desde la fecha más antigua o desde la más reciente?

Depende de las dependencias y del valor de negocio. Si una partición posterior depende del estado de una anterior, ejecute hacia adelante. Si las particiones son independientes y los informes recientes tienen mayor urgencia, el orden inverso puede resultar beneficioso. En ambos casos, la compuerta de publicación debe cubrir el intervalo completo, a menos que el responsable del producto apruebe explícitamente una publicación por fases con versiones, alcance de consumidores y límites de rollback independientes para cada fase.

Fuentes públicas

Preguntas relacionadas