Respuesta A: Anthropic Claude Opus 5
SERVICIO DE NOTIFICACIÓN EN TIEMPO REAL — PLAN DE DISEÑO DEL SISTEMA
- RESUMEN DE REQUISITOS Y ESTIMACIÓN DE CAPACIDAD
Matemáticas del tráfico:
- 100M DAU x 10 eventos/día = 1000 millones de eventos desencadenantes de notificaciones por día.
- Promedio = 1000 millones / 86 400 ≈ 11 600 eventos/segundo. Pico a 5x ≈ 58 000 eventos/segundo.
- Multiplicador de fan-out: la mayoría de los eventos (me gusta, comentario, seguir, DM) se dirigen exactamente a un destinatario, por lo que el fan-out es ~1:1. Sin embargo, los eventos de cuentas con muchos seguidores (una celebridad publicando) pueden distribuirse a millone...
Mostrar respuesta completa ▼
SERVICIO DE NOTIFICACIÓN EN TIEMPO REAL — PLAN DE DISEÑO DEL SISTEMA
- RESUMEN DE REQUISITOS Y ESTIMACIÓN DE CAPACIDAD
Matemáticas del tráfico:
- 100M DAU x 10 eventos/día = 1000 millones de eventos desencadenantes de notificaciones por día.
- Promedio = 1000 millones / 86 400 ≈ 11 600 eventos/segundo. Pico a 5x ≈ 58 000 eventos/segundo.
- Multiplicador de fan-out: la mayoría de los eventos (me gusta, comentario, seguir, DM) se dirigen exactamente a un destinatario, por lo que el fan-out es ~1:1. Sin embargo, los eventos de cuentas con muchos seguidores (una celebridad publicando) pueden distribuirse a millones de destinatarios; trátelos como una ruta separada de "fan-out masivo". Suponga una entrega pico efectiva de 80 000–100 000 notificaciones/segundo, incluidas las campañas masivas.
- Almacenamiento: historial de las últimas 100 notificaciones por usuario. Suponga ~400 bytes por fila -> 100 x 400 B = 40 KB/usuario -> 100M de usuarios ≈ 4 TB de historial activo, más un factor de replicación de 3 ≈ 12 TB. Se puede fragmentar trivialmente.
- Conexiones: suponga que entre el 20% y el 25% de los DAU están en línea simultáneamente en el pico ≈ 20–25M de conexiones WebSocket activas. Con ~100 000 conexiones por nodo de puerta de enlace (Linux ajustado, epoll), eso son 200–250 nodos más margen.
Objetivos no funcionales:
- Latencia p99 de extremo a extremo inferior a 2 segundos para usuarios en línea (medida desde la ingesta de eventos hasta la confirmación del cliente).
- Disponibilidad del 99,9 % = ~43 minutos de inactividad por mes.
- Entrega al menos una vez con deduplicación idempotente en el lado del cliente/servidor.
- ARQUITECTURA DE ALTO NIVEL
El diseño es un pipeline impulsado por eventos con una clara división entre la ruta de ingesta (rápida, duradera, optimizada para escritura) y la ruta de entrega (específica del canal, reintentable).
Flujo:
Servicios productores (Servicio de Publicaciones, Servicio de Gráfico Social, Servicio de Comentarios, Servicio de Mensajería)
-> API/Puerta de Enlace de Notificaciones (gRPC + REST, autenticación, limitación de velocidad, validación de esquemas, clave de idempotencia)
-> Tópico de Kafka notification.events (particionado por recipient_user_id cuando se conoce, de lo contrario por actor_id)
-> Servicio de Fan-out (resuelve destinatarios, expande eventos de celebridades, aplica reglas de agregación)
-> Tópico de Kafka notification.deliveries (un mensaje por destinatario)
-> Servicio de Preferencias y Políticas (búsqueda en línea a través de caché: opt-ins de canal, horas de silencio, silenciar/bloquear, resumen vs. instantáneo)
-> El Enrutador/Distribuidor escribe en tópicos por canal:
deliver.websocket, deliver.mobile_push, deliver.web_push, deliver.email
-> Trabajadores de Canal:
Distribuidor WebSocket -> Búsqueda en el Registro de Conexiones -> nodo de Puerta de Enlace en Tiempo Real -> cliente
Trabajador de Push Móvil -> APNs (iOS) / FCM (Android)
Trabajador de Push Web -> Protocolo VAPID/Web Push a través de servicios de push del navegador
Trabajador de Correo Electrónico -> SES / SendGrid, con renderizado de plantillas y lotes de resúmenes
-> En paralelo, un consumidor de Escritor de Historial persiste cada entrega en la tienda de Historial de Notificaciones e incrementa los contadores de no leídos.
Transversales: Servicio de Plantillas, Registro de Dispositivos, Registro de Conexiones, Tienda de Deduplicación, Colas de Mensajes Fallidos (DLQ), pila de Observabilidad y un plano de Administración/Análisis que consume los mismos flujos de Kafka.
- COMPONENTES CLAVE Y RESPONSABILIDADES
Puerta de Enlace de API de Notificaciones
- Punto de entrada único para productores internos (gRPC, esquemas protobuf en un registro) y para APIs de lectura de clientes (REST/GraphQL para historial, marcar como leído, preferencias).
- Responsabilidades: autenticación (servicio a servicio mTLS, JWT para clientes), limitación de velocidad/cuotas por inquilino y por productor, validación de solicitudes, aceptación de claves de idempotencia y adición duradera inmediata a Kafka. Devuelve 202 Accepted rápidamente; no realiza ningún trabajo de entrega en línea.
Ingesta de Eventos / Kafka
- Registro duradero y reproducible.
notification.eventscon ~256 particiones, factor de replicación 3, min.insync.replicas=2, acks=all, retención de 7 días para recuperación de incidentes y reproducción. - Proporciona contrapresión y almacenamiento en búfer naturales para el pico 5x, desacoplando a los productores de los proveedores externos lentos.
Servicio de Fan-out
- Resuelve un evento en una lista de destinatarios. Para eventos 1:1, es un pase directo. Para eventos 1:N (nueva publicación para seguidores, actividad de hilo grupal), pagina el Servicio de Gráfico Social y emite mensajes de destinatarios en lotes.
- Estrategia de fan-out híbrida: basada en push (escribir por destinatario) para cuentas normales; basada en pull/perezosa para cuentas por encima de un umbral de seguidores (por ejemplo, 1M+), donde se escribe un único "marcador de feed" y los destinatarios se materializan al leer. Esto evita que un evento de celebridad cree una tormenta de escritura de 50 millones de mensajes en la ruta activa.
- Limita la velocidad de las expansiones masivas a un tópico de Kafka separado de baja prioridad para que nunca agoten las notificaciones interactivas.
- Aplica agregación/coalescencia: "Alice y otras 24 personas le dieron me gusta a tu publicación" en lugar de 25 filas, utilizando una ventana deslizante corta (por ejemplo, 30–60 s) con clave (destinatario, post_id, tipo) en Redis.
Servicio de Preferencias y Políticas
- Almacena y sirve preferencias de canal por usuario, opt-ins a nivel de categoría, horas de silencio con zona horaria, configuraciones a nivel de dispositivo, listas de silenciar/bloquear y banderas de consentimiento legal (GDPR/CAN-SPAM).
- La ruta de lectura se almacena en caché en Redis con invalidación write-through; objetivo de búsqueda p99 inferior a 5 ms. Fuente de verdad en una tienda relacional.
- Aplica limitación de frecuencia (por ejemplo, máximo N pushes/hora por usuario) para proteger la experiencia del usuario y las cuotas del proveedor.
Enrutador / Distribuidor
- Mapea una entrega aprobada en elementos de trabajo específicos del canal. Decide "solo en la aplicación + WebSocket si está en línea; de lo contrario, push móvil" utilizando el Registro de Conexiones, y programa resúmenes de correo electrónico en lugar de envíos instantáneos cuando las preferencias lo indican.
Puerta de Enlace en Tiempo Real (capa WebSocket)
- Nivel con estado que mantiene conexiones WebSocket persistentes (fallback: Server-Sent Events, luego long polling).
- Al conectar: autenticar, registrar (user_id, device_id) -> gateway_node_id en el Registro de Conexiones (Redis Cluster, TTL + actualización de heartbeat), luego enviar cualquier historial pendiente.
- Al entregar: el distribuidor busca el nodo, envía a través de un flujo gRPC interno o un canal Kafka/Redis Pub/Sub por nodo; la puerta de enlace escribe en el socket y espera la confirmación del cliente.
- Heartbeats cada 30 s; los heartbeats perdidos eliminan la entrada del registro y las notificaciones futuras vuelven automáticamente al push móvil.
Trabajadores de Canal
- Trabajador de Push Móvil: lotes a APNs (HTTP/2 multiplexado, autenticación basada en tokens) y FCM. Maneja límites de concurrencia por proveedor, retroceso exponencial con jitter, y elimina tokens de dispositivo no válidos/no registrados del Registro de Dispositivos.
- Trabajador de Push Web: protocolo Web Push con claves VAPID y cifrado de carga útil.
- Trabajador de Correo Electrónico: renderiza plantillas, admite resúmenes instantáneos, horarios y diarios; maneja rebotes/quejas a través de webhooks del proveedor y mantiene una lista de supresión.
- Todos los trabajadores son consumidores idempotentes con clave notification_id y escriben el estado terminal de vuelta a un tópico
delivery.status.
Escritor de Historial y Ruta de Lectura
- Consumidor que persiste notificaciones y mantiene contadores de no leídos en Redis (contador autoritativo reconciliado periódicamente desde la tienda).
- La API de lectura sirve las últimas 100 notificaciones de la tienda de historial, con una caché de Redis de la primera página por usuario para lecturas típicas de menos de 10 ms.
Servicios de Soporte
- Servicio de Plantillas: plantillas localizadas y versionadas con interpolación de variables; desacopla los cambios de copia de los despliegues de código.
- Registro de Dispositivos: token_dispositivo, plataforma, version_app, locale, timezone, last_seen.
- Tienda de Deduplicación: Redis con un TTL de 24 h en (producer_id, idempotency_key) para que al menos una vez se comporte como efectivamente una vez.
- Programador: para notificaciones retrasadas/programadas y ventanas de resumen (colas agrupadas por tiempo en conjuntos ordenados de Redis o un programador dedicado como una escalera de tópicos de retraso de Kafka).
- DLQ + Replayer: mensajes venenosos estacionados y reproducibles después de las correcciones.
- MODELO DE DATOS Y ELECCIONES DE BASE DE DATOS
a) Historial de Notificaciones — Cassandra (o ScyllaDB / DynamoDB)
Tabla: notifications_by_user
- Clave de partición: user_id
- Clave de agrupación: created_at DESC, notification_id
- Columnas: type, actor_id(s), target_type, target_id, aggregated_count, preview_text, image_url, deep_link, read_at, channels_sent, created_at
- TTL: 90 días; la aplicación limita las lecturas a 100 filas.
Justificación: el patrón de acceso es una clave de partición única y bien conocida con una rebanada ordenada por tiempo — exactamente el punto fuerte de Cassandra. Ofrece escalabilidad lineal de escritura (necesitamos 60–100K escrituras/segundo sostenidas), replicación maestra sin maestro multiregión para disponibilidad, consistencia ajustable (escribir QUORUM/LOCAL_QUORUM, leer LOCAL_ONE para el feed), y TTL nativo para la retención. No necesitamos uniones ni transacciones de varias filas aquí, por lo que una tienda relacional solo agregaría dolor de fragmentación y riesgo de amplificación de escritura.
b) Contadores de no leídos y primera página activa — Redis Cluster
- Contador entero
unread:{user_id}; lista JSON en cachénotif:page0:{user_id}.
Justificación: los contadores se leen en cada apertura de aplicación (QPS extremadamente alto, bajo valor por lectura) y deben ser de milisegundos de un solo dígito. Redis absorbe esto de manera económica; los contadores de Cassandra son comparativamente costosos y propensos a errores. Los contadores se reconcilian asincrónicamente para que la deriva se autocorrija.
c) Preferencias de usuario y tokens de dispositivo — PostgreSQL (fragmentado por user_id) con caché de lectura anticipada de Redis
Tablas: user_preferences(user_id, category, channel, enabled, quiet_hours_start, quiet_hours_end, timezone, updated_at), devices(device_id, user_id, platform, push_token, locale, last_seen, active), suppression_list(email, reason, created_at).
Justificación: estos datos son de bajo volumen, con muchas lecturas, relacionales (usuarios -> dispositivos -> configuraciones por categoría), y se benefician de transacciones y restricciones para la corrección y la auditoría (los registros de consentimiento tienen peso de cumplimiento). El volumen es lo suficientemente pequeño (~100M de filas) como para fragmentarlo trivialmente y almacenarlo en caché casi por completo.
d) Registro de Conexiones — Redis Cluster
conn:{user_id}-> conjunto de {device_id, gateway_node_id, connected_at}, TTL 90s refrescado por heartbeat.
Justificación: efímero, rotación extremadamente alta, debe ser rápido; la durabilidad no es necesaria porque una entrada perdida se degrada con gracia a fallback de push.
e) Deduplicación / idempotencia — Redis con TTL, respaldado por nada (la pérdida solo arriesga un duplicado raro).
f) Plantillas y configuración — PostgreSQL + almacenamiento de objetos para activos, almacenado en caché en el borde.
g) Analítica — eventos transmitidos desde Kafka a un data lake (S3/Parquet) y data warehouse (Snowflake/BigQuery) para informes de tasas de entrega, tasas de apertura y latencia; ClickHouse para dashboards operativos casi en tiempo real.
- RECOMENDACIONES DE STACK TECNOLÓGICO
- Lenguaje/runtime: Go para la puerta de enlace, la puerta de enlace en tiempo real y los trabajadores (goroutines y baja memoria por conexión se adaptan a millones de sockets); Java/Kotlin aceptable para agregación intensiva de Kafka Streams.
- Mensajería: Apache Kafka (gestionado: MSK/Confluent) como la columna vertebral; tópicos separados por canal y por clase de prioridad. Kafka Streams o Flink para agregación/coalescencia con ventanas.
- Transporte en tiempo real: WebSocket sobre TLS con SSE y fallbacks de long-poll; balanceo de carga NLB/L4 con vaciado de conexión; el enrutamiento pegajoso no es necesario ya que el registro almacena la identidad del nodo.
- Almacenamiento en caché: Redis Cluster (o Elasticache/MemoryDB) para contadores, preferencias, registro, deduplicación, límites de velocidad.
- Almacenes de datos: Cassandra/ScyllaDB para historial; PostgreSQL (Aurora) para preferencias/dispositivos; S3 + data warehouse para analítica.
- Proveedores de push: APNs, FCM, Web Push (VAPID); correo electrónico a través de SES con SendGrid como proveedor secundario detrás de una capa de abstracción de proveedor para failover.
- Infraestructura: Kubernetes con HPA/KEDA escalando en el lag del consumidor de Kafka (no solo CPU), mesh de servicios Envoy/Istio para mTLS y reintentos, Terraform para IaC.
- Observabilidad: rastreo OpenTelemetry (id de rastreo propagado desde el evento productor hasta la confirmación del cliente), métricas Prometheus + Grafana, logs estructurados en Loki/ELK, alertas PagerDuty sobre SLOs.
- Bibliotecas de resiliencia: disyuntores y bulkheads por proveedor externo, limitadores de velocidad de cubo de tokens, retroceso exponencial con jitter.
- ESTRATEGIAS DE ESCALABILIDAD, LATENCIA Y DISPONIBILIDAD
Escalabilidad
- Todos los componentes sin estado (API, fan-out, enrutador, trabajadores) escalan horizontalmente; el número de particiones de Kafka es el límite de paralelismo, por lo que se deben aprovisionar particiones para 5–10 veces el pico actual desde el primer día (reparticionar es operacionalmente doloroso).
- Autoscale en lag del consumidor con KEDA para que un pico de 5x active el escalado en segundos; mantenga un búfer cálido de 30–40% de margen porque el escalado no es instantáneo.
- Fragmentar por user_id consistentemente en Cassandra, Postgres y Redis para que los datos de un solo usuario estén co-ubicados y la mitigación de particiones calientes sea uniforme.
- Carriles de prioridad: las notificaciones interactivas (DM, comentario en tu publicación) usan un tópico de alta prioridad con grupos de consumidores dedicados; el fan-out masivo/marketing/celebridad usa un carril de baja prioridad limitado. Esto garantiza el SLO de 2 segundos para las notificaciones que los usuarios realmente notan.
- Manejo de celebridades/claves calientes a través del fan-out híbrido push/pull descrito anteriormente, más claves de partición con sal para objetivos extremadamente calientes.
Baja latencia (p99 inferior a 2 s)
- La ruta crítica es intencionalmente corta: adición de API -> Kafka -> fan-out -> acierto de caché de preferencias -> búsqueda de registro -> escritura WebSocket. Todas las búsquedas son en Redis (menos de 5 ms); ninguna escritura de base de datos síncrona bloquea la entrega.
- La persistencia del historial y la analítica son asíncronas, fuera de la ruta de entrega.
- Productores de Kafka ajustados con linger.ms=5 y compresión (lz4) para equilibrar la lotificación con la latencia; los consumidores usan confirmación manual después del procesamiento.
- Despliegue multiregión con usuarios anclados a la región más cercana para reducir el RTT; las conexiones WebSocket terminan en los bordes regionales.
- Las ventanas de agregación son configurables por tipo y se deshabilitan para tipos críticos de latencia como los DM.
- Sondas sintéticas continuas miden la latencia real de extremo a extremo por región y por canal.
Alta disponibilidad (99,9 % +)
- Sin puntos únicos de fallo: multi-AZ para cada nivel, Kafka RF=3 con min.insync.replicas=2, Cassandra RF=3 con escrituras LOCAL_QUORUM, Postgres con standby síncrono y failover automatizado.
- Multiregión activa-activa para los niveles en tiempo real y de entrega; Cassandra replica entre regiones de forma asíncrona, Postgres usa réplicas de lectura regionales con una región de escritura designada.
- Degradación elegante: si la ruta WebSocket no está saludable, recurre al push móvil; si la caché de preferencias está caída, recurre a Postgres y luego a valores predeterminados conservadores; si las escrituras de Cassandra fallan, continúa entregando en tiempo real y reproduce las escrituras de historial desde Kafka después.
- Reintentos con retroceso exponencial más jitter, intentos limitados, luego DLQ con alertas y una herramienta de reproducción.
- Disyuntores por proveedor externo para que una interrupción de APNs no agote los hilos de trabajo y detenga el correo electrónico.
- Entrega al menos una vez más deduplicación de notification_id en el servidor y el cliente; los clientes también se deduplican al reconectarse al reproducir el historial pendiente.
- Prácticas de confiabilidad: ejercicios de caos/juegos (matar un nodo de puerta de enlace y verificar el fallback de push), pruebas de carga al 5x del pico, despliegues blue-green y canary, flags de funciones para interruptores por canal, descarte de contrapresión de tráfico de baja prioridad antes que de alta prioridad.
- CUELLOS DE BOTELLA Y COMPENSACIONES
Posibles cuellos de botella
- Proveedores de terceros (APNs/FCM/correo electrónico): el techo más difícil, ya que el rendimiento no depende de nosotros. Mitigar con agrupación de conexiones sobre HTTP/2, lotificación, limitadores de velocidad por proveedor, failover multi-proveedor para correo electrónico y suavizado basado en colas de picos.
- Fan-out de celebridades: una sola publicación puede generar decenas de millones de entregas. Mitigado por push/pull híbrido, carriles masivos limitados y agregación.
- Nivel de conexión WebSocket: memoria y descriptores de archivo por nodo, más reconexiones de "rebaño thundering" después de un despliegue o un problema de red. Mitigar con límites de kernel ajustados, reconexión escalonada con jitter y retroceso exponencial forzado en el lado del cliente, y vaciado lento de conexiones durante los despliegues.
- Claves calientes de Redis: la clave de agregación de una publicación viral o un contador compartido. Mitigar con salting de claves, cachés locales en memoria con TTL cortos y fragmentación en el lado del cliente.
- Amplificación de escritura de Cassandra y presión de compactación a 100K escrituras/segundo. Mitigar con compactación de ventana de tiempo (TWCS) adecuada para datos TTL de series temporales, y al no almacenar tipos de notificación de bajo valor en el historial en absoluto.
- Desviación de particiones de Kafka si se particiona por una clave de baja cardinalidad; siempre particionar por recipient_user_id en el tópico de entrega.
Compensaciones explícitas
- Al menos una vez sobre exactamente una vez: exactamente una vez a través de proveedores externos heterogéneos es impráctico y costoso. Aceptamos duplicados raros y los resolvemos con claves de idempotencia y deduplicación en el lado del cliente — más barato y mucho más disponible.
- Consistencia eventual para contadores e historial sobre consistencia fuerte: una insignia de no leído que está momentáneamente desfasada es aceptable; la latencia de varios segundos para garantizarla no lo es. Los trabajos de reconciliación limitan la deriva.
- Persistencia políglota sobre una sola base de datos: esto aumenta la superficie operativa (tres almacenes de datos más Redis) pero cada carga de trabajo obtiene el motor correcto. Un solo clúster de Postgres se convertiría en el cuello de botella con 1000 millones de escrituras/día; un solo clúster de Cassandra haría que las auditorías de preferencias y consentimiento fueran incómodas.
- Fan-out basado en push para la mayoría de los usuarios, basado en pull para celebridades: complejidad de código añadida, pero es la única forma de evitar tormentas de escritura ilimitadas.
- La agregación mejora la experiencia del usuario y reduce drásticamente el volumen de entrega, pero agrega hasta una ventana de latencia para los tipos agregables. Mantenemos las ventanas cortas y eximimos los DM.
- Multiregión activa-activa aumenta el costo e introduce sutilezas de consistencia entre regiones, justificado por los objetivos de disponibilidad y latencia. Si el presupuesto fuera limitado, una postura de región única con standby cálido aún cumpliría el 99,9% pero con un RTO más largo.
- Kafka sobre una cola gestionada más simple (SQS): más carga operativa, pero necesitamos reproducción, particiones ordenadas por clave, grupos de consumidores independientes múltiples y retención de 7 días para recuperación de incidentes.
- Almacenar solo las últimas ~100 notificaciones con un TTL de 90 días intercambia la completitud del archivo por costo y rendimiento de lectura; los datos a largo plazo viven en el data lake de analítica si alguna vez se necesitan.
- PLAN DE DESPLIEGUE (POR FASES)
Fase 1: API de Ingesta + Kafka + escritor de historial + API de lectura (solo notificaciones en la aplicación). Establece la columna vertebral duradera.
Fase 2: Puerta de enlace en tiempo real, registro de conexiones, contadores de no leídos, entrega WebSocket con fallback de push.
Fase 3: Trabajadores de push móvil y push web, registro de dispositivos, servicio de preferencias y horas de silencio.
Fase 4: Instantáneo de correo electrónico + resúmenes, servicio de plantillas, manejo de supresión.
Fase 5: Agregación/coalescencia, fan-out híbrido de celebridades, limitación de frecuencia.
Fase 6: Multiregión activa-activa, pruebas de caos, validación de carga 5x, dashboards de SLO y presupuestos de error.
- MÉTRICAS CLAVE Y SLOs
- Latencia p50/p95/p99 de extremo a extremo por canal (SLO: p99 inferior a 2 s para WebSocket).
- Tasa de éxito de entrega por canal; tasas de error del proveedor y tasa de invalidación de tokens.
- Lag del consumidor de Kafka por tópico (señal principal de escalado automático y paginación).
- Conteo de conexiones WebSocket, tasa de rotación y tasa de confirmación.
- Deriva del contador de no leídos detectada por reconciliación.
- Profundidad y antigüedad de la DLQ.
- Disponibilidad por API medida desde la perspectiva del cliente, rastreada contra un presupuesto de error mensual.
Resultado
Votos ganadores
3 / 3
Puntuación media
Puntuación total
Comentario general
La respuesta A es un diseño sobresaliente y muy concreto con estimaciones de capacidad cuantificadas, rutas de ingesta y entrega claramente separadas, modelos de datos detallados, carriles de prioridad, fan-out híbrido, resiliencia específica del canal y medidas accionables de disponibilidad y latencia. Sus características más sólidas son la configuración operativa explícita, la planificación de capacidad de WebSocket, las rutas de degradación por fallos y un análisis inusualmente exhaustivo de cuellos de botella y compensaciones. La principal debilidad es que no utiliza explícitamente un patrón de publicación de eventos transaccional o de outbox en los servicios de origen, dejando una brecha potencial entre la transacción comercial originadora y la ingesta duradera en Kafka. Algunos detalles de consistencia multirregional también se tratan a un nivel alto.
Ver detalle de evaluación ▼
Calidad de la arquitectura
Peso 30%El pipeline duradero basado en eventos, los temas de fan-out y canal separados, el enrutamiento de políticas, el registro de conexiones, la pasarela en tiempo real, el escritor asíncrono de historial y los carriles de prioridad forman una arquitectura lógica con responsabilidades claras. La brecha principal es la falta de un outbox explícito en el servicio de origen, por lo que una transacción comercial podría teóricamente confirmarse sin que su evento de notificación llegue a la API de ingesta. La relación entre un registro de historial lógico y múltiples entregas a canales también podría especificarse con mayor precisión.
Integridad
Peso 20%Aborda todas las áreas solicitadas y va más allá de ellas con estimaciones de capacidad, dimensionamiento de conexiones, esquemas detallados, comportamiento del canal, controles de cumplimiento, observabilidad, fases de implementación y SLOs medibles. Las omisiones menores incluyen la publicación transaccional de origen y una explicación más exacta de cómo el almacén aplica una política estricta de los últimos 100 en lugar de simplemente limitar las lecturas y aplicar TTL.
Análisis de compromisos
Peso 20%La respuesta examina explícita y correctamente la entrega al menos una vez frente a exactamente una vez, la consistencia eventual frente a la fuerte, la persistencia políglota, el fan-out push frente a pull, la latencia de agregación, el costo multirregional, Kafka frente a colas más simples y los límites de retención. Las compensaciones están vinculadas a los requisitos y acompañadas de estrategias de mitigación en lugar de enumerarse de forma abstracta.
Escalabilidad y fiabilidad
Peso 20%El diseño cuantifica el tráfico promedio y pico, estima la capacidad concurrente de WebSocket, escala los consumidores por el lag de Kafka, reserva margen de calentamiento, aísla el tráfico prioritario, maneja el fan-out de celebridades y especifica replicación multizona, configuraciones de quorum, reintentos, DLQs, disyuntores, rutas de respaldo, pruebas de carga y ejercicios de caos. El comportamiento de datos activo-activo regional y la atomicidad de eventos de origen requieren más detalles.
Claridad
Peso 10%A pesar de su extensión, la organización numerada, el flujo explícito, los componentes nombrados, los esquemas y las secciones separadas para escalado, disponibilidad, cuellos de botella, implementación y métricas hacen que el plan sea fácil de navegar. Algunas afirmaciones son demasiado confiadas o comprimidas, como llamar trivial al sharding de 100 millones de filas, y algunas semánticas de canal/historial podrían formularse con más cuidado.
Puntuación total
Comentario general
Una respuesta sobresaliente que ejemplifica un diseño de sistemas de nivel senior. Es integral, está bien estructurada, se basa en datos cuantitativos y demuestra una profunda comprensión de las compensaciones y las realidades operativas. El diseño es muy detallado, con elecciones tecnológicas específicas y estrategias concretas para la escalabilidad y la fiabilidad. La inclusión de un plan de implementación por fases y una sección dedicada a métricas/SLOs lo eleva más allá de un diseño puramente teórico, haciéndolo parecer un documento listo para producción.
Ver detalle de evaluación ▼
Calidad de la arquitectura
Peso 30%La arquitectura es excepcionalmente sólida, detallada y está bien articulada. El flujo impulsado por eventos es claro y la separación de responsabilidades entre componentes como la API, el servicio Fan-out y los trabajadores específicos del canal es excelente. La inclusión de una estrategia híbrida de fan-out push/pull para cuentas de celebridades demuestra una comprensión sofisticada del espacio del problema.
Integridad
Peso 20%Esta respuesta es excepcionalmente completa. Aborda cada parte de la pregunta con gran detalle y va más allá al incluir una estimación detallada de la capacidad, un plan de implementación por fases y una sección dedicada a métricas clave y SLOs. Este nivel de detalle es lo que se esperaría del documento de diseño de un ingeniero senior.
Análisis de compromisos
Peso 20%La discusión de los cuellos de botella y las compensaciones es excelente. No solo identifica problemas potenciales, sino que también enumera explícitamente las concesiones de diseño realizadas, como elegir la entrega 'al menos una vez' sobre 'exactamente una vez' y usar persistencia políglota. El razonamiento es agudo, conciso y demuestra una perspectiva de ingeniería madura.
Escalabilidad y fiabilidad
Peso 20%Las estrategias de escalabilidad y fiabilidad son detalladas y concretas. Menciona enfoques específicos como el escalado automático basado en el retraso de los consumidores de Kafka con KEDA, el uso de carriles de prioridad para diferentes tipos de tráfico y la implementación de una escalera de degradación elegante. La inclusión de prácticas como la ingeniería del caos muestra un enfoque proactivo hacia la fiabilidad.
Claridad
Peso 10%La respuesta es excepcionalmente clara y está bien estructurada. El uso de secciones numeradas, un diagrama de flujo basado en texto al principio y puntos concisos hace que la gran cantidad de información técnica sea muy fácil de seguir y digerir. El flujo lógico desde los requisitos hasta las métricas es impecable.
Puntuación total
Comentario general
La respuesta A es un documento de diseño de nivel de personal casi completo. Comienza con cálculos concretos de capacidad (eventos/segundo, dimensionamiento de almacenamiento, recuentos de conexiones WebSocket y estimaciones de nodos), luego recorre una división clara entre ingesta y entrega con detalles de configuración específicos (recuentos de particiones de Kafka, configuraciones de replicación, confirmaciones, retención), un fan-out híbrido push/pull para cuentas de celebridades, carriles de prioridad para proteger el SLO de 2 segundos, modelos de datos por tienda con justificaciones explícitas, una escalera de degradación elegante, prácticas de caos/juegos de guerra, un plan de implementación por fases y métricas de SLO. La sección de compensaciones es excepcional: cada elección (al menos una vez frente a exactamente una vez, persistencia políglota, Kafka frente a SQS, costo de latencia de agregación, costo multirregional) se presenta con la alternativa y por qué fue rechazada. Debilidades menores: la densidad puede hacer que la lectura sea pesada y no discute el patrón outbox para la durabilidad de eventos en el lado del productor.
Ver detalle de evaluación ▼
Calidad de la arquitectura
Peso 30%Arquitectura sobresaliente: división clara de ingesta/entrega, fan-out híbrido push/pull con un umbral concreto de seguidores, carriles de prioridad que garantizan el SLO de 2 segundos para eventos interactivos, nivel de conexión dimensionado (20-25M sockets, ~100K por nodo) y topología específica de Kafka (256 particiones, RF=3, min.insync.replicas=2, retención de 7 días). Las responsabilidades de los componentes son precisas y la ruta crítica se mantiene deliberadamente libre de escrituras síncronas en la base de datos.
Integridad
Peso 20%Cubre todos los requisitos del prompt más extras: estimación de capacidad con cálculos de almacenamiento, modelos de datos completos para seis tiendas con justificaciones, los cuatro canales, resúmenes, cumplimiento (GDPR/CAN-SPAM, listas de supresión), observabilidad con SLOs, un plan de implementación por fases y una sección dedicada a cuellos de botella/compensaciones. Nada del prompt falta.
Análisis de compromisos
Peso 20%Sección de compensaciones excepcional: cada decisión nombra la alternativa y por qué fue rechazada (al menos una vez vs exactamente una vez, persistencia políglota vs base de datos única, Kafka vs SQS, fan-out push vs pull, costo activo-activo vs standby en caliente, latencia de agregación vs volumen). Las compensaciones se integran en las justificaciones a lo largo del documento, no se limitan a una sola sección.
Escalabilidad y fiabilidad
Peso 20%Concreto y cuantificado: justificación de la sobreaprovisionamiento de particiones, KEDA autoscaling por lag del consumidor con un 30-40% de margen en caliente, claves 'hot keys' saladas, compactación TWCS para la tasa de escritura, configuraciones explícitas de replicación y quorum de Cassandra/Postgres/Kafka, escalera de degradación elegante, disyuntores por proveedor, pruebas de caos y validación de carga 5x, y herramientas de repetición de DLQ. Vincula directamente los mecanismos a los objetivos de 100M DAU / 5x pico / 99.9%.
Claridad
Peso 10%Excelente estructura numerada desde los requisitos hasta la implementación y las métricas; el diagrama de flujo en forma de texto facilita el seguimiento del pipeline. La densidad de detalles ocasionalmente hace que las secciones sean pesadas, pero los encabezados y el formato consistente las mantienen navegables.