En una entrevista de diseño de sistemas o en un documento de diseño, el diagrama es donde el razonamiento se hace visible. Dibujar una caja con la etiqueta "caché" es fácil; lo que hace que el diagrama merezca la lectura es mostrar por qué está ahí, cuánto tráfico absorbe y qué pasa cuando la caché está fría.
Esta guía recorre un ejercicio clásico, un acortador de URL, desde los requisitos hasta un diagrama de diseño de sistemas terminado. Lo importante no es el acortador en sí, sino el método: primero los requisitos y los números, luego la API y los datos, después las cajas, con cada decisión escrita donde todos puedan verla.
Paso 1: requisitos
Funcionales:
- Crear un enlace corto para una URL larga, opcionalmente con un alias personalizado y una fecha de expiración.
- Redirigir un enlace corto a su URL larga.
- Contar los clics por enlace.
No funcionales:
- Las redirecciones deben ser rápidas y de alta disponibilidad; la creación de enlaces puede tolerar más latencia.
- El sistema es de lectura intensiva: los enlaces se crean una vez y reciben muchos clics.
- Los códigos cortos no deben ser fáciles de enumerar.
Paso 2: cálculos aproximados
Supón 100 millones de enlaces nuevos al mes y 100 redirecciones por enlace creado:
| Magnitud | Estimación |
|---|---|
| Escrituras | 100M / 2,6M segundos al mes ≈ 40 por segundo en promedio |
| Lecturas | 100 × 40 ≈ 4.000 redirecciones por segundo; dimensiona para picos de 10×, 40.000 por segundo |
| Enlaces a 5 años | 100M × 12 × 5 = 6 mil millones |
| Almacenamiento | 6 mil millones × ~500 bytes ≈ 3 TB, sin contar réplicas |
| Longitud del código | 7 caracteres en base62 dan 62⁷ ≈ 3,5 billones de códigos |
Los números ya dan forma al diseño: dominan las lecturas, así que la ruta de lectura lleva una caché; 3 TB no van a caber para siempre en una sola base de datos pequeña, así que el modelo de datos debe admitir un sharding limpio; y 7 caracteres dejan margen de sobra.
Paso 3: API
POST /api/links
{ "url": "https://example.com/a/very/long/path", "alias": "launch", "expiresAt": "2027-01-01" }
→ 201 { "code": "launch", "shortUrl": "https://s.example/launch" }
GET /{code}
→ 302 Location: https://example.com/a/very/long/path
Hay una decisión que merece una línea en el diagrama: ¿301 o 302? Un 301 es permanente, así que los navegadores lo guardan en caché y las visitas repetidas nunca llegan a ti. Eso ahorra tráfico, pero pierdes el conteo de clics. Un 302 hace pasar cada clic por el servicio de redirección, que es justo lo que necesita la analítica. Este diseño usa 302.
Paso 4: modelo de datos e IDs
La tabla principal es sencilla: code (clave primaria), long_url, owner_id, created_at, expires_at. Cada lectura es una búsqueda por code, así que sirve tanto un almacén clave-valor como una base de datos relacional con clave primaria, y hacer sharding por un hash de code reparte la carga de forma uniforme.
Generar los códigos es la parte interesante:
| Enfoque | Ventajas | Desventajas |
|---|---|---|
| Contador + base62 | Sin colisiones | Los códigos secuenciales son fáciles de enumerar; requiere coordinación |
| 7 caracteres aleatorios | Difíciles de adivinar, sin coordinación | Hay que comprobar colisiones al insertar |
| Hash de la URL | La misma URL obtiene el mismo código | Colisiones al truncar; los alias requieren un tratamiento especial |
Aquí, la API de escritura pide rangos de IDs a un asignador de rangos de IDs, por ejemplo un millón cada vez, y desordena cada ID con una permutación reversible antes de codificarlo en base62, de modo que los códigos son únicos sin comprobar colisiones y no parecen secuenciales vistos desde fuera.
Paso 5: el diagrama
Separa las rutas que tienen requisitos distintos. La ruta de escritura tiene poco volumen y debe ser correcta; la de lectura tiene mucho volumen y debe ser rápida; la analítica puede ir con retraso.
Contenido del diagrama
- Users
- Load balancer
- ID range allocator
- Write API
- Redirect service
- Cache: code → URL
- Links DB (sharded by code)
- click events
- Analytics workers
- Analytics store
- HTTPS
- POST · 40/s
- GET · 4k/s, peak 40k/s
- lease ID range
- INSERT link
- GET code
- on cache miss
- click event
- consume
- counts
Cómo leerlo:
- Ruta de escritura (arriba). El balanceador de carga envía
POST /api/linksa la API de escritura, que toma un ID de su rango reservado, lo codifica y escribe el enlace en la base de datos. - Ruta de lectura (centro).
GET /{code}llega al servicio de redirección, que consulta primero Redis. Si los datos más consultados caben en memoria, la mayoría de las redirecciones nunca tocan la base de datos. Ante un fallo de caché, el servicio lee la base de datos y llena la caché. - Analítica (abajo). Cada redirección emite un evento de clic a Kafka, y los workers de analítica agregan los conteos en el almacén de analítica. La redirección nunca espera a la analítica.
Dibújalo para que se vea el razonamiento
- Pon números en las conexiones.
40/sen la conexión de escritura y4k/s, peak 40k/sen la de lectura explican la caché mejor que cualquier etiqueta. - Escribe los supuestos junto a las cajas. "Objetivo de tasa de aciertos de caché: 90 %", "302 para la analítica", "IDs reservados en rangos de 1M".
- Separa lo síncrono de lo asíncrono. Conexiones continuas para la ruta de la petición y discontinuas para los eventos de clic.
- Muestra qué pasa cuando algo falla. Si Redis cae, las redirecciones recurren a la base de datos con más latencia; escríbelo en el diagrama.
- Mantén las estimaciones en el lienzo. Una pequeña tabla de números junto al diagrama lo convierte en un documento de diseño.
Temas a fondo que conviene preparar
- Caché. Los enlaces más visitados siguen una distribución de cola larga, así que una caché LRU con un TTL moderado cubre la mayor parte del tráfico. Invalida al borrar y al expirar.
- Escalado de la base de datos. Aquí las réplicas de lectura ayudan menos que la caché; el sharding por código hace que las escrituras y el almacenamiento crezcan de forma pareja.
- Expiración. Comprueba
expires_aten la lectura y limpia en segundo plano, en lugar de lanzar un enorme job de borrado. - Abuso. Limita la tasa de creación de enlaces por usuario y comprueba las URL de destino contra listas de malware.
Constrúyelo en Archboard
- Inicia sesión con Google o GitHub y crea un diagrama.
- Añade un nodo Internet del pack Red para los usuarios y un Balanceador de carga en la nube del pack Nube para el balanceo de carga.
- Añade la API de escritura, el servicio de redirección, el asignador de IDs y los workers de analítica como nodos Contenedor del pack Modelo C4, con el lenguaje en el campo Tecnología.
- Añade del pack Datos un Redis para la caché, Postgres para la base de datos de enlaces, un Tema para los eventos de clic y un Almacén de datos para la analítica.
- Etiqueta las conexiones con operaciones y tasas, dibuja con línea discontinua los eventos de clic y pon las estimaciones en un bloque Markdown del pack Básico.
El ejemplo usa 11 nodos de diagrama, incluido el bloque Markdown con las estimaciones, dentro del plan Free. Para el método general detrás de cualquier diagrama de arquitectura, consulta cómo dibujar un diagrama de arquitectura de software.
Preguntas frecuentes
¿Qué nivel de detalle debe tener un diagrama de diseño de sistemas en una entrevista? El suficiente para mostrar las rutas de lectura y escritura, el almacén de datos, la caché y una pieza asíncrona. Profundiza solo donde te lo pida quien te entrevista.
¿SQL o NoSQL para la tabla de enlaces? Cualquiera sirve para una búsqueda por clave primaria. Elige según cómo pienses hacer sharding y lo que tu equipo opera bien, y escribe el motivo en el diagrama.
¿Debo dibujar una CDN? Solo si guardas las redirecciones en caché en el edge. Con 302 y conteo de clics, la caché en el edge tiene un alcance limitado, así que muchos diseños la dejan fuera.
¿Por qué no usar 301 en todas partes? Un 301 ahorra tráfico, pero los navegadores dejan de preguntarte, así que pierdes los datos de clics y no puedes cambiar el destino para los visitantes que vuelven.
¿Dónde van los números? En el lienzo, junto al diagrama, para que cualquiera que revise el diseño pueda comprobar los supuestos detrás de las cajas.