Tema representativo de entrevista

Entrevista de diseño de sistemas: ¿Cómo diseñarías un planificador de tareas por lotes multiinquilino justo?

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

Pregunta

Un clúster compartido ejecuta tareas sensibles a la latencia y grandes cargas de trabajo por lotes. Unos pocos inquilinos envían suficiente trabajo como para hacer esperar a los demás. Diseña el planificador, abarcando cuotas, prioridad, equidad, apropiación, recuperación ante fallas y métricas de verificación.

Planteamiento y contexto

Un clúster de cómputo compartido ejecuta tareas interactivas, trabajo por lotes y entrenamiento apropiativo. Los inquilinos pueden tener ráfagas de uso, pero ninguno puede retener CPU, memoria o GPU de forma ilimitada. El trabajo de alta prioridad necesita menor tiempo de espera, mientras que los inquilinos de baja prioridad no deben quedar desatendidos por inanición.

Diseña colas, un registro contable de recursos, políticas de planificación, apropiación y recuperación. Kubernetes separa PriorityClass, ResourceQuota y apropiación; las directrices de gestión de colas de la IETF tratan de manera similar la equidad y el control de congestión como restricciones relacionadas en lugar de un único FIFO global.

Qué está evaluando el entrevistador

  • Separar la cuota de inquilino, la prioridad del trabajo y la viabilidad del nodo.
  • Definir una equidad que no deje sin recursos al trabajo de baja prioridad.
  • Acotar los efectos secundarios de la apropiación, la amplificación de reintentos y la fragmentación.
  • Recuperarse de fallas del planificador, despachos duplicados y pérdida de workers.
  • Demostrar la equidad con métricas a nivel de inquilino en lugar de promedios del clúster.

Preguntas para clarificar

  • ¿Los recursos son CPU, memoria, GPU o nodos heterogéneos con discos locales?
  • ¿Las cuotas tienen alcance por inquilino, proyecto, cola u organización?
  • ¿Puede la prioridad apropiarse del trabajo y cuál es el costo de recuperación por checkpoint?
  • ¿Pueden los trabajos dividirse, cancelarse o reintentarse, y las escrituras de resultados son idempotentes?
  • ¿La equidad se basa en max-min share, cuota ponderada o un límite de tiempo de espera?

Respuesta en treinta segundos

Mantendría cuotas, uso y capacidad de préstamo con expiración por inquilino, y luego colocaría los trabajos en colas a nivel de inquilino. Tras filtrar las restricciones de los nodos, el planificador selecciona al inquilino más desatendido mediante un servicio equitativo ponderado; el envejecimiento eleva la prioridad efectiva para que el trabajo no sufra inanición. La apropiación se permite solo cuando la política, la cuota y la recuperación la hacen segura. Las reservas, los leases y los fencing tokens son duraderos, y las métricas se desglosan por inquilino, cola y tipo de recurso.

Diseño paso a paso

Paso 1: Construir el registro de recursos y cuotas

Representa la CPU, la memoria, la GPU y las etiquetas de nodo como un vector de recursos. El uso prolongado consume la cuota del inquilino; el préstamo para ráfagas expira. Reserva recursos de forma atómica antes del despacho y devuélvelos al finalizar, cancelar o expirar el lease. Aplica la cuota en la admisión y en la planificación para que un llamador no pueda eludirla con una prioridad alta.

Paso 2: Usar colas jerárquicas y selección equitativa

Estratifica organización, inquilino y clase de trabajo, y luego selecciona entre los inquilinos ejecutables según su ponderación. Rastrea el servicio virtual o el uso reciente de recursos y elige al inquilino desatendido; añade envejecimiento acotado tras un umbral de espera. Una cola de prioridad global puede permitir que un inquilino grande domine el frente para siempre, mientras que la rotación a nivel de inquilino hace explícito el límite de equidad.

Paso 3: Acotar prioridad, préstamo y apropiación

La prioridad representa urgencia, no capacidad ilimitada. El préstamo se limita a la capacidad ociosa o a una ventana explícita. Antes de expropiar, estima los recursos liberados, el costo del checkpoint y el presupuesto de la víctima; prioriza el trabajo recuperable de baja prioridad. Si la recuperación no es demostrablemente segura, deja que el trabajo urgente espere en lugar de arriesgarte a efectos secundarios duplicados.

Paso 4: Filtrar nodos y controlar la fragmentación

Filtra arquitectura, modelo de GPU, zona, afinidad y capacidad antes de puntuar los nodos. Mezclar solicitudes grandes y pequeñas en una sola cola genera fragmentación; reserva un pool acotado para perfiles grandes y establece un límite de espera. Registra las causas de rechazo por separado: capacidad total, incompatibilidad de perfil y cuota agotada.

Paso 5: Despachar con leases y recuperación idempotente

Persiste una reserva versionada. Los workers reclaman un lease corto con un fencing token. Un despacho duplicado se comprueba mediante (job_id, attempt); solo un token más reciente puede tomar el control de un lease expirado. Libera la reserva tras confirmar el resultado. Al reiniciar el planificador, reconstruye los trabajos no terminados a partir del log o de la base de datos en lugar de adivinarlos desde la memoria.

Paso 6: Manejar fallas, cancelaciones y reintentos

Marca primero a un worker perdido como desconocido y luego reclámalo tras la ventana del lease y del heartbeat. Reanuda los trabajos recuperables desde checkpoints; los efectos no idempotentes requieren búsqueda de estado o compensación. Los reintentos consumen presupuestos del inquilino y del trabajo con un backoff limitado. La recuperación no debe redespachar todas las tareas con tiempo expirado de golpe.

Paso 7: Escalar capacidad y modificar políticas

Publica políticas versionadas cuando cambien los nodos o las ponderaciones. Mantén la política anterior para los trabajos ya encolados y migra el nuevo trabajo gradualmente; un cambio de ponderación no debe revocar instantáneamente la cuota prometida. Rastrea por separado los recursos escasos como GPU, zonas y discos locales, con eventos de auditoría para préstamos y recuperaciones.

Paso 8: Verificar la equidad y la eficiencia

Realiza pruebas de carga con cargas sintéticas y reales: un inquilino saturado, varios inquilinos lentos, pérdida aleatoria de nodos, recuperación por checkpoints y cambios de política en caliente. Mide el p50/p95 de espera del inquilino, la cuota de recursos, el intervalo máximo de inanición, las apropiaciones, la ejecución duplicada, la antigüedad de la cola, la fragmentación y el tiempo de recuperación. Compara FIFO, prioridad estricta y planificación justa para mostrar el balance de compensaciones.

Respuesta de ejemplo de alta calidad

Separaría la cuota, la prioridad y la viabilidad del nodo. Las colas de inquilinos se eligen mediante un servicio ponderado para los más desatendidos más un envejecimiento acotado. El préstamo utiliza capacidad ociosa que expira; la apropiación requiere una prueba de recuperación, verificación de cuota y un presupuesto de checkpoints. Cada asignación persiste una reserva, un lease y un fencing token, mientras que los resultados son idempotentes por intento. El planificador se reconstruye desde su log y los reintentos consumen presupuestos del inquilino. Las pruebas de fallas crean un vecino ruidoso y pérdida de workers, comparando luego la espera del inquilino, la cuota compartida, la inanición, el trabajo duplicado, la fragmentación y el tiempo de recuperación.

Errores comunes

  • Una sola cola de prioridad global → un inquilino grande domina el frente → selecciona un inquilino antes de un trabajo local del inquilino.
  • Tratar la cuota como prioridad → el trabajo urgente elude los límites → mantén las comprobaciones de cuota atómicas e independientes.
  • Apropiación no acotada → el costo del checkpoint y los efectos duplicados explotan → añade presupuestos y periodos de enfriamiento.
  • Colas únicamente en memoria → el reinicio duplica o pierde despachos → persiste reservas, leases y tokens.
  • Solo promedios del clúster → un inquilino puede sufrir inanición de forma invisible → desglosa la espera y la cuota por inquilino.
  • Reintento inmediato tras la pérdida de un worker → la ejecución anterior aún podría estar corriendo → espera al fencing o utiliza una ruta idempotente.

Preguntas de seguimiento

¿Cómo demuestras que no hay inanición?

Reserva una cuota de servicio mínima para cada inquilino ejecutable y pon un tope al envejecimiento. Bajo una capacidad fija y trabajo continuamente planificable, verifica que la espera máxima se mantenga dentro del límite de la política.

¿Cómo evitas la facturación duplicada tras una apropiación?

Factura el trabajo lógico o la etapa confirmada, no cada intento. Los efectos externos utilizan una clave de idempotencia y búsqueda de estado.

¿Qué ocurre si la cuota entra en conflicto con la capacidad ociosa?

Permite el préstamo con expiración y registra la capacidad recuperable. Detén primero los nuevos préstamos y luego espera a que finalicen o apropia únicamente trabajo recuperable.

¿El planificador necesita consistencia fuerte?

Las reservas, los leases y el fencing necesitan actualizaciones condicionales linearizables; los paneles de control pueden ser asíncronos. Una caché desactualizada no debe asignar la última GPU.

¿Cuándo es innecesaria la planificación justa?

Para un solo inquilino, ventanas por lotes fijas o prioridad estricta donde se acepta la inanición, una cola de prioridad simple es más fácil de verificar.

¿Qué desencadena una reversión (rollback)?

Ejecución duplicada, fallas en la recuperación, incumplimiento del límite de espera o una cuota de inquilino fuera de presupuesto detienen la nueva política. Restaura la versión anterior y conserva los logs de reserva para reproducirlos.

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