HardПрактика7 min

Полные worked examples

Три полных расчёта: URL shortener, Twitter-like feed, Instagram photos. QPS, storage, bandwidth, cache, выбор БД

Здесь применим всё из предыдущих глав к трём классическим system design задачам. Каждый расчёт -- от требований до выбора технологий, как на senior-интервью.

Example 1: URL Shortener (bit.ly)

Требования

  • 100 M новых URL per month (create)
  • Read:Write = 10:1 (каждую короткую ссылку открывают 10 раз)
  • Retention: 5 лет (после -- archive/delete)
  • Availability: 99.9%
  • Redirect latency: < 100 ms global

Шаг 1: QPS

Writes:
  100M / month = 100M / (30 × 86400) ≈ 38 writes/sec avg
  peak (x3) = 115 writes/sec

Reads (10x writes):
  380 reads/sec avg
  peak = 1 150 reads/sec

Итого: 1.2k peak RPS. Это небольшая нагрузка -- один хороший instance держит.

Шаг 2: Storage

Объект URL:

  • short_code: 7 chars (base62, поддерживает 62^7 ≈ 3.5×10^12 уникальных)
  • long_url: ~100 bytes avg
  • created_at: 8 bytes
  • user_id: 16 bytes (UUID)
  • metadata (clicks, geo, etc): 50 bytes
  • Total per record: ~200 bytes
5 лет × 12 месяцев × 100M = 6 B URLs

Raw storage = 6 × 10^9 × 200 = 1.2 TB
+ indexes (30%) = 1.56 TB
× replication (3) = 4.7 TB
+ backups (50%) = 7 TB total

Шаг 3: Bandwidth

Redirect = 302 с Location header. Response ~300 bytes (headers + empty body).

Peak egress = 1 150 × 300 B = 345 KB/sec = 2.7 Mbps

Ничего. Обычный load balancer пропускает.

Click analytics ingestion (если трекать):

1 150 clicks/sec × 500 bytes (event) = 575 KB/sec ingress в analytics pipeline

Шаг 4: Cache sizing

Популярные ссылки читаются часто (viral), длинный хвост -- редко. Классический Zipf.

Total URLs: 6B
Hot (1% популярных дают 90% трафика): 60M URLs
Cache entry: 120 bytes (short_code + long_url + small metadata)

Working set: 60M × 120 = 7 GB

Влезает в один r5.xlarge (32 GB RAM). С запасом -- r5.2xlarge (64 GB) или Redis cluster 2-3 ноды.

Шаг 5: Выбор БД

Варианты:

  • PostgreSQL: 7 TB на одной ноде тяжело, придётся шардить. Плюс: транзакции, SQL.
  • MySQL со sharding: опыт YouTube. Minus: ручной шардинг.
  • Cassandra/DynamoDB: key-value, отлично подходит (short_code → long_url). Минус: нет транзакций.
  • Redis как source of truth: плохо -- persistence дорог, 7 TB RAM = $$$.

Рекомендация: Cassandra/DynamoDB как primary, Redis как hot cache.

Архитектура

                    ┌────────────┐
 User ──HTTP GET──▶ │    CDN     │  Кэш 302 ответов (TTL 1 час)
                    └─────┬──────┘
                          │ miss
                          ▼
                    ┌────────────┐
                    │    ALB     │
                    └─────┬──────┘
                          │
                ┌─────────┴─────────┐
                │                   │
                ▼                   ▼
          ┌──────────┐         ┌──────────┐
          │ API node │  ...    │ API node │  Go/Gin, 3-5 instances m5.large
          └─────┬────┘         └─────┬────┘
                │                    │
                └──────┬─────────────┘
                       │
                ┌──────▼──────┐
                │    Redis    │  Cache: hot URLs, rate limit
                │  (cluster)  │  Hit rate > 95%
                └──────┬──────┘
                       │ miss
                ┌──────▼──────┐
                │  DynamoDB   │  6B records, key-value
                │ / Cassandra │  RF=3, eventual consistency OK
                └─────────────┘

 Analytics:  Click events → Kinesis/Kafka → Redshift/BigQuery

Шаг 6: Servers

  • API: 5 × m5.large (2 vCPU, 8 GB) -- каждая держит 1k RPS на Go = 5k capacity на 1.2k peak load (x4 запас)
  • Redis: 3 × r5.xlarge cluster
  • DynamoDB: autoscale, начать с 1 500 RCU / 200 WCU

Шаг 7: Cost (AWS примерно)

Компонент Monthly cost
5 × m5.large $365
3 × r5.xlarge (Redis) $550
DynamoDB (6B items, autoscale) $3 000
S3 backup $150
CDN (CloudFront) $400
Total ~$4 500

Example 2: Twitter-like feed

Требования

  • 200 M DAU
  • 5 tweets per active user per day
  • 50 feed refreshes per user per day
  • avg followers: 200 (Pareto: 20% users have 80% followers, max 100M followers)
  • Home timeline latency: p99 < 500 ms
  • Retention: forever (public)

Шаг 1: QPS

Tweets (writes):
  200M × 5 = 1B tweets/day
  avg = 1B / 86400 ≈ 12 000 tweets/sec
  peak (x3) = 35 000 tweets/sec

Feed reads:
  200M × 50 = 10B reads/day
  avg = 115 000 reads/sec
  peak = 350 000 reads/sec

350k peak reads/sec, 35k writes/sec. Это серьёзная инфра.

Шаг 2: Fan-out математика

Есть две стратегии:

  • Push (fan-out on write): при твите -- записать в timeline каждого followers. Быстро читать.
  • Pull (fan-out on read): при чтении -- собрать с timelines всех followed. Быстро писать.

Hybrid (используется Twitter):

  • Обычные users (≤ 10k followers): push
  • Celebrities (> 10k followers): pull на чтении feed'а
  • Граница настраивается

Fan-out стоимость:

12 000 tweets/sec × 200 avg followers = 2.4M timeline writes/sec (push)
35 000 peak × 200 = 7M writes/sec peak

7M writes/sec -- это Redis cluster на 50-100 нод, иначе никак. Celebrities exclusion снижает на 30-50%.

Шаг 3: Storage

Tweets:

Avg tweet: text 280 B + metadata 300 B + media refs = 600 B
Daily raw: 1B × 600 B = 600 GB/day
Annually: 220 TB/year
Compressed (3x for structured): 70 TB/year
× RF=3: 210 TB/year storage

Timelines (если push):

200M users × 1000 tweets cached = 200B timeline entries
Entry size: ~100 B (tweet_id + author_id + score)
Storage: 200B × 100 B = 20 TB (in Redis!)

20 TB RAM -- это ~60 × r5.12xlarge (384 GB each). Дорого, но реально для Twitter-scale.

Media (25% tweets):

Images 25% × 500K × 1B tweets = 125B images over all time
Daily: 250M × 300 KB = 75 TB/day (невероятно, поэтому Twitter жмёт и шрафически сжимает)

Шаг 4: Cache sizing

Home timeline cache:

  • 200M users, 20% active daily = 40M hot timelines
  • 500 tweets per timeline × 100 B = 50 KB per timeline
  • Hot cache: 40M × 50 KB = 2 TB

Это 10 × r5.12xlarge (384 GB) или 20 × r5.6xlarge (192 GB).

Шаг 5: Bandwidth

Feed read response: 20 tweets initial, ~50 KB JSON.

Peak egress = 350k RPS × 50 KB = 17.5 GB/sec = 140 Gbps

Это требует CDN + много API-нод с 10-25 Gbps uplinks. CDN кэширует public profile data, но home feed -- персонализирован, так что offload низкий (20-40%).

Шаг 6: Выбор БД

Компонент Технология Обоснование
Tweets (authoritative) Cassandra / Manhattan Append-heavy, TS-sorted, шардинг по user_id
Timelines (hot) Redis Cluster Sorted sets, микросекундный доступ
User graph (followers) Graph DB / sharded MySQL Связи, обход
Media S3 + CloudFront Object storage + CDN
Search Elasticsearch Full-text, в реальном времени
Trending/analytics Flink + ClickHouse Streaming aggregation

Архитектура

              ┌──────────┐
User ──WSS──▶ │ CDN/Edge │  ← Static, public data
              └────┬─────┘
                   ▼
              ┌──────────┐
              │   ALB    │
              └────┬─────┘
                   │
              ┌────▼───────────────────┐
              │   API Gateway (Kong)   │  Auth, rate limit, routing
              └──┬──────────┬──────────┘
                 │          │
         ┌───────▼─┐   ┌────▼────────┐
         │ Tweet   │   │ Timeline    │  Go microservices
         │ service │   │ service     │
         └───┬─────┘   └─────┬───────┘
             │               │
             │        ┌──────┴─────────┐
             │        │                │
             ▼        ▼                ▼
         ┌──────┐ ┌─────────┐   ┌──────────┐
         │Kafka │ │  Redis  │   │Cassandra │
         └──┬───┘ │ Cluster │   │ (tweets, │
            │     └─────────┘   │  graph)  │
            ▼                    └──────────┘
         ┌──────────┐
         │ Fan-out  │  Celery/workers
         │ workers  │  Push timelines on write
         └──────────┘

Шаг 7: Servers (rough)

Компонент Ноды
API servers 500 × m5.2xlarge
Redis timeline cache 60 × r5.12xlarge
Cassandra (tweets + graph) 200 × i3.4xlarge
Kafka (events) 50 × m5.2xlarge
Elasticsearch (search) 100 × r5.2xlarge
Fan-out workers 200 × c5.2xlarge
Media (S3) managed
CDN CloudFront, multi-region

Примерный monthly infrastructure cost: $2-5M.


Example 3: Instagram photos

Требования

  • 500 M DAU
  • 2 photos upload per user per day (average; large variance)
  • 50 photos viewed per user per day (scrolling feed + explore)
  • Photo retention: forever
  • Thumbnail sizes: original + 4 derivatives (1080w, 640w, 320w, 150w)
  • Global access, p99 < 300 ms

Шаг 1: QPS

Uploads:
  500M × 2 = 1B photos/day
  avg = 11 500 photos/sec
  peak = 35 000 photos/sec

Views:
  500M × 50 = 25B views/day
  avg = 290 000 views/sec
  peak = 870 000 views/sec

870k peak views/sec -- но 99% идут через CDN. Origin видит ~1% = 9k RPS.

Шаг 2: Storage (photos)

Размеры:

Variant Avg size
Original (JPEG 90% quality, 4000x3000) 3 MB
1080w (feed) 250 KB
640w (retina) 120 KB
320w (thumb) 40 KB
150w (avatar) 15 KB
Total per photo ~3.4 MB
Daily raw upload:
  1B × 3 MB (original) = 3 PB/day originals
  + 1B × 425 KB (derivatives) = 425 TB/day

Total daily: ~3.4 PB/day
Annually: 1.2 EB (!) raw

With S3 replication (built-in): storage billed 1x
S3 Standard cost: 1 EB × $23/TB = $23M/month just for year 1

Оптимизация: тiered storage

  • Hot (last 30 days): S3 Standard
  • Warm (30-180 days): S3 Standard-IA
  • Cold (180+ days): S3 Glacier Instant Retrieval

Costs drop ~70%.

Шаг 3: Metadata DB

Photo metadata record:

  • photo_id (UUID 16B)
  • user_id (16B)
  • timestamp (8B)
  • location (16B optional)
  • caption (avg 100B)
  • tags, mentions (100B avg)
  • variant URLs (5 × 50B = 250B)
  • Total: ~500 B
Metadata daily: 1B × 500 B = 500 GB/day
Annually: 180 TB/year
With RF=3: 540 TB/year

Это для Cassandra или DynamoDB по user_id.

Шаг 4: Bandwidth (самое важное)

Peak views: 870 000 views/sec
Avg size served: 250 KB (1080w variant, dominant)
Peak egress: 870k × 250 KB = 217 GB/sec = 1.7 Tbps

1.7 Tbps -- CDN is mandatory.

CDN hit ratio: 95% (media is highly cacheable)
Origin egress: 5% × 217 GB/s = 11 GB/s = 90 Gbps
CDN egress cost: 1.7 Tbps × 30 days × 86400 s = 5.4 EB/month
  (unrealistic -- это значит триллионы долларов, CDN pricing снижается с объёмом)

Instagram использует свой edge PoP + партнёрство с CDN (Meta EdgeNetwork). За деньги извне -- $0.01-0.02/GB в bulk.

Шаг 5: Cache sizing

Feed view: 95% фото -- из последних 30 дней. Это 30B фото.

CDN edge cache (global):
  Hot 10% = 3B photos × avg 250 KB = 750 TB distributed across PoPs
  Per PoP (50 PoPs worldwide): 15 TB

Metadata cache (Redis):

  • 100M active users feeds × 100 recent photo meta × 500 B = 5 TB
  • Redis cluster: 20 × r5.12xlarge

Шаг 6: Upload pipeline

Upload flow:
  Client ──POST multipart──▶ Upload API
                                 │
                                 ▼
                          ┌──────────────┐
                          │ Validate     │  ClamAV virus scan,
                          │ + pre-sign   │  EXIF strip, hash dedup
                          └──────┬───────┘
                                 │
                                 ▼
                          ┌──────────────┐
                          │ S3 (origin)  │  Store original
                          └──────┬───────┘
                                 │ S3 event
                                 ▼
                          ┌──────────────┐
                          │ Resize worker│  Lambda/Fargate
                          │ (5 variants) │  writes back to S3
                          └──────┬───────┘
                                 │
                                 ▼
                          ┌──────────────┐
                          │ Write meta   │  Cassandra
                          │ Push to feed │  Kafka → fan-out
                          │ of followers │
                          └──────────────┘

Шаг 7: Архитектура

 User (mobile) ────▶ ┌────────────┐
                     │  CDN Edge  │ Meta EdgeNetwork + CloudFront
                     │  (global)  │ 95%+ hit ratio on media
                     └──┬─────┬───┘
                        │     │ miss
                media ◀─┘     │
                              ▼
                     ┌────────────────┐
                     │   API / Feed   │  Go services, 1000+ instances
                     │   Service      │
                     └───┬──────┬─────┘
                         │      │
                  ┌──────┘      └──────┐
                  ▼                    ▼
           ┌──────────────┐     ┌─────────────┐
           │  Redis (feed │     │  Cassandra  │  Photo metadata,
           │  cache)      │     │  (metadata) │  user timelines
           └──────────────┘     └─────────────┘

 Upload: → S3 (origin) → Lambda (resize) → S3 (derivatives) + meta DB
 Fan-out: Kafka → Feed generation workers → Redis

Шаг 8: Cost sketch

Компонент Monthly cost (rough)
S3 (exabytes with tiering) $15M
CDN egress (1.5 EB/month) $15M
Cassandra cluster (500 × i3.4xlarge) $1.5M
Redis (20 × r5.12xlarge) $200k
API servers (1000+ instances) $1M
Resize Lambda $500k
Total ~$35M/month

(Reality check: Meta spends billions/year on infra.)


Сравнительная таблица

Метрика URL Shortener Twitter feed Instagram
DAU ~10M 200M 500M
Peak RPS 1 200 350 000 870 000 (views)
Storage/year ~1 TB text 210 TB 1.2 EB
Cache size (hot) 7 GB 2 TB 750 TB (CDN)
CDN critical? Nice to have Partially Mandatory
Primary DB DynamoDB/Cassandra Cassandra Cassandra + S3
Monthly cost ~$5k ~$3M ~$35M

Общий pattern для любой worked example

  1. Read requirements -- вычлените DAU, actions, retention
  2. Compute QPS -- avg + peak, split read/write
  3. Compute storage -- raw × index × RF × backup + 5-year growth
  4. Compute bandwidth -- QPS × response size, CDN offload
  5. Compute cache -- working set (hot objects × size)
  6. Choose DB -- по нагрузке read/write и схеме доступа
  7. Draw architecture -- клиент → CDN → LB → API → cache → DB
  8. Estimate servers + cost -- по QPS и known instance capacity

Выводы

  • URL shortener -- small scale: 1k RPS, 1 TB, $5k/month. Один r5.xlarge + DynamoDB решают.
  • Twitter-like -- hybrid fan-out (push для обычных, pull для celebrities), 2 TB timeline cache
  • Instagram-like -- dominated CDN и S3: текстовая БД мала, media измеряется экзабайтами
  • Общий алгоритм: QPS → Storage → Bandwidth → Cache → DB → Architecture → Cost
  • Peak capacity под product-specific bursts: Twitter FIFA finals 10x от normal peak