Tema representativo de entrevista

Entrevista de diseño de sistemas: Diseñar un servicio de asignación de derechos de funciones multi-tenant

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

Pregunta

Diseña un servicio que responda si un usuario en un tenant puede utilizar una función del producto. Los planes de suscripción, complementos, pruebas, límites de asientos y cancelaciones cambian con el tiempo. Explica el modelo de datos, la API de evaluación, la ruta de propagación, la estrategia de caché, las garantías de revocación y el comportamiento de recuperación.

Prompt y contexto

Este ejercicio de diseño de sistemas se adapta a roles de plataforma, backend e infraestructura SaaS. Un sistema de facturación emite eventos de planes y pagos; los servicios del producto necesitan una decisión de autorización como can tenant T use feature F for subject U?. Asume 50,000 tenants, 10 millones de sujetos, 100,000 solicitudes de decisión por segundo en horas pico y un objetivo de disponibilidad mensual del 99.99%. Un derecho cancelado o suspendido no debe permanecer utilizable indefinidamente, mientras que una interrupción en la facturación no debe derribar todas las rutas de lectura.

Qué evalúa el entrevistador

  • ¿Puedes separar la facturación como la fuente de verdad comercial de una instantánea evaluada de derechos de acceso?
  • ¿Defines el aislamiento de tenants y sujetos, y la precedencia entre plan, complemento, prueba y reglas de denegación?
  • ¿Puedes razonar sobre el orden de eventos, la obsolescencia de caché, la latencia de revocación y las decisiones de fail-open frente a fail-closed?
  • ¿Proporcionas una API versionada, registro de auditoría, observabilidad y una ruta de recuperación reproducible mediante replay?

Preguntas aclaratorias para hacer

Pregunta si las decisiones son por tenant, usuario, cuenta de servicio o asiento; si una función se puede habilitar para un subconjunto; con qué rapidez la cancelación debe revocar el acceso; si las cuotas de uso son parte de la decisión; y si cada decisión necesita un motivo explicable. Confirma si los eventos de facturación son de tipo at-least-once y pueden llegar desordenados. Estas respuestas cambian el esquema de la instantánea, el manejo de eventos, el TTL de la caché y la directiva de conmutación por error.

Estructura de respuesta en 30 segundos

Mantendría la facturación como la fuente autoritativa y construiría una proyección de derechos indexada por tenant, alcance de sujeto, función y versión. Una ruta de escritura consume eventos de suscripción ordenados o deduplicados, calcula una nueva instantánea y publica una invalidación. Una API de lectura evalúa la instantánea con una precedencia explícita y devuelve allow, deny, motivo y versión. Las cachés regionales atienden lecturas de alta demanda, pero un token de revocación o version fence limita el acceso obsoleto. Fail-open se permite solo para funciones de bajo riesgo; las funciones de pago o críticas para la seguridad fallan en modo closed y exponen una ruta de recuperación. Cada cambio y decisión es auditable.

Análisis detallado paso a paso

  1. Definir el contrato. Evaluate(tenant_id, subject_id, feature, context) devuelve una decisión, código de motivo, versión de instantánea y expiración. El contexto puede incluir atributos de plan, región, asiento o despliegue; OpenFeature requiere una clave de targeting única y admite campos personalizados, por lo que no sobrecargues un único string de texto libre con el estado de facturación.
  2. Modelar concesiones inmutables. Almacena productos de suscripción, complementos, pruebas, asientos, horas de entrada en vigencia y expiración, y denegaciones explícitas como hechos versionados. La proyección almacena el conjunto de funciones resuelto junto con los IDs de hechos de origen. Una denegación por suspensión o cumplimiento anula una concesión normal; una prueba con límite de tiempo expira sin mutar el historial.
  3. Construir la ruta de propagación. La facturación emite un evento con tenant, versión de suscripción, ID de evento y hora de entrada en vigencia. Un inbox deduplica los IDs de eventos, rechaza una versión más antigua y escribe el hecho y la proyección transaccionalmente. Un outbox publica entitlement_version_changed; los consumidores invalidan por tenant y función. Reproducir los hechos reconstruye una proyección tras una corrupción de datos.
  4. Atender lecturas. Una API de evaluación sin estado lee una caché local o un almacén regional. Las claves de caché incluyen tenant, alcance de sujeto, función y versión de política. Las entradas de caché llevan la versión de la proyección y la expiración. Si una solicitud presenta un version fence más nuevo que la caché, lee el almacén regional autoritativo antes de decidir.
  5. Elegir la consistencia según el riesgo. Establece un SLO de revocación medido, como 60 segundos para una cancelación ordinaria y un fencing casi inmediato para fraudes o suspensiones de seguridad. Publica un fence de denegación en un almacén de alta disponibilidad y fuerte accesibilidad; los servicios rechazan los allows cacheados más antiguos que ese fence. No prometas lecturas sin obsolescencia sin asumir el costo de las comprobaciones sincrónicas.
  6. Manejar fallas y escala. Particiona los eventos por tenant para preservar el orden por tenant, fragmenta (shard) las proyecciones mediante el hash del tenant y mantén aislados a los tenants de alto tráfico. Ante retrasos en la facturación, expón la última versión aplicada y genera alertas. Ante fallas en la caché o en el almacén regional, utiliza una ventana de obsolescencia delimitada solo para funciones de bajo riesgo; devuelve un error de dependencia tipado para funciones de alto riesgo en lugar de conceder acceso silenciosamente.
  7. Auditar y verificar. Registra quién cambió un plan, qué versión de evento produjo una proyección y por qué se tomó una decisión. Mide el lag de eventos, la antigüedad de la proyección, la tasa de aciertos de caché, los bloqueos de stale-allow, la latencia de decisiones y los fallos de autorización entre tenants. Prueba eventos fuera de orden, entrega duplicada, desfase de reloj (clock skew), cancelación durante una solicitud, migración de tenants y replay desde una proyección vacía.

Respuesta de ejemplo de alta calidad

Separaría la verdad comercial de una proyección de derechos versionada. Los eventos de facturación llevan un ID de evento, tenant, versión de suscripción, hora de entrada en vigencia y productos modificados. Un inbox deduplica y rechaza versiones más antiguas, luego escribe transaccionalmente los hechos, la instantánea de funciones resuelta y una notificación outbox. La API de evaluación devuelve allow o deny, motivo, versión de proyección y expiración. Una clave de caché incluye el tenant y el alcance del sujeto para que un cliente no pueda leer la decisión de otro cliente.

La compensación clave es la revocación. Establecería un SLO de cancelación ordinaria de 60 segundos y publicaría un fence de denegación para suspensiones por fraude o seguridad. Cada allow cacheado lleva una versión de proyección; un fence más nuevo fuerza una lectura en el almacén regional. Las funciones de interfaz de usuario de bajo riesgo pueden utilizar una ventana de obsolescencia delimitada durante una interrupción del almacén, mientras que la exportación de datos de pago o los controles de seguridad fallan en modo closed con un error de dependencia tipado. Los registros de auditoría vinculan cada decisión a la versión del evento y de la política, y un trabajo de replay reconstruye las proyecciones a partir de hechos inmutables.

Errores comunes

  • Leer tablas de facturación sincrónicamente para cada solicitud → la latencia y las interrupciones de pago se convierten en interrupciones de autorización → proyecta hechos inmutables en una instantánea optimizada para lectura.
  • Cachear únicamente por función → un tenant o sujeto puede recibir la decisión de otro alcance → incluye tenant, alcance de sujeto y versión de política en la clave.
  • Aplicar eventos en orden de llegada → una cancelación o renovación antigua puede sobrescribir un estado más nuevo → deduplica IDs y rechaza versiones más antiguas que la versión aplicada.
  • Prometer revocación instantánea en todas partes → el diseño oculta los costos de red y caché → define un SLO de revocación medible y aplica un fence de denegación.
  • Aplicar fail-open a funciones de pago o de seguridad → el acceso obsoleto se convierte en un incidente financiero o de seguridad → clasifica las funciones por riesgo y aplica fail-closed donde sea necesario.

Preguntas de seguimiento y respuestas

¿Cómo admites una función para solo el 10 por ciento de los usuarios de un tenant?

Mantén separados el derecho comercial y el targeting de despliegue. La instantánea de derechos indica que el tenant posee la función; un contexto de evaluación con una clave de targeting de sujeto estable aplica la regla de despliegue. Registra ambas decisiones para que un ingeniero de soporte pueda distinguir entre "no adquirido" y "no seleccionado por el despliegue".

¿Qué sucede cuando un evento de cancelación se retrasa?

Expón la antigüedad de la proyección y el lag del evento, genera alertas antes de que se incumpla el SLO de revocación y utiliza la versión de facturación o el fence de denegación cuando esté disponible. No infieras la cancelación a partir de la ausencia de un heartbeat. Una vez que llegue el evento, aplícalo de forma idempotente e invalida todos los alcances afectados.

¿Cómo migras un tenant entre shards?

Escribe una época de migración en los metadatos del tenant, realiza lecturas duales durante el cutover delimitado y publica un fence que impida que un shard anterior entregue allows. Verifica recuentos, versiones y decisiones muestreadas antes de eliminar la copia antigua; conserva hechos reproducibles para rollback.

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