Declaración del problema y cuándo aplica
Diseña un generador distribuido de IDs únicos a lo largo de cuatro regiones. Cada región tiene como máximo 200 workers generadores. La flota alcanza un pico de 2 millones de IDs por segundo, mientras que cualquier worker individual puede generar hasta 3,000 IDs en un solo milisegundo. Cada ID debe ser un entero positivo de 64 bits, globalmente único, ordenado aproximadamente por tiempo de generación y utilizable durante al menos 60 años. La ruta crítica (hot path) no puede realizar una solicitud de red por cada ID. El objetivo de latencia es un p99 igual o menor a 5 milisegundos y el objetivo de disponibilidad es del 99.99%, pero el generador debe detenerse antes de arriesgarse a emitir un duplicado.
Se permiten huecos (gaps) y no se requiere un orden monótono estricto entre regiones. Los IDs son identificadores de mensajes internos y claves primarias de bases de datos, por lo que la predictibilidad es aceptable por ahora. Se necesita un tratamiento separado si un identificador se expondrá a clientes no confiables. Estas capacidades y SLOs son restricciones de entrevista, no afirmaciones sobre el tráfico de producción de ninguna empresa.
Esta pregunta encaja en entrevistas de backend senior, infraestructura y diseño de sistemas. La verdadera tarea consiste en transformar los requisitos de vida útil, cantidad de workers y ráfagas por milisegundo en un presupuesto de bits, para luego demostrar que las fallas de reloj, concurrencia e identidad de workers no pueden crear duplicados. Decir únicamente “usar Snowflake” no es un diseño.
Qué evalúa el entrevistador
Primero, ¿puede el candidato separar unicidad, orden, continuidad e impredecibilidad? Snowflake puede proporcionar enteros de 64 bits únicos y ordenados aproximadamente por tiempo. No proporciona automáticamente una secuencia sin huecos, orden causal entre regiones ni un token de seguridad. Un requisito diferente cambia el diseño.
Segundo, ¿puede el candidato derivar la distribución a partir de las restricciones? Una respuesta sólida calcula qué cubren 41 bits de marca de tiempo, 10 bits de worker y 12 bits de secuencia, y luego verifica la vida útil de 60 años, los 800 workers y los 3,000 IDs por worker por milisegundo. No copia la división clásica buscando una justificación después.
Tercero, ¿puede el candidato demostrar que los IDs no se repiten? La corrección requiere un único propietario activo para un código de worker dentro de cualquier rango de tiempo superpuesto, que dicho worker no reutilice la secuencia dentro de un mismo milisegundo y que no haya retrocesos de reloj o reinicios que vuelvan a entrar en un rango de marca de tiempo y secuencia previamente utilizado.
Cuarto, ¿puede el candidato completar el diseño frente a fallas? El agotamiento de secuencias, relojes hacia atrás, concesiones (leases) perdidas, procesos resucitados, aislamiento regional y el agotamiento de la marca de tiempo pueden amenazar la unicidad o la disponibilidad. La respuesta necesita condiciones de parada explícitas, alertas y procedimientos de recuperación.
Quinto, ¿puede el candidato elegir entre Snowflake, UUIDv7, UUIDs aleatorios y asignación centralizada o por segmentos según las restricciones? El requisito de 64 bits y la ausencia de coordinación por cada ID favorecen a Snowflake en este caso. Si se aceptaran 128 bits y no fuera deseable registrar workers, UUIDv7 sería una opción más simple.
Preguntas para clarificar antes de responder
- ¿La unicidad es determinista o se acepta una probabilidad minúscula de colisión? La unicidad determinista necesita espacios de nombres de workers aislados. Si la unicidad probabilística es aceptable, UUIDv4 o UUIDv7 pueden eliminar la asignación de workers.
- ¿El identificador debe ser de 64 bits? Si la base de datos, el protocolo y los índices aceptan 128 bits, el estándar UUIDv7 ofrece un prefijo temporal y espacio aleatorio con un plano de control más simple. Este problema fija la salida a un entero positivo de 64 bits.
- ¿Qué tan estricto es el “ordenado”? El orden temporal aproximado puede usar relojes locales. El orden total estricto entre regiones requiere un secuenciador centralizado, un log de consenso o una secuencia particionada por negocio, lo cual tiene costos muy distintos.
- ¿Se permiten huecos? La preasignación de segmentos, caídas y reintentos pueden dejar huecos. Combinar la ausencia de huecos con un incremento global estricto traslada la asignación a una ruta de transacción serial. Aquí se permiten huecos.
- ¿Los IDs serán públicos? Los bits de marca de tiempo y de worker pueden revelar el momento de creación e información del despliegue, mientras que los valores incrementales pueden enumerarse. Eso puede ser aceptable para claves internas; los identificadores públicos deben usar un valor opaco separado.
- ¿Cómo se crean y reemplazan los workers? Máquinas fijas, contenedores orquestados y autoescalado tienen diferentes riesgos de reutilización de identidad de workers. Los workers dinámicos necesitan leases, fencing y una regla de reutilización segura.
- ¿Qué tiene prioridad durante una partición de red? Los workers existentes pueden continuar mientras su plano de control regional esté saludable y sus leases sigan siendo seguros. Un worker debe detenerse cuando no se pueda demostrar la propiedad exclusiva, sacrificando algo de disponibilidad.
La respuesta de 30 segundos
“Dividiría los 64 bits en un bit de signo fijo, 41 bits de tiempo en milisegundos, 10 bits para región más worker y una secuencia de 12 bits por milisegundo. Eso cubre unos 69.7 años, 1,024 códigos de worker y 4,096 IDs por worker por milisegundo, por lo que cumple con las restricciones. Cada worker genera (timestamp, worker, sequence) dentro de una sección crítica local, sin llamadas de red en la ruta crítica. Un plano de control regional asigna y renueva los leases de los workers. El worker nunca reinicia el ciclo (wrap) ante el agotamiento de secuencia y se detiene ante la pérdida del lease o un retroceso de reloj no seguro. El resultado está ordenado aproximadamente por tiempo, no estrictamente ordenado entre regiones. Si se permitieran 128 bits y quisiera eliminar el registro de workers, evaluaría UUIDv7”.
Análisis paso a paso a profundidad
Paso 1: Usar las restricciones para descartar valores predeterminados inadecuados
Una secuencia de base de datos centralizada proporciona un orden claro, pero cada asignación entra en una ruta de escritura compartida. Eso entra en conflicto con los requisitos de evitar la red en la ruta crítica y mantener el aislamiento regional. Asignar rangos en lotes amortiza la coordinación, pero deja huecos cuando un worker falla. Como se permiten huecos, la asignación por segmentos sigue siendo una alternativa viable, aunque aún requiere un servicio de rangos y una política de precarga (prefetch).
UUIDv4 y UUIDv7 son formatos de 128 bits. UUIDv4 es aleatorio y no proporciona orden temporal. Bajo RFC 9562, UUIDv7 coloca una marca de tiempo Unix en milisegundos de 48 bits en la porción más significativa y utiliza el espacio restante para versión, variante y campos aleatorios o monótonos. Puede producir valores ordenados aproximadamente sin registrar workers, pero viola el requisito de 64 bits de este problema.
Eso nos deja con una estructura de 64 bits estilo Snowflake. Decir que es “libre de coordinación” aplica únicamente a cada asignación en la ruta crítica; la identidad del worker todavía necesita un plano de control. Ocultar ese costo no hace que el sistema esté libre de coordinación.
Paso 2: Derivar la estructura 1 + 41 + 10 + 12 a partir de la capacidad
Reserva el bit más significativo como cero para que el valor siga siendo un entero con signo positivo de 64 bits, y luego asigna los 63 bits restantes de la siguiente manera:
| Campo | Bits | Rango | Ajuste al requisito |
|---|---|---|---|
| Signo | 1 | Fijo en 0 | Mantiene el BIGINT positivo |
| Milisegundos desde una época personalizada | 41 | 2^41 milisegundos, aprox. 69.7 años | Supera la vida útil de 60 años |
| Región + worker | 10 | 1,024 códigos | 2 bits de región × 8 bits de worker local admite 4 × 256 workers |
| Secuencia dentro de un milisegundo | 12 | 0–4,095, o 4,096 valores | Supera los 3,000 IDs por worker por milisegundo |
El total es de 1 + 41 + 10 + 12 = 64 bits. La flota tiene como máximo 4 × 200 = 800 workers, por debajo de 1,024, y 200 workers por región caben dentro de los 256 valores provistos por 8 bits. El rango de tiempo de 41 bits es de aproximadamente 2^41 ÷ 1000 ÷ 60 ÷ 60 ÷ 24 ÷ 365.2425 = 69.7 años. Para satisfacer estrictamente el requisito de ser “positivo”, reserva el ID con todos los bits en cero y sitúa la época personalizada antes de la primera asignación. De este modo, incluso la secuencia cero en el primer worker nunca devolverá 0.
La tasa para toda la flota de 2 millones de IDs por segundo es una comprobación de capacidad agregada. El campo de secuencia debe satisfacer la ráfaga más estricta por worker y por milisegundo. Un cálculo promedio por segundo no puede demostrar que 12 bits sean suficientes: un solo worker puede agotar su secuencia incluso cuando el QPS global de la flota sea bajo.
Paso 3: Implementar la generación local y demostrar la unicidad
Cada worker utiliza operaciones con enteros de 64 bits y protege lastMs y sequence con un bloqueo o una sección crítica atómica:
nextId():
lock
now = wallClockMs() - customEpochMs
if now < lastMs:
fail("clock_moved_back")
if now == lastMs:
if sequence == 4095:
now = waitUntilAfter(lastMs)
sequence = 0
else:
sequence = sequence + 1
else:
sequence = 0
lastMs = now
return (now << 22) | (workerCode << 12) | sequenceLa secuencia no debe volver a cero silenciosamente después de 4,095 mientras el reloj permanezca en el mismo milisegundo; eso duplicaría inmediatamente un valor anterior. El ID número 4,096 es válido porque la secuencia comienza en cero. La solicitud número 4,097 en ese mismo milisegundo debe esperar al siguiente milisegundo o recibir un error de sobrecarga.
La prueba de unicidad tiene tres casos. Diferentes workers tienen distintos códigos de worker de 10 bits. El mismo worker en diferentes milisegundos tiene distintas marcas de tiempo de 41 bits. El mismo worker en el mismo milisegundo tiene diferentes valores de secuencia de 12 bits. Si los campos se mantienen dentro de rango, la propiedad del worker no se superpone y el reloj nunca vuelve a un estado ya utilizado, la carga útil completa de 63 bits no se puede repetir.
Paso 4: Colocar la identidad del worker en el plano de control
Ejecuta un asignador de leases de workers independiente en cada región, fijando el código de 2 bits de la región mediante la configuración de despliegue. El plano de control almacena:
| Campo | Propósito |
|---|---|
region_id, worker_id | Forman el código global de worker de 10 bits |
owner_id | Identifica el proceso actual o la instancia de despliegue |
fencing_token | Distingue entre propietarios más nuevos y más antiguos de un mismo código de worker |
lease_expires_at | Delimita cuánto tiempo sigue siendo válida la propiedad |
timestamp_ceiling_ms | Delimita el rango de marcas de tiempo que el antiguo propietario puede usar durante la reutilización segura |
Al iniciar, un nodo adquiere un ID de worker y un lease. La ruta crítica del ID verifica únicamente el estado del propietario, el estado de fencing, un límite de tiempo de seguridad del lease en memoria y now <= timestamp_ceiling_ms; la renovación se produce de forma asíncrona, por lo que la asignación no contacta al plano de control por cada ID. Un nodo deja de generar tan pronto como su lease no sea seguro o alcance el techo de marca de tiempo. Antes de reutilizar ese ID de worker para un reemplazo, el plano de control debe aplicar fencing al antiguo propietario y esperar hasta que el reloj del nuevo nodo supere el timestamp_ceiling_ms del lease anterior. Así, ni siquiera un nodo antiguo demorado y su reemplazo podrán usar el mismo rango de marcas de tiempo.
El token de fencing no se codifica en el ID final, por lo que no puede reparar una colisión una vez ocurrida. Mantiene a un propietario desactualizado fuera de la ruta de generación. Si una plataforma no puede aplicar fencing a procesos antiguos de manera confiable, debería asignar IDs de worker duraderos y no reutilizados a ranuras de despliegue (deployment slots) o usar UUIDv7 en lugar de asumir que un lease por sí solo resuelve la resurrección de procesos.
Paso 5: Definir condiciones de parada para relojes, desbordamiento y particiones
La política para now < lastMs debe ser acotada. Un ejemplo es esperar ante un retroceso de como máximo 5 milisegundos únicamente cuando a la solicitud le quede suficiente presupuesto de latencia; la espera se descuenta del presupuesto p99 de 5 milisegundos. Para un retroceso mayor o presupuesto insuficiente, devuelve un error reintentable, retira el nodo de servicio y genera una alerta. Al iniciar el proceso, compara la hora actual con la marca de agua alta persistente de ese worker y rechaza el inicio si el reloj está atrasado. Mantener lastMs únicamente en memoria no cubre los reinicios.
Cuando la secuencia se agote, espera al siguiente milisegundo e incrementa una métrica sequence_exhausted. El agotamiento frecuente significa que la carga está desbalanceada o que el presupuesto de bits es incorrecto. Distribuye el tráfico, añade workers o asigna más bits de secuencia en un nuevo formato. Nunca des la vuelta (wrap) a la secuencia.
Durante el aislamiento entre regiones o de la red global, el campo de región de 2 bits sigue separando los espacios de nombres. Los workers existentes pueden continuar localmente mientras sus leases regionales sigan siendo seguros. Si el servicio de leases regional no está disponible y el límite de seguridad expira, esos workers se detienen. La unicidad tiene prioridad sobre el objetivo de disponibilidad del 99.99%, y la excepción debe documentarse en el SLO y en las alertas.
La marca de tiempo de 41 bits eventualmente expira. Expón el tiempo de vida restante de la época e inicia la migración con años de anticipación. Nunca reinicies la marca de tiempo tras un desbordamiento ni reinterpretes silenciosamente la misma columna de 64 bits con una nueva estructura. Agregar regiones o expandir el recuento de workers requiere el mismo tipo de migración de formato.
Paso 6: Establecer lo que realmente significan “ordenado” y “seguro”
Colocar el tiempo en los bits superiores hace que los IDs estén aproximadamente ordenados, pero el desfase del reloj (clock skew) puede hacer que un registro posterior tenga un ID menor. Los bits de worker también afectan el orden dentro de un mismo milisegundo. Un ID de Snowflake no demuestra causalidad entre regiones y no puede reemplazar la secuencia de confirmación (commit) de un libro mayor de pagos.
Si una API realiza una sincronización incremental con id > cursor, un ID que llegue tarde desde un reloj lento puede ser menor que el cursor guardado y quedar omitido para siempre. Cuando el orden completo importa, utiliza una secuencia de commit de base de datos, una posición en un log de consenso o un secuenciador acotado a una partición de negocio, como una conversación o una cuenta. Snowflake sigue siendo la identidad, no la autoridad de ordenamiento.
El ID en crudo también expone un tiempo de creación aproximado y puede revelar bits de región o worker. No es una credencial de autorización. Un recurso público puede conservar la clave interna de 64 bits y exponer un identificador opaco independiente. Nunca confíes en que un ID sea difícil de adivinar para proteger los datos.
Paso 7: Comparar alternativas bajo las mismas restricciones
| Enfoque | Ancho y orden | Coordinación | Mejor caso de uso | Costo principal |
|---|---|---|---|---|
| Estilo Snowflake | 64 bits, orden aproximado | Coordinación al inicio y renovación; ruta crítica local | IDs de 64 bits, rendimiento muy alto, orden aproximado | Gestión de reloj y workers |
| UUIDv7 | 128 bits, prefijo temporal | Sin registro de workers | Se aceptan 128 bits y se prefiere un formato estándar sin plano de control de workers | Valores más anchos; la unicidad depende de la calidad de la aleatoriedad y la implementación |
| UUIDv4 | 128 bits, orden aleatorio | Ninguna | El orden no es necesario y la opacidad importa | Peor localidad de índice y sin inferencia de tiempo a partir del ID |
| Secuenciador central / segmentos | Generalmente 64 bits, incremento estricto o aproximado | Asignación mediante servicio o base de datos; los segmentos pueden agruparse en lotes | Se requiere orden central o el sistema ya depende de una base de datos | Dependencia de red/base de datos; los lotes dejan huecos |
Snowflake gana en este problema debido a la restricción estricta de 64 bits y la prohibición de llamadas de red por cada ID. Si el entrevistador elimina la restricción de 64 bits, reconsidera UUIDv7. Si se requiere un orden total estricto, reconoce que Snowflake no lo cumple y pasa a un secuenciador serializado en lugar de parchar la primitiva equivocada.
Paso 8: Validar mediante inyección de fallas
La validación debe ir más allá de generar una muestra normal grande sin duplicados. Cubre al menos estos casos:
- Congela el tiempo y genera 4,096 IDs desde un solo worker en un milisegundo. Todos deben ser únicos; el número 4,097 debe esperar o fallar.
- Invoca un generador concurrentemente y verifica que la sección crítica local evite que dos hilos reutilicen una secuencia.
- Retrocede el reloj 1, 5 y 2,000 milisegundos y verifica las rutas de espera, tiempo de espera agotado (timeout), retirada del servicio y alerta.
- Pausa un propietario antiguo, deja que expire su lease, activa un nuevo propietario y luego reanuda el propietario antiguo. Verifica que el fencing impida que el proceso obsoleto genere IDs.
- Congela las cuatro regiones y los 800 workers en el mismo milisegundo, genera diferentes secuencias y verifica los rangos de campos decodificados y la unicidad global.
- Aísla el servicio regional de leases. Los workers existentes pueden continuar dentro del intervalo seguro del lease y deben fallar de forma cerrada (fail closed) después.
- Avanza el tiempo a
2^41 - 1y verifica que el siguiente milisegundo sea rechazado y dispare la alerta de migración.
Como mínimo, el monitoreo en producción debe cubrir clock_rollback_ms, sequence_exhausted, fallas de renovación de leases, margen disponible de códigos de worker, latencia de generación, tasa de errores y vida útil restante de la época. Una restricción unique en la base de datos es una última línea de defensa útil y una fuente de alertas, pero capturar una colisión y reintentar no reemplaza la corrección del generador.
Respuesta de ejemplo de alta calidad
“Primero confirmaría que el requisito sea un ID positivo de 64 bits deterministamente único. Se permiten huecos y el orden solo necesita ser aproximado. Con cuatro regiones, 200 workers por región y hasta 3,000 IDs por worker por milisegundo, elegiría un diseño estilo Snowflake en lugar de un UUIDv7 de 128 bits o una llamada a un secuenciador centralizado por cada ID.
El bit más significativo permanece en cero. Una marca de tiempo en milisegundos con época personalizada de 41 bits dura unos 69.7 años. Diez bits de worker se dividen en 2 bits de región y 8 bits de worker local, cubriendo 4 × 256 nodos. Una secuencia de 12 bits produce 4,096 valores por worker por milisegundo. Las tres dimensiones superan las restricciones establecidas y utilizan exactamente la carga útil de 63 bits.
Cada worker mantiene lastMs y sequence en una sección crítica local. Reinicia la secuencia cuando el tiempo avanza, la incrementa dentro del mismo milisegundo y espera después de la secuencia 4,095. Nunca continúa ante un retroceso del reloj: hasta 5 milisegundos pueden esperar dentro del presupuesto de latencia, mientras que un retroceso mayor retira al worker y alerta. Diferentes códigos de worker separan a los workers, las marcas de tiempo separan los milisegundos para un mismo worker y las secuencias separan los IDs dentro de un milisegundo de un worker.
Ejecutaría un plano de control regional para leases de workers. Los nodos lo contactan solo al iniciar y para renovación asíncrona, mientras que la generación permanece local. Un propietario anterior se detiene tras perder su lease. Antes de reutilizar su ID de worker, el asignador aplica fencing al propietario anterior y asegura que el reloj del reemplazo supere el techo de marca de tiempo del lease antiguo. Si no se puede probar la propiedad exclusiva, el worker se detiene.
Por último, señalaría que esto proporciona solo un orden aproximado. El orden estricto entre regiones necesita un log de consenso o un secuenciador particionado por negocio, y los IDs públicos no enumerables necesitan un valor opaco separado. La validación incluiría la solicitud número 4,097 en un milisegundo, acceso concurrente a la secuencia, un retroceso de reloj de dos segundos, toma de control del lease y agotamiento de la época, no solo el camino feliz”.
Errores comunes
- Decir “usar UUID” de inmediato → La respuesta nunca aclara el ancho, el orden o la semántica de colisiones → Separa primero UUIDv4, UUIDv7 y un espacio de nombres determinista de workers.
- Copiar 41-10-12 → No hay prueba de que la vida útil, los workers o la capacidad de ráfaga encajen → Calcula
2^41milisegundos,2^10códigos de worker y2^12valores de secuencia por separado. - Usar solo el QPS promedio de la flota → Una ráfaga por worker y por milisegundo aún puede agotar la secuencia → Valida la capacidad en la unidad de tiempo más pequeña y en el worker con mayor carga.
- Hacer un wrap de la secuencia con una máscara → El mismo worker repite un ID en el mismo milisegundo → Espera al siguiente milisegundo, aplica contrapresión (backpressure) o falla.
- Poner un ID de worker en la configuración y detenerse ahí → El autoescalado, la configuración copiada y la resurrección de procesos crean dos propietarios → Diseña leases, fencing, reutilización segura y condiciones de parada.
- Continuar con el reloj de pared actual tras un retroceso → El worker puede repetir un par de marca de tiempo y secuencia → Espera dentro de un límite o falla de forma cerrada, y verifica una marca de agua alta persistente tras reiniciar.
- Llamar al orden aproximado monótono global → El desfase de reloj y los workers concurrentes alteran el orden → Usa un log serializado o un secuenciador particionado cuando se requiera orden estricto.
- Tratar el ID como control de acceso → Un ID decodificable o enumerable no autoriza una solicitud → Expón un identificador opaco separado y sigue aplicando autorización en el servidor.
- Probar únicamente millones de IDs normales → La carga aleatoria ordinaria rara vez alcanza los límites peligrosos → Congela el tiempo e inyecta retrocesos, tomas de control de leases y agotamiento de campos.
Preguntas de seguimiento y respuestas
Pregunta de seguimiento 1: ¿Qué cambia si los IDs deben incrementarse estrictamente entre regiones sin huecos?
Snowflake deja de calificar. El orden total estricto requiere que cada asignación pase por un punto de linealización, como un único estado de secuencia en un log de consenso. La ausencia de huecos también significa que el número debe confirmarse junto con la transacción de negocio exitosa, por lo que los segmentos precargados no utilizados son inaceptables. El lado minoritario de una partición de red debe detenerse, reduciendo el rendimiento, la disponibilidad y aumentando la latencia. Pregunta si el negocio realmente necesita ausencia de huecos; muchos sistemas de auditoría necesitan una referencia de negocio inmutable, no una clave primaria de base de datos sin huecos.
Pregunta de seguimiento 2: ¿Cómo agregarías una quinta región o admitirías 300 workers por región?
Los 2 bits de región y 8 bits de worker local actuales no pueden representar ninguno de los dos casos. Antes del lanzamiento, los 10 bits podrían repartirse añadiendo un bit de región y reduciendo la capacidad de workers locales. Una vez que existen IDs, los valores antiguos no pueden reinterpretarse en línea bajo el nuevo límite. Introduce un formato nuevo explícito o migra a identificadores de 128 bits, haciendo que lectores y escritores reconozcan ambas versiones. Mover silenciosamente el límite de bits rompe los supuestos de decodificación, orden y unicidad.
Pregunta de seguimiento 3: El reloj de un nodo retrocede dos segundos. ¿Pueden los bits de secuencia mantenerlo disponible?
No de forma segura con una solución no persistida. Después de un reinicio, el proceso puede olvidar qué marca de tiempo lógica tomó prestada. Bajo la política establecida, retira el nodo inmediatamente, alerta y desvía el tráfico a otra parte. Restáuralo solo después de que el tiempo de pared alcance a lastMs o tras recuperar un tiempo lógico comprobado a partir de una marca de agua alta persistente. Si mantener la disponibilidad durante el retroceso es obligatorio, utiliza un diseño deliberado de reloj lógico persistente y vuelve a demostrar el comportamiento de desbordamiento, reinicio y orden; decir simplemente “usar un reloj lógico” omite el difícil problema de la recuperación de estado.
Pregunta de seguimiento 4: El ID aparecerá en una URL pública de pedidos. ¿Cómo evitas la enumeración y la filtración del volumen de ventas?
Mantén Snowflake como la clave de unión interna y genera un identificador externo aleatorio separado. UUIDv4 es adecuado cuando se desea suficiente entropía y opacidad; UUIDv7 es una opción si filtrar un prefijo temporal es aceptable. Almacena el mapeo en la fila del pedido. Cada lectura de pedido debe seguir autorizando al usuario actual, independientemente del formato del identificador. La impredecibilidad reduce el riesgo de enumeración, pero no reemplaza la autorización.
Pregunta de seguimiento 5: ¿Puede continuar la generación cuando una región pierde contacto con el plano de control global?
Sí, porque los bits de región aíslan los espacios de nombres y la asignación no necesita el plano de control global. Los workers existentes continúan mientras sus leases regionales permanezcan dentro del intervalo seguro. Si el asignador de leases regional tampoco está disponible, los workers cuyo plazo de renovación expire se detienen. El almacén regional de leases puede utilizar a su vez un clúster de consenso dentro de la región para mayor disponibilidad, pero dos particiones nunca deben renovar el mismo código de worker de forma concurrente.
Pregunta de seguimiento 6: ¿Qué pasa si un worker de repente necesita 5,000 IDs por milisegundo?
Una secuencia de 12 bits suministra solo 4,096 valores. La respuesta inmediata es contrapresión y distribución de carga hacia más workers; reiniciar el ciclo (wrapping) está prohibido. A largo plazo, asigna más bits de secuencia en un nuevo formato tomándolos de la vida útil de la marca de tiempo o de la capacidad de workers, o elimina la restricción de 64 bits y utiliza UUIDv7. Mide la distribución real de ráfagas en un milisegundo antes de cambiar la distribución; los promedios por segundo no responden a esta pregunta.
Pregunta de seguimiento 7: Si solo se requiere un orden estricto dentro de una misma conversación, ¿es necesario un secuenciador global?
No. Mapea cada conversación a una partición estable y mantén una secuencia de commit dentro de esa partición. Snowflake sigue siendo la identidad global, mientras que la secuencia de partición lleva el orden de la conversación. Esto reduce la coordinación y el dominio de falla en comparación con serializar todas las regiones. Los lectores ordenan por (conversation_id, sequence) y nunca asumen que el ID de Snowflake equivale al orden de commit de la conversación.