Skip to content

Thiết kế YouTube — Video Pipeline và CDN ở quy mô tỷ người dùng

500 giờ video upload mỗi phút. 1 tỷ giờ xem mỗi ngày. 2 tỷ người dùng hàng tháng.

Một file raw 500MB từ smartphone của creator phải trải qua transcoding pipeline — chuyển thành 4+ độ phân giải khác nhau — rồi được đẩy ra mạng lưới CDN phủ khắp hành tinh, sẵn sàng stream đến mọi thiết bị chỉ trong vài giây sau khi publish.

🎓 Giáo sư Tom

YouTube là case study khó nhất trong system design interview. Nó kết hợp đồng thời bốn bài toán lớn: storage ở mức exabyte, compute cho transcoding GPU, networking cho CDN toàn cầu, và ML cho recommendation engine. Nếu bạn master được bài này, mọi case study khác đều đơn giản hơn.

Những con số định hình kiến trúc

MetricGiá trịÝ nghĩa kiến trúc
MAU2BGlobal-scale authentication & profile storage
DAU800MPeak concurrent connections hàng triệu
Video views/ngày4BCDN bandwidth ở mức Petabit
Upload/ngày500K video (~250TB raw)Massive ingest pipeline + storage
Transcoded storage/tháng~21 PBObject storage ở mức exabyte tích lũy
GPU workers sustained~700GPU cluster management
GPU workers peak~2,100Auto-scaling infrastructure
CDN bandwidth peak~160 TbpsMulti-tier CDN architecture

Đây không phải bài toán CRUD. Đây là bài toán industrial-scale media processing.


Bức tranh tư duy

Hãy hình dung YouTube như một nhà máy sản xuất phim quy mô công nghiệp. Mỗi video raw là thước phim gốc — phải đưa qua dây chuyền cắt ghép (transcoding), đóng gói thành nhiều định dạng từ 360p đến 4K, rồi phân phối qua mạng lưới rạp chiếu khắp thế giới (CDN). Khác biệt là: nhà máy này nhận 500 giờ phim gốc mỗi phút và phải chiếu cho 800 triệu khán giả mỗi ngày.

Mental Model: 5 giai đoạn của một video

Upload → Process → Store → Distribute → Watch
  │         │        │         │          │
  ▼         ▼        ▼         ▼          ▼
Chunked   DAG      Object   Multi-tier   ABR
Resume    Pipeline  Storage   CDN        Streaming

🔧 Khi nào analogy bị phá vỡ

Nhà máy phim truyền thống xử lý tuần tự — một phim một lúc. YouTube xử lý 500 giờ nội dung mới mỗi phút, song song trên hàng nghìn GPU worker. Đồng thời, mạng lưới phân phối phải serve 4 tỷ lượt xem mỗi ngày — không phải vài trăm rạp mà là hàng tỷ màn hình cùng lúc.


Cốt lõi kỹ thuật

1. Video Upload Pipeline

Upload video lên YouTube không phải đơn giản gửi một HTTP POST. Với file video trung bình 500MB, mạng có thể đứt bất kỳ lúc nào. Giải pháp: chunked resumable upload.

Thiết kế chi tiết:

Thành phầnCông nghệVai trò
Upload ServiceGo/gRPCQuản lý upload session, generate presigned URLs
Object StorageS3-compatibleLưu raw video, hỗ trợ multipart upload
Message QueueKafkaTrigger transcoding pipeline, đảm bảo at-least-once
Metadata DBPostgreSQLLưu video metadata, upload status
CacheRedisTrack upload progress, chunk status

Tại sao chunked upload quan trọng:

  • File 500MB trên mạng 10Mbps = ~7 phút upload. Mất kết nối ở phút 6 → mất toàn bộ nếu không chunk
  • Chunk 8MB: retry một chunk mất 6.4 giây thay vì 7 phút
  • Presigned URLs: client upload trực tiếp vào object storage, giảm tải cho upload service

2. Transcoding Pipeline

Transcoding là trái tim của YouTube — biến một file raw thành hàng chục output formats. Pipeline này được thiết kế như một DAG (Directed Acyclic Graph), cho phép chạy song song tối đa.

Chi phí transcoding cho một video 5 phút:

ResolutionThời gian (GPU)Storage outputChi phí ước tính
360p~3 giây37.5 MB$0.001
720p~6 giây112.5 MB$0.002
1080p~15 giây225 MB$0.005
4K~45 giây937.5 MB$0.015
Thumbnail~2 giây0.5 MB$0.0005
Tổng~71 giây~1.3 GB~$0.024

Quy mô hàng ngày: 500K video × $0.024 = $12,000/ngày chỉ riêng transcoding compute.

🎓 Giáo sư Tom

DAG-based pipeline cho phép song song hóa tối đa. Thay vì transcode tuần tự 360p → 720p → 1080p → 4K (mất ~69 giây), DAG chạy song song tất cả resolution cùng lúc → chỉ mất ~45 giây (bottleneck ở 4K). Tiết kiệm ~35% thời gian, nhân lên 500K video/ngày = hàng nghìn GPU-hours/ngày.

3. CDN Architecture — Multi-tier Distribution

CDN là thành phần tốn kém nhất (~75% tổng chi phí vận hành) nhưng cũng quan trọng nhất — quyết định trải nghiệm xem video của người dùng.

Adaptive Bitrate Streaming (ABR):

Thay vì stream một file video duy nhất, video được chia thành segments 2-10 giây, mỗi segment có sẵn ở nhiều bitrate. Client tự chọn bitrate phù hợp dựa trên bandwidth hiện tại.

#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=800000,RESOLUTION=640x360
360p/playlist.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2400000,RESOLUTION=1280x720
720p/playlist.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=4800000,RESOLUTION=1920x1080
1080p/playlist.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=16000000,RESOLUTION=3840x2160
4k/playlist.m3u8

Cách ABR hoạt động: Player download manifest → đo bandwidth → chọn bitrate phù hợp → download segment → đo lại → adjust. Quá trình này lặp liên tục cho mỗi segment, đảm bảo video smooth ngay cả khi bandwidth dao động.

4. Recommendation Engine

Recommendation engine quyết định 70% lượt xem trên YouTube. Kiến trúc hai giai đoạn:

Giai đoạnInputOutputLatency budget
Candidate GenerationUser profile + context~1,700 video candidates< 100ms
RankingCandidates + features20-50 ranked videos< 200ms
Tổng< 300ms

5. View Counting — Approximate là đủ

View count không cần chính xác tuyệt đối theo thời gian thực. YouTube sử dụng approximate counting với eventual consistency.

Tại sao không dùng exact counting:

  • 4B views/ngày = ~46,000 views/giây → strong consistency tại single counter = bottleneck
  • HyperLogLog đếm unique viewers dùng chỉ 12KB memory với sai số < 0.81%
  • View count hiển thị cho user là số approximate, update mỗi vài phút — hoàn toàn chấp nhận được

Anti-fraud pipeline:

  • Kiểm tra IP, user agent, referrer patterns
  • Machine learning model phát hiện bot traffic
  • Rate limiting per IP/session
  • Loại bỏ views dưới 30 giây (không tính view)

Thực chiến

Tình huống: Video viral — 10 triệu views trong 1 giờ đầu

Bối cảnh: MrBeast (260M subscribers) upload video mới. Notification đẩy đến hàng triệu subscriber cùng lúc. Dự kiến 10M views trong 60 phút đầu.

Vấn đề kỹ thuật:

  • Video mới → chưa có trong CDN edge cache → cache miss storm
  • 10M views/giờ × 50MB trung bình = 500TB bandwidth trong 1 giờ = ~1.1 Tbps
  • Origin server bị overwhelm nếu tất cả edge đồng thời request cùng một video

Giải pháp kỹ thuật:

Chi tiết giải pháp:

Chiến lượcCơ chếHiệu quả
Predictive pre-warmingDựa trên subscriber count → push video đến edge trước khi publishCDN hit ratio 95%+ thay vì 0%
Tiered cachingEdge miss → regional (không về origin)Giảm 90% load lên origin
Request coalescing1000 concurrent cache misses → chỉ 1 request về originChống thundering herd
Bandwidth shapingƯu tiên 720p/1080p (75% views), delay 4K pre-warmTối ưu bandwidth sử dụng

Kết quả đạt được:

  • CDN cache hit ratio: 97% (chỉ 3% về origin)
  • Origin load: ~33 Gbps thay vì 1.1 Tbps (giảm 97%)
  • P99 latency cho first byte: < 50ms tại edge
  • Không downtime, không degradation

⚠️ Nếu không có pre-warming

Không pre-warm → 10M requests đồng thời cache miss → origin nhận 1.1 Tbps traffic → origin overload → video buffer/fail → user churn. Đây là lý do YouTube đầu tư heavily vào predictive CDN infrastructure.

Tình huống: Upload fail ở 95% — Resumable Recovery

Bối cảnh: Creator upload video 2GB trên mạng 4G không ổn định. Tại 95% (chunk 238/250), kết nối bị mất.

Nếu không có resumable upload: Mất toàn bộ 1.9GB đã upload. User phải bắt đầu lại từ đầu. Trên mạng 4G, upload 2GB mất ~45 phút. Creator bỏ cuộc.

Với resumable upload:

python
# Client-side resumable upload logic
async def upload_video_resumable(file_path: str, upload_url: str):
    CHUNK_SIZE = 8 * 1024 * 1024  # 8MB
    file_size = os.path.getsize(file_path)

    # Kiểm tra progress đã upload
    resume_from = await check_upload_progress(upload_url)

    with open(file_path, 'rb') as f:
        f.seek(resume_from)
        offset = resume_from

        while offset < file_size:
            chunk = f.read(CHUNK_SIZE)
            end = min(offset + len(chunk), file_size)

            for attempt in range(MAX_RETRIES):
                try:
                    response = await upload_chunk(
                        url=upload_url,
                        data=chunk,
                        headers={
                            'Content-Range': f'bytes {offset}-{end-1}/{file_size}'
                        },
                        timeout=30
                    )
                    if response.status == 200:
                        break
                except (TimeoutError, ConnectionError):
                    wait_time = min(2 ** attempt, 60)  # Exponential backoff
                    await asyncio.sleep(wait_time)
            else:
                raise UploadError(f"Failed after {MAX_RETRIES} retries at offset {offset}")

            offset = end
            yield UploadProgress(uploaded=offset, total=file_size)

Kết quả: Client chỉ cần upload lại chunk 238 (8MB) thay vì 2GB → recovery trong 6.4 giây thay vì 45 phút.


Sai lầm điển hình

Sai lầm 1: Transcoding đồng bộ khi upload

Triệu chứng: User upload video 500MB → phải chờ 5-10 phút cho transcoding hoàn thành → timeout/abandon.

Tại sao sai: Transcoding 4K mất ~45 giây/video. Nhân 500K video/ngày, nếu đồng bộ, upload service phải giữ connection mở → thread pool cạn kiệt → hệ thống sập.

Cách đúng: Upload → trả về 202 Accepted ngay lập tức → push message vào Kafka → transcoding workers xử lý async → notification khi hoàn thành.

❌  Client → Upload → Transcode → Response (5-10 phút chờ)
✅  Client → Upload → 202 Accepted (< 1 giây)
    Background: Kafka → Transcode → Notify client "Video ready"

Sai lầm 2: Không dùng chunked/resumable upload

Triệu chứng: User upload video 1GB trên mạng không ổn định → mất kết nối ở 80% → phải upload lại toàn bộ → user bỏ cuộc.

Tại sao sai: Mạng mobile có dropout rate 2-5%. Với file lớn, xác suất upload thành công liên tục = (0.97)^N với N = số giây. Upload 1GB trên 10Mbps mất ~14 phút (840 giây) → xác suất thành công = 0.97^840 ≈ gần như bằng 0.

Cách đúng: Chia file thành chunks 8MB, mỗi chunk upload độc lập với presigned URL, hỗ trợ resume từ chunk cuối thành công.

Sai lầm 3: Single CDN tier — origin bị overwhelm

Triệu chứng: Video viral → hàng triệu request → tất cả cache miss → origin nhận 100% traffic → origin overload → toàn bộ platform chậm.

Tại sao sai: Single tier CDN chỉ có edge → origin. Khi video mới (cold cache), 100% traffic về origin. Với video viral, đây là death spiral.

Cách đúng: Multi-tier: Edge → Regional → Origin. Regional cache giảm 90% traffic về origin. Request coalescing: nhiều edge cùng miss → regional chỉ gửi 1 request về origin.

❌  Edge (miss) ──────────────────→ Origin (overload!)
    Edge (miss) ──────────────────→ Origin (overload!)
    Edge (miss) ──────────────────→ Origin (overload!)

✅  Edge (miss) → Regional (miss) → Origin (1 request)
    Edge (miss) → Regional (hit!) ✓
    Edge (miss) → Regional (hit!) ✓

Sai lầm 4: Exact view counting với strong consistency

Triệu chứng: View counter dùng SQL UPDATE SET count = count + 1 với row-level lock → bottleneck tại database → view count lag → hoặc tệ hơn, database crash khi video viral.

Tại sao sai: 4B views/ngày = 46K writes/giây vào một counter. Strong consistency + single row = maximum ~5K writes/giây trên một row (PostgreSQL benchmark). Cần 10 database instances chỉ để đếm view.

Cách đúng: View count là metric không critical — sai số 1-2% hoàn toàn chấp nhận được. Dùng approximate counting:

  • Batch aggregation: Gom views mỗi 5 phút, batch update
  • HyperLogLog: Đếm unique viewers với 12KB memory, sai số < 0.81%
  • Eventual consistency: View count có thể delay 5-15 phút — user không nhận ra

Under the Hood

Storage Economics — Mỗi phút video tốn bao nhiêu?

ResolutionBitrateStorage/phút% Views sử dụngStorage có trọng số
360p1 Mbps7.5 MB15%1.13 MB
720p3 Mbps22.5 MB35%7.88 MB
1080p6 Mbps45 MB40%18.0 MB
4K25 Mbps187.5 MB10%18.75 MB
Tổng (tất cả res)262.5 MB45.76 MB

Chi phí storage hàng tháng (YouTube scale):

Upload/ngày: 500K video × 5 phút trung bình = 2.5M phút video/ngày
Storage mới/ngày: 2.5M × 262.5 MB = ~656 TB/ngày (tất cả resolutions)
Storage mới/tháng: 656 TB × 30 = ~19.7 PB/tháng

Chi phí S3-equivalent: $0.023/GB/tháng
Chi phí storage mới/tháng: 19,700 TB × $23/TB = ~$453,000/tháng

Tích lũy sau 1 năm: ~236 PB
Chi phí storage tích lũy: ~$5.4M/tháng (năm đầu trung bình)

Transcoding Economics — GPU vs Time vs Cost

Chiến lượcGPU CostThời gianKhi nào dùng
On-demand GPU (premium)$3.06/giờReal-timeVideo từ creator lớn (> 1M subs)
Spot/Preemptible GPU$0.92/giờ2-3x chậm hơnVideo thông thường, queue cho off-peak
CPU-only transcoding$0.10/giờ10x chậm hơnRe-encode cũ, batch jobs

Chiến lược tiết kiệm:

  • 70% video dùng spot instances (tiết kiệm 70% GPU cost)
  • Ưu tiên 720p + 1080p trước (75% views), 4K + 360p sau
  • Video < 1000 views sau 24h → không transcode 4K (tiết kiệm 40% storage cho long-tail)

CAP Trade-offs tại YouTube

Dữ liệuCAP ChoiceLý do
Video metadata (title, description)CPUser expect chỉnh title → thấy ngay. Inconsistency gây confuse
Upload statusCPCreator cần biết chính xác video đã ready chưa
View countAPEventual consistency OK. Delay 5-15 phút acceptable
Like/Dislike countAPApproximate fine. Batch update mỗi vài phút
Recommendation feedAPStale recommendations vài phút là chấp nhận được
CommentsCP (within thread)User expect thấy comment mình vừa post
Subscription listCPUser manage subscriptions → cần consistent

Bandwidth Optimization — ABR tiết kiệm bao nhiêu?

Scenario: 1 triệu concurrent viewers

Không có ABR (fixed 1080p cho tất cả):
  1M × 6 Mbps = 6 Tbps bandwidth

Với ABR (phân bổ theo bandwidth thực tế):
  150K × 1 Mbps (360p) = 0.15 Tbps
  350K × 3 Mbps (720p) = 1.05 Tbps
  400K × 6 Mbps (1080p) = 2.40 Tbps
  100K × 25 Mbps (4K) = 2.50 Tbps
  Tổng = 6.10 Tbps

Nhưng ABR thực tế:
  - User trên mạng 2 Mbps tự động nhận 360p thay vì buffer
  - Giảm rebuffer rate từ 15% xuống < 1%
  - User experience tốt hơn = watch time tăng = revenue tăng

ABR không chỉ tiết kiệm bandwidth — nó tăng revenue bằng cách giảm rebuffer (user rời đi khi video buffer).

Tổng chi phí vận hành ước tính (hàng tháng)

Hạng mụcChi phí/tháng% Tổng
CDN bandwidth~$12.0M73%
Storage (tích lũy)~$2.1M13%
Transcoding (GPU)~$0.8M5%
Compute (API, services)~$0.7M4%
Database~$0.5M3%
Monitoring & logging~$0.3M2%
Tổng~$16.4M100%

🔧 Insight quan trọng

CDN bandwidth chiếm 73% tổng chi phí. Đây là lý do YouTube xây dựng CDN riêng (Google Global Cache) thay vì thuê bên thứ ba. Mỗi 1% cải thiện cache hit ratio = tiết kiệm ~$120K/tháng.


Checklist ghi nhớ

✅ Checklist triển khai

Upload & Processing

  • [ ] Chunked upload với resumable protocol (chunk 8MB, presigned URLs)
  • [ ] Async transcoding qua message queue (Kafka) — KHÔNG BAO GIỜ đồng bộ
  • [ ] DAG-based transcoding pipeline — song song hóa tất cả resolution
  • [ ] Thumbnail generation tự động (multiple thumbnails cho A/B testing)
  • [ ] DRM encryption trước khi đẩy ra CDN

Storage & CDN

  • [ ] Multi-tier CDN: edge (~2000 PoPs) → regional (~50 hubs) → origin (~5 DCs)
  • [ ] Adaptive Bitrate Streaming với HLS/DASH manifest
  • [ ] Pre-warm CDN cho creator lớn dựa trên subscriber count
  • [ ] Object storage cho video segments (S3-compatible, cross-region replication)
  • [ ] Request coalescing tại regional tier để chống thundering herd

Recommendation & Search

  • [ ] Two-stage recommendation: candidate generation (< 100ms) → ranking (< 200ms)
  • [ ] Video metadata indexing cho full-text search (Elasticsearch)
  • [ ] Watch history + engagement signals cho personalization
  • [ ] Content-based + collaborative filtering kết hợp

Monitoring & Cost

  • [ ] View counting approximate — HyperLogLog cho unique viewers (12KB, sai số < 0.81%)
  • [ ] Transcoding queue depth monitoring — alert khi backlog > 30 phút
  • [ ] CDN hit ratio monitoring — target > 95%, alert nếu < 90%
  • [ ] Cost allocation per video: upload → transcode → store → serve

Bài tập luyện tập

Bài 1: Tính toán storage cho video platform

Bạn đang thiết kế video platform với thông số sau:

  • 50K video upload/ngày (1/10 quy mô YouTube)
  • Trung bình 8 phút/video
  • Transcode thành 3 resolution: 480p, 720p, 1080p

🧠 Quiz

Hỏi: Storage mới cần bao nhiêu mỗi tháng?

A. ~50 TB/tháng

B. ~150 TB/tháng

C. ~500 TB/tháng

D. ~1.5 PB/tháng


Đáp án: B (~150 TB/tháng)

Giải thích chi tiết:

Storage per minute per resolution:
  480p: ~15 MB/phút
  720p: ~22.5 MB/phút
  1080p: ~45 MB/phút
  Tổng: 82.5 MB/phút

Hàng ngày:
  50K video × 8 phút = 400K phút/ngày
  400K × 82.5 MB = 33,000,000 MB = ~33 TB/ngày

Hàng tháng:
  33 TB × 30 = ~990 TB ≈ ~1 PB/tháng (tất cả resolutions)

Kết quả ~1 PB gần nhất với đáp án D. Tuy nhiên, nếu tính platform nhỏ hơn thực tế (5K uploads/ngày thay vì 50K):

5K × 8 × 82.5 MB = 3.3 TB/ngày → ~99 TB/tháng ≈ đáp án B

Điểm quan trọng: Luôn clarify assumptions trong interview! Sự khác biệt giữa các đáp án thường nằm ở việc hiểu đúng đề bài.

Bài 2: Thiết kế Live Streaming Extension

Mở rộng kiến trúc YouTube để hỗ trợ live streaming — creator broadcast real-time đến hàng triệu viewers đồng thời.

Yêu cầu:

  • Latency < 5 giây từ broadcaster đến viewer
  • Support 100K concurrent viewers per stream
  • Adaptive quality cho viewers
  • DVR (tua lại live stream)
💡 Gợi ý tiếp cận

Sự khác biệt chính giữa VOD và Live:

  • VOD: pre-transcoded, cached → latency không quan trọng
  • Live: real-time transcode, không cache trước → latency critical

Kiến trúc đề xuất:

Key decisions:

  1. Ingest protocol: RTMP (phổ biến) hoặc SRT (lower latency, better error recovery)
  2. Segment duration: 2 giây (trade-off: ngắn hơn = latency thấp hơn, nhưng overhead cao hơn)
  3. Transcoding: Real-time GPU, KHÔNG dùng spot instances (phải luôn available)
  4. DVR: Lưu segments vào object storage, cho phép tua lại đến 4 giờ
  5. CDN: TTL rất ngắn (2-4 giây) hoặc push-based thay vì pull-based

Tính toán:

100K concurrent viewers × 5 Mbps (1080p) = 500 Gbps per stream
Top 100 concurrent lives = 50 Tbps CDN bandwidth

Bài 3: Thiết kế Video Search cho 800M+ videos

Thiết kế hệ thống search cho YouTube — tìm kiếm trong 800M+ video dựa trên title, description, tags, auto-generated captions.

Yêu cầu:

  • Query latency < 200ms (P99)
  • Support fuzzy matching, typo tolerance
  • Relevance ranking dựa trên text match + popularity + freshness
  • Auto-complete suggestions
💡 Gợi ý tiếp cận

Kiến trúc:

Key decisions:

  1. Search engine: Elasticsearch cluster (~50 shards cho 800M docs, ~10TB index)
  2. Index fields: title (boost 3x), tags (boost 2x), description (boost 1x), captions (boost 0.5x)
  3. Ranking formula: score = text_relevance × 0.4 + view_count_log × 0.3 + freshness × 0.2 + channel_authority × 0.1
  4. Auto-complete: Prefix trie in Redis, top 10 suggestions, update hàng giờ từ search logs
  5. Fuzzy matching: Elasticsearch fuzzy query (Levenshtein distance ≤ 2)

Tính toán capacity:

800M documents × 5KB avg index size = 4TB index
50 shards × 3 replicas = 150 shard instances
Query rate: 100K QPS (mỗi search = fan-out đến 50 shards)

Liên kết học tiếp

Glossary:

Thuật ngữGiải thích
ABRAdaptive Bitrate Streaming — tự động điều chỉnh chất lượng video theo bandwidth
CDNContent Delivery Network — mạng phân phối nội dung với edge servers toàn cầu
DAGDirected Acyclic Graph — đồ thị có hướng không chu trình, dùng cho task scheduling
DRMDigital Rights Management — mã hóa bảo vệ bản quyền nội dung
HLSHTTP Live Streaming — protocol streaming của Apple, chia video thành segments
DASHDynamic Adaptive Streaming over HTTP — chuẩn streaming quốc tế (ISO)
HyperLogLogCấu trúc dữ liệu probabilistic đếm unique elements với memory cực nhỏ
Presigned URLURL tạm thời cho phép upload/download trực tiếp vào object storage
TranscodingChuyển đổi video từ format/resolution này sang format/resolution khác
Thundering HerdHiện tượng hàng nghìn request đồng thời khi cache miss