Tema representativo de entrevista

Entrevista de diseño de sistemas: Diseñar un orquestador verificable de eliminación de datos de inquilinos

Diseño de sistemasDifícil
Equipo editorial de Offer.ccPublicado Actualizado

Pregunta

Diseñe un servicio de eliminación de datos para un inquilino cerrado. Los datos residen en una base de datos principal, almacenamiento de objetos, índices de búsqueda, caché y copias de seguridad; el sistema debe admitir reintentos, fallos parciales, auditabilidad y un estado de finalización verificable.

Planteamiento y contexto

Después de que un inquilino se cierra, el sistema recibe una solicitud de eliminación. Los datos del inquilino están distribuidos en una base de datos principal, almacenamiento de objetos, índices de búsqueda, cachés y copias de seguridad. La eliminación no debe bloquear el hilo de la solicitud ni perder trabajo silenciosamente cuando un servicio descendente no esté disponible. La entrevista se centra en la orquestación, la idempotencia, la recuperación y la evidencia detrás de un estado “completo”.

Lo que el entrevistador está evaluando

El entrevistador quiere ver la semántica de eliminación definida antes de dibujar los componentes. Un diseño sólido cubre el catálogo de datos, la máquina de estados, la partición de tareas, las claves de idempotencia, los reintentos y las colas de mensajes no entregados (dead letters), el control de concurrencia, la observabilidad y la prueba final. La documentación del almacenamiento de objetos distingue la eliminación inmediata, las versiones y las reglas de ciclo de vida; las réplicas y la eliminación asíncrona significan que el éxito en la base de datos principal no es prueba de que todas las copias hayan sido procesadas.

Preguntas clarificadoras para hacer primero

Pregunte si el alcance es un inquilino, un usuario o recursos seleccionados; cómo se definen la eliminación definitiva (hard delete), la eliminación diferida y las ventanas de retención; si las copias de seguridad se borran de inmediato o expiran después de una ventana de tiempo; qué registros de auditoría deben permanecer sin copiar datos personales sin procesar; y qué límites de consistencia, tiempo de finalización, escala y políticas aplican. No invente plazos legales que no hayan sido proporcionados.

Un marco de respuesta de 30 segundos

Diga: “Construiría un catálogo de datos y una política de eliminación del inquilino, y luego orquestaría trabajos de eliminación versionados a través de adaptadores de almacenamiento. La solicitud crea un trabajo idempotente y responde rápidamente; una cola impulsa las fases, y cada fase registra evidencia, reintentos y su último error. El verificador marca el trabajo como completo solo cuando los datos principales, los índices derivados, las cachés y las copias de seguridad permitidas por la política alcanzan sus estados requeridos; de lo contrario, programa un reintento o la intervención humana”.

Análisis profundo paso a paso

1. Construir el catálogo de datos y la política

Para cada recurso, registre la propiedad del inquilino, la ubicación, la derivación, el método de eliminación, la ventana de retención y la consulta de verificación. Marque las copias de seguridad o los registros que no puedan eliminarse de inmediato como excepciones de política, incluyendo la expiración, la aprobación y cómo permanecen inaccesibles para las lecturas del producto durante el período de retención.

2. Enviar un trabajo de eliminación idempotente

El flujo de cierre crea un deletionJobId globalmente único y utiliza una generación del inquilino o una versión del evento de cierre como condición de idempotencia. La API devuelve rápidamente un estado de aceptado; las solicitudes duplicadas devuelven el mismo trabajo. Persista una instantánea (snapshot) de la versión del catálogo para que las ediciones posteriores del catálogo no cambien los límites del trabajo.

3. Dividir el trabajo reintentable por dependencia

Congele las escrituras o cambie el estado del inquilino primero, luego procese los registros principales y los objetos, seguidos de los índices de búsqueda, las cachés y los archivos derivados. Cada adaptador utiliza (deletionJobId, resourceId, generation) como su clave de idempotencia. El éxito, la ausencia previa y los errores reintentables de forma segura necesitan resultados diferenciados; los errores no reintentables van a una cola de mensajes no entregados con una ruta de recuperación humana.

4. Manejar réplicas, versiones y copias de seguridad

El almacenamiento de objetos puede tener versiones, reglas de ciclo de vida y réplicas entre regiones; una llamada exitosa a la API de eliminación no prueba que las copias asíncronas hayan desaparecido de inmediato. Registre la hora de la solicitud, la versión observada o el marcador de eliminación, y la última verificación para cada réplica. Permita que las copias de seguridad sigan su política de retención y verifique la irrecuperabilidad después de su vencimiento en lugar de pretender que el borrado es instantáneo.

5. Diseñar el verificador y los estados de finalización

El verificador consulta el catálogo y comprueba lecturas principales, búsquedas en índices, lecturas de caché y listados de objetos. La máquina de estados debe distinguir al menos ACCEPTED, RUNNING, WAITING_RETRY, BLOCKED, VERIFIED y FAILED. Solo los recursos requeridos con evidencia y excepciones de política explícitas pueden alcanzar VERIFIED; las escrituras condicionales evitan que un reintento antiguo sobrescriba un resultado más reciente.

6. Agregar observabilidad, aislamiento y auditoría

Rastree la latencia, la tasa de éxito, los reintentos, los mensajes no entregados, la limitación de tasa (throttling) de servicios descendentes y los recursos restantes por inquilino y por trabajo. Utilice credenciales dedicadas y el principio de menor privilegio para evitar la eliminación entre inquilinos. Los registros de auditoría conservan únicamente el ID del trabajo, el tipo de recurso, la versión de la política, el actor y el resumen del resultado, nunca datos sin procesar. Las alertas distinguen entre un solo inquilino bloqueado y una interrupción global de servicios descendentes.

Respuesta de muestra de alta calidad

“Comenzaría con un catálogo de tablas, prefijos de objetos, índices, claves de caché y políticas de copias de seguridad, cada uno con la propiedad del inquilino, un método de eliminación y una consulta de verificación. Cerrar un inquilino escribe un deletionJobId único, congela nuevas escrituras y encola el trabajo. El orquestador sigue las dependencias: datos principales y objetos primero, luego índices y cachés; cada adaptador es idempotente según la generación del recurso. Se registra la evidencia de réplicas y versiones de objetos, mientras que las copias de seguridad siguen su política de retención en lugar de declararse como borradas instantáneamente. Un verificador vuelve a comprobar los listados principales, de búsqueda, de caché y de objetos, y pasa a VERIFIED solo cuando se cuenta con evidencia de cada recurso requerido. Los fallos en servicios descendentes utilizan retroceso exponencial (exponential backoff) y luego una ruta de mensajes no entregados con un responsable asignado. Las auditorías almacenan la versión de la política, un resumen del resultado y el ID del trabajo; las credenciales están aisladas por inquilino. El cliente recibe un estado consultable y evidencia, no una simple cadena ‘deleted’ sin respaldo”.

Errores comunes y mejoras

  • Eliminar solo las filas principales: Diseñe el catálogo de datos y las derivaciones, y luego defina la eliminación y verificación para cada uno.
  • Llamar a todos los servicios descendentes de forma síncrona: Utilice una cola de trabajos y una máquina de estados para aislar la latencia de las solicitudes de posibles interrupciones.
  • Tratar el trabajo duplicado como una excepción: Defina una clave de idempotencia por recurso y distinga la ausencia previa de un fallo real.
  • Prometer el borrado instantáneo de copias de seguridad: Indique la ventana de retención, el ciclo de vida y el estado de expiración verificable.

Preguntas de seguimiento y respuestas

¿Qué debería ver el cliente cuando un servicio descendente sigue fallando?

Devuelva el estado consultable del trabajo, la fase, la clase de error y la hora del próximo reintento sin exponer credenciales internas. Una vez agotado el presupuesto de reintentos, pase a BLOCKED o FAILED, notifique al responsable y conserve una ruta segura de reanudación.

¿Cómo evita que un trabajo antiguo elimine escrituras nuevas?

Congele las escrituras o utilice una generación del inquilino. Cada eliminación incluye la generación capturada en el momento de la creación, y la condición de almacenamiento rechaza cualquier discrepancia. Las actualizaciones de catálogo y de estado también utilizan escrituras condicionales versionadas.

¿Cómo prueba que VERIFIED no pueda ser un falso positivo?

Inyecte mensajes duplicados, réplicas retrasadas, reconstrucciones de índices, repoblación de caché y restauraciones de copias de seguridad. Si una consulta simulada aún puede leer datos, el verificador debe permanecer incompleto y registrar la evidencia faltante.

¿Qué sucede si los propios registros de auditoría contienen información del inquilino?

Almacene solo una referencia o hash irreversible del inquilino, el ID del trabajo, la versión de la política y el resumen del resultado. Restrinja el acceso y asigne al registro de auditoría su propia política de retención. La auditoría debe probar el procesamiento sin copiar los datos eliminados.

Fuentes públicas

Preguntas relacionadas

Herramienta de entrevista relacionada

Usa Resolver para una respuesta de diseño de sistemas

Aclara primero los requisitos y luego avanza a través de la escala, la arquitectura, la elección de componentes y las compensaciones (trade-offs).

Ver la herramienta