1. Pregunta y contexto
Una plataforma SaaS atiende solicitudes de API, trabajos concurrentes y almacenamiento para múltiples inquilinos. Un inquilino puede tener cuotas a nivel de proyecto, organización y recurso; algunas se reinician por minuto mientras que otras se acumulan a lo largo de un período de facturación. El negocio requiere una decisión de admisión rápida y un uso confiable para alertas, auditoría y facturación. Diseña el servicio de verificación de cuotas y medición, incluyendo límites estrictos (hard limits), umbrales flexibles (soft thresholds), políticas de exceso (overage) y comportamiento ante fallas multirregión.
2. Lo que evalúa el entrevistador
- Si distingues entre límites de asignación, de tasa y de concurrencia, y si defines su alcance y semántica de reinicio.
- Si separas la admisión sincrónica de los eventos de uso asincrónicos, la agregación de facturación y la conciliación.
- Si manejas reservas atómicas, claves de idempotencia, eventos duplicados o fuera de orden, inquilinos de alta carga (hot tenants) y versiones de configuración.
- Si explicas la consistencia interregional, la degradación, las pistas de auditoría, las alertas y los cambios manuales seguros.
3. Aclaraciones a solicitar antes de responder
- ¿Estamos limitando la tasa de solicitudes, trabajos simultáneos, capacidad de almacenamiento o uso acumulativo en un período de facturación?
- ¿El alcance es organización, inquilino, proyecto, usuario o instancia de recurso, y los límites se heredan en la jerarquía?
- Al agotarse, ¿el sistema debe rechazar, encolar, degradar o permitir el exceso para facturación?
- ¿Se requiere una consistencia fuerte multirregión y cuánto retraso de eventos es aceptable antes de la conciliación?
4. Estructura de respuesta en 30 segundos
Dividiría el sistema en un catálogo de cuotas, un motor de admisión sincrónico, un libro de registro (ledger) de reservas, una canalización asincrónica de eventos de uso, consultas agregadas y alertas de auditoría. Una solicitud transporta inquilino, proyecto, tipo de recurso y un ID de solicitud idempotente. El motor de admisión verifica las cuotas de tasa, concurrencia y acumulativas bajo una versión de configuración y reserva atómicamente cuando es necesario; la finalización o cancelación libera la reserva y emite un evento de uso. Los eventos llevan un ID único, marca de tiempo del evento y dimensiones; los consumidores agregan de forma idempotente y luego concilian el período con el libro de reservas y los datos de entrada de facturación. Para cada recurso, se eligen escrituras autoritativas o sobreventa acotada entre regiones; se protegen los límites estrictos durante fallas y se retorna una señal reintentable cuando corresponda.
5. Respuesta detallada paso a paso
Paso 1: Definir modelos y alcances de cuotas
El catálogo de cuotas almacena el tipo de recurso, alcance, unidad, ventana, límite, capacidad de ajuste y versión de configuración. Una cuota de tasa limita el consumo en una ventana de tiempo, una cuota de concurrencia limita las operaciones que se ejecutan simultáneamente y una cuota de asignación limita los recursos ya asignados. Un límite de organización puede ser el tope; las reservas de inquilinos y proyectos deben encajar dentro de la capacidad restante del padre para que las verificaciones independientes no sobrevenda el total.
Paso 2: Diseñar verificaciones sincrónicas y reservas atómicas
La ruta sincrónica posee los datos fácticos que afectan la admisión: contadores de la ventana actual, reservas activas y versión de configuración. Utiliza claves particionadas (sharded) para tráfico pesado o almacenamiento particionado por inquilino fuertemente consistente para un inquilino de alta carga. Una reserva debe verificar la capacidad restante e incrementar el monto reservado de forma atómica, evitando que dos solicitudes concurrentes usen el mismo saldo. Los trabajos de larga duración reciben un ID de reserva; la finalización, cancelación y expiración son idempotentes.
checkAndReserve(tenant, dimensions, amount, requestId, configVersion)
verify configVersion is active
if requestId already committed: return previous decision
atomically check remaining quota and add reservation
persist reservation with expiry and requestId
return reservationId and retryAfterPaso 3: Desacoplar los eventos de uso de la agregación de medición
El éxito, fallo, cancelación y expiración deben emitir eventos. Cada evento transporta inquilino, proyecto, recurso, cantidad, unidad, marca de tiempo del evento y un ID de evento único. Con entrega al menos una vez (at-least-once), los consumidores desduplican por ID de evento; los eventos fuera de orden utilizan una ventana basada en la hora del evento o un libro de registro reproducible. Los agregados atienden consultas, alertas de umbral y datos para facturación, pero no deben sobreescribir el libro de registro de reservas sincrónico.
Paso 4: Manejar excesos, cambios de cuota y equidad
Rechaza o encola cuando se agote una cuota estricta; un umbral flexible debe disparar una alerta. Si se permite el exceso, debe ser una configuración de producto explícita con un actor autorizado y una regla de precio. Antes de reducir una cuota, inspecciona las reservas existentes para que el trabajo ya aceptado no pierda capacidad repentinamente. Un inquilino de alta carga no debe consumir un shard compartido; los límites de concurrencia por inquilino, los cubos de tokens (token buckets) y las colas equitativas (fair queues) pueden proteger a los demás inquilinos. Las solicitudes de aumento deben seguir reglas de aprobación o automatización y conservar versiones anteriores para auditoría.
Paso 5: Comportamiento multirregión, recuperación y conciliación
Si un límite estricto debe ser globalmente exacto, enruta el recurso a una única autoridad o utiliza almacenamiento respaldado por consenso. Si la disponibilidad importa más, asigna presupuestos regionales y declara la sobreventa máxima. Durante una partición regional, rechaza decisiones de límite estricto que no puedan tomarse de manera segura; un límite flexible puede degradarse temporalmente a solo emitir alertas. Tras la recuperación, reproduce los eventos inmutables y registros de reservas, compara decisiones de admisión, agregados y resultados de facturación, y repara las diferencias con eventos compensatorios en lugar de editar el historial.
6. Ejemplo de respuesta de alta calidad
Separaría el sistema en un catálogo de cuotas, un motor de admisión sincrónico, un libro de registro de reservas, una canalización asincrónica de medición y consultas de auditoría. El catálogo define alcances de organización, inquilino y proyecto, además de límites de tasa, concurrencia y asignación. La admisión utiliza dimensiones del inquilino y un ID de idempotencia para verificar y reservar atómicamente; los trabajos de larga duración obtienen un ID de reserva y hacen que la finalización, cancelación y expiración sean idempotentes. Los eventos de éxito y fallo entran a una canalización de entrega al menos una vez; los consumidores desduplican por ID de evento y agregan por tiempo de evento para alertas y facturación, sin sobreescribir el libro de registro de admisión. Por recurso, el comportamiento multirregión es autoritativo o de sobreventa acotada. Durante una falla, se protegen las cuotas estrictas; tras la recuperación, se reproduce y concilia, asegurando que cada cambio y compensación sea auditable.
7. Errores comunes
- Usar un único contador compartido → un inquilino de alta carga ralentiza a todos → particiona por inquilino y aplica topes justos.
- Permitir que un agregado asincrónico decida la admisión → el retraso en eventos causa sobreventa → mantén un libro de registro de reservas atómico como fuente de verdad para la admisión.
- Analizar únicamente límites de tasa → los trabajos largos y el almacenamiento consumen capacidad ilimitada → modela límites de tasa, concurrencia y asignación.
- Desduplicar solo IDs de solicitud → los eventos reintentados se cuentan dos veces → utiliza claves de idempotencia separadas para reservas y eventos de uso.
- Sobreescribir el saldo al reducir una cuota → el trabajo aceptado es rechazado repentinamente → versiona la configuración e inspecciona las reservas existentes.
8. Preguntas de seguimiento y respuestas
Pregunta de seguimiento 1: ¿Por qué no depender únicamente de un contador de Redis?
Un contador es útil para estadísticas de ventana de baja latencia, pero las reservas atómicas entre recursos, la expiración de trabajos, las versiones de configuración y las auditorías requieren un libro de registro más completo. Un contador solo puede ser una ruta rápida cuando existen un registro autoritativo y un proceso de reconstrucción.
Pregunta de seguimiento 2: ¿Cómo evitas que eventos de uso duplicados se facturen dos veces?
Asigna a cada evento un ID único y estable. El consumidor escribe el registro de desduplicación y el agregado en una sola transacción, o utiliza una operación atómica equivalente. Los agregados se mantienen recalculables; la facturación consume una versión de agregado confirmada y conserva eventos compensatorios.
Pregunta de seguimiento 3: ¿Se continúa admitiendo trabajo durante una partición multirregión?
Pausa o enruta los recursos a la autoridad para cuotas estrictas que no admiten sobreventa. Para una cuota flexible con un presupuesto de sobreventa acotado, admite trabajo desde las asignaciones regionales y registra el riesgo máximo. La decisión responde a las pérdidas comerciales y a los objetivos de consistencia.
Pregunta de seguimiento 4: ¿Cómo pruebas el servicio de cuotas?
Realiza pruebas de carga con inquilinos de alta demanda, reservas concurrentes, eventos duplicados y fuera de orden, reducción de versiones de configuración, partición regional, reproducción de consumidores y cambio de ciclo/período. Comprueba que los límites estrictos nunca se rompan, que las operaciones idempotentes sean estables y que el libro de registro, los agregados y la facturación converjan tras la recuperación.