Planteamiento y alcance
Un servicio de cuotas responde si se puede reclamar una cantidad de recursos ahora; no mueve archivos ni ejecuta la operación de negocio. El diseño debe separar la capacidad autoritativa, las reservas temporales y el uso final, manteniendo al mismo tiempo la equidad en la infraestructura compartida.
Qué evalúa el entrevistador
- Distinguir entre límites de tasa (rate limits), cuotas de capacidad, reservas y confirmaciones.
- Prevenir la sobreventa con actualizaciones concurrentes y APIs idempotentes.
- Recuperar reservas expiradas después de caídas del emisor y reintentos.
- Razonar sobre la equidad entre inquilinos, claves calientes (hot keys), consistencia regional y degradación.
Preguntas de clarificación para hacer
Aclare la dimensión del recurso (solicitudes, bytes o trabajos concurrentes), el alcance (inquilino, proyecto, usuario o endpoint), las reglas de ráfaga y jerarquía, la duración de la reserva, la consistencia de facturación y si las solicitudes interregionales pueden usar una sola autoridad.
La respuesta de 30 segundos
Mantendría una máquina de estados autoritativa por clave de recurso con limit, committed y reserved, exponiendo APIs de reserva, confirmación, liberación y consulta. La reserva realiza una comprobación condicional atómica y lleva un reservation_id idempotente y una expiración. La confirmación convierte una reserva en uso; la liberación o expiración la devuelve. Un registro de eventos inmutable y la conciliación reparan desviaciones, mientras que las reglas de enrutamiento y equidad evitan que un inquilino con alta carga prive de recursos a otros.
Análisis paso a paso a fondo
1. Definir los límites del estado y la API
Cada registro de cuota tiene una clave de recurso, límite, cantidad confirmada, cantidad reservada, versión y marca de tiempo de actualización. reserve devuelve un reservation_id, la cantidad disponible y la expiración; commit solo puede consumir su reserva; release es repetible; la consulta devuelve la capacidad restante y la frescura. El emisor reserva antes de escribir el recurso, confirma después del éxito y libera en caso de fallo o cancelación.
2. Prevenir la sobreventa bajo concurrencia
La actualización de una clave de recurso debe ser una transacción atómica o una operación de almacenamiento linealizable: reservar solo cuando committed + reserved + amount <= limit. Repetir una clave de idempotencia devuelve el resultado original; cambiar sus parámetros se rechaza. Las claves calientes pueden particionarse por inquilino o recurso, pero el diseño debe establecer si se permite un exceso temporal y cómo se concilian las particiones.
3. Recuperar reservas filtradas
Los emisores pueden fallar después de reservar, por lo que se debe almacenar una expiración y recuperar la capacidad mediante un escáner o una cola retardada. Gestione las carreras entre recuperación y confirmación con condiciones de estado: una reserva confirmada no se puede liberar y una reserva liberada no se puede confirmar. Monitoree el retraso de recuperación para que una limpieza demorada no se confunda con capacidad disponible.
4. Manejar grupos compartidos y equidad
Un grupo compartido puede tener restricciones globales, de inquilino y de proyecto. Compruébelas en un orden fijo y dentro de una sola transacción. Asigne ráfagas según la cuota del inquilino, prioridad o equidad ponderada para que un solo inquilino no pueda consumir todo el grupo. Devuelva la capacidad restante, los tiempos de reintento o el estado de la cola para reducir los reintentos a ciegas.
5. Diseñar fallas, regiones y conciliación
Si la autoridad no está disponible, rechace de manera conservadora las reservas de alto riesgo en lugar de gastar capacidad facturable a partir de un estado desconocido; las lecturas de bajo riesgo pueden devolver una aproximación con marca de tiempo. Asigne un inquilino a una región de origen (home region) o defina un límite explícito de exceso local y concilie de forma asíncrona. Escriba cada reserva, confirmación y liberación en un registro inmutable, compárelo con el uso real de recursos y repare desviaciones con tareas de compensación idempotentes.
Un ejemplo de respuesta sólida
Aclararía el recurso, la jerarquía de inquilinos, la duración de la reserva y el requisito de consistencia. El servicio almacena límite, confirmado, reservado y versión por clave de recurso y expone operaciones de reserva, confirmación, liberación y consulta basadas en reservation_id. La reserva comprueba la suma de manera atómica; los reintentos devuelven el mismo resultado. Los emisores confirman después de una escritura exitosa, liberan en caso de fallo y un recuperador maneja la expiración. Los grupos compartidos verifican los límites globales y del inquilino juntos y utilizan enrutamiento fijo, prioridad o equidad ponderada. Ante una falla de la autoridad, las escrituras de alto riesgo fallan cerradas (fail closed). La ubicación multirregión utiliza una región de origen del inquilino o un exceso acotado explícito. Un registro inmutable y una conciliación periódica mantienen la cuota registrada alineada con el uso real.
Errores comunes
- Tratar la cuota como un limitador de tasa que solo devuelve 429.
- Leer la capacidad restante y escribir más tarde sin una condición atómica.
- Omitir la identidad de la reserva, la expiración y la semántica de idempotencia.
- Permitir que un emisor caído retenga capacidad para siempre.
- Ignorar los grupos compartidos, la jerarquía y la equidad ante vecinos ruidosos (noisy neighbors).
- Fallar abierto (fail open) durante una interrupción de almacenamiento y corregir contadores manualmente después.
Preguntas de seguimiento y respuestas
El emisor agota el tiempo de espera antes de confirmar. ¿Reintentar o reservar de nuevo?
Consulte o reintente la confirmación con el mismo reservation_id primero. Cree una nueva reserva solo después de confirmar que la anterior fue liberada o expiró.
¿Qué pasa si varios productos comparten la cuota de un inquilino?
Trate al inquilino como el elemento padre compartido y a los productos como restricciones secundarias, comprobando ambos en una sola transacción. Informe qué capa se ha agotado para que los clientes puedan encolar o degradar.
¿Pueden las regiones reservar concurrentemente?
Para capacidad facturable que no admite sobreventa, utilice una sola autoridad o coordinación fuerte. Si un exceso acotado es aceptable, asigne a cada región un límite de préstamo y concilie la deuda explícitamente.
¿Cómo detecta la desviación de cuotas?
Compare los eventos del registro y los escaneos de recursos con el uso confirmado, reservado y real por inquilino y tipo de recurso. Genere alertas sobre diferencias y ejecute tareas de compensación auditables e idempotentes.