Nền tảng video
Hiểu đề
Yêu cầu chức năng
- Người dùng có thể tải lên video lớn (đến vài GB) và tiếp tục khi mạng bị ngắt
- Hệ thống xử lý video thành nhiều độ phân giải kèm ảnh thumbnail
- Người dùng có thể xem video mượt, chất lượng tự điều chỉnh theo mạng
- Người dùng có thể xem thông tin video và số lượt xem
Yêu cầu phi chức năng
- Video bắt đầu phát p95 < 2 s, tỉ lệ khựng (rebuffer) < 1% thời gian xem
- Video 10 phút sẵn sàng để xem trong < 10 phút sau khi upload xong
- Không mất video đã upload: độ bền lưu trữ 99,999999999% (11 số 9)
- Trang xem video sẵn sàng 99,95%; số lượt xem được trễ vài phút
- Chi phí băng thông là khoản lớn nhất, phải tối ưu từng MB phát ra
Ngoài phạm vi: Livestream (xem bài Bình luận livestream cho phần real-time); Gợi ý video, tìm kiếm, bình luận, quảng cáo; Kiểm duyệt nội dung và bản quyền (Content ID); DRM cho nội dung trả phí.
Thực thể và API
| Method | Endpoint | Ghi chú |
|---|---|---|
| POST | /v1/uploads | Tạo Video + UploadSession, trả uploadId và presigned URL cho từng phần 8 MB. |
| PUT | {presigned-url}?partNumber=n | Client đẩy thẳng từng phần lên object storage, không đi qua API. |
| GET | /v1/uploads/{id} | Danh sách phần đã nhận, dùng để upload tiếp sau khi mất mạng. |
| POST | /v1/uploads/{id}/complete | Ghép các phần, chuyển Video sang PROCESSING và khởi động pipeline transcode. |
| GET | /v1/videos/{id} | Metadata, số lượt xem và URL master manifest (HLS/DASH) trên CDN có ký. |
| POST | /v1/videos/{id}/views | Heartbeat khi đang xem (30 s/lần), dùng để đếm view và thời gian xem. |
Thiết kế tổng thể
Đi lần lượt từng yêu cầu chức năng. Mục tiêu ở đây là chạy đúng, việc tối ưu để dành cho phần đào sâu.
1) Người dùng có thể tải lên video lớn và tiếp tục khi mất mạng
File gốc vài trăm MB đến vài GB không nên đi qua API server. API chỉ cấp presigned URL, client chia file thành phần 8 MB và đẩy thẳng lên object storage bằng multipart upload.
- 1Client gọi POST /v1/uploads với kích thước file, nhận uploadId và URL cho từng phần
- 2Client PUT song song 3-4 phần một lúc lên S3/GCS, phần lỗi thì gửi lại riêng phần đó
- 3Mất mạng: client gọi GET /v1/uploads/{id} để biết phần nào đã có và gửi tiếp
- 4Xong hết thì gọi /complete, storage ghép thành một object raw/{videoId}
Nguồn: Grokking Modern System Design · ch.26 Design YouTube ↗ · bài "Design of YouTube" · mục "High-level design" (upload, blob storage) ; Grokking Modern System Design · ch.20 Blob Store ↗ · bài "Design of a Blob Store" · mục "Write a blob" (chia blob thành chunk) ; Chưa có nguồn trong thư viện: presigned URL và multipart upload của S3/GCS không có trong sách
2) Hệ thống xử lý video thành nhiều độ phân giải
Sự kiện upload xong kích hoạt một DAG job: kiểm tra file, cắt thành đoạn, encode song song từng đoạn ở từng mức, rồi đóng gói thành HLS/DASH. Mỗi job idempotent nên chạy lại được khi worker chết.
- 1Object storage phát sự kiện upload xong vào queue
- 2Orchestrator tạo DAG: probe → split → encode (đoạn × mức) → package → thumbnail
- 3Worker ffmpeg lấy job, encode đoạn 10 s ở một mức, ghi kết quả lên storage
- 4Đủ đoạn thì package sinh manifest .m3u8/.mpd, cập nhật Video sang READY
Nguồn: Grokking Modern System Design · ch.26 Design YouTube ↗ · bài "Design of YouTube" · mục "High-level design" (encoder/transcoder tạo nhiều độ phân giải) ; Grokking Modern System Design · ch.26 Design YouTube ↗ · bài "The Reality Is More Complicated" · mục "Encode" (chia video thành segment, encode từng segment) ; Grokking Modern System Design · ch.23 Distributed Task Scheduler ↗ · mục "Task idempotency" ; Chưa có nguồn trong thư viện: định dạng HLS/DASH và ffmpeg
3) Người dùng có thể xem video mượt theo tốc độ mạng
Video được lưu thành các segment 4 s ở nhiều bitrate. Player tải manifest, đo băng thông và độ đầy buffer, tự chọn mức phù hợp cho từng segment. Mọi segment đi qua CDN vì nội dung không bao giờ đổi.
- 1Client gọi GET /v1/videos/{id}, nhận URL master manifest có chữ ký hết hạn
- 2Player tải master manifest từ CDN, chọn mức khởi đầu thấp để phát nhanh
- 3Player tải segment tiếp theo, tăng hoặc giảm mức theo băng thông đo được
- 4CDN miss thì lấy từ origin shield, rồi mới tới object storage
Nguồn: Grokking Modern System Design · ch.26 Design YouTube ↗ · bài "The Reality Is More Complicated" · mục "Adaptive streaming" (chọn chunk theo băng thông và buffer), mục "Deliver" ; Grokking Modern System Design · ch.11 Content Delivery Network (CDN) ↗ · mục "Multi-tier CDN architecture" ; Chưa có nguồn trong thư viện: độ dài segment 4 s và URL ký hết hạn
4) Người dùng có thể xem thông tin video và số lượt xem
Metadata đọc nhiều hơn ghi rất nhiều nên đi qua cache. Lượt xem được ghi thành sự kiện và cộng dồn bất đồng bộ, số hiển thị có thể trễ vài phút.
- 1API đọc metadata từ Redis, miss thì đọc DB replica rồi ghi lại cache
- 2Player gửi heartbeat /views mỗi 30 s
- 3Heartbeat vào bộ đếm (Redis ở mức vừa, Kafka + stream job ở mức lớn)
- 4Bộ đếm định kỳ ghi tổng vào DB, cache metadata được làm mới
Nguồn: Grokking Modern System Design · ch.26 Design YouTube ↗ · bài "Evaluation of YouTube's Design" · mục "Distributed cache", "Consistency" (chấp nhận nhất quán yếu cho số liệu không quan trọng) ; Grokking Modern System Design · ch.16 Distributed Cache ↗ · mục "Writing policies" ; Grokking Modern System Design · ch.24 Sharded Counters ↗ · mục "High-level solution sketch"
Hạ tầng theo quy mô
Cùng một sản phẩm, ba mức người dùng. Chọn từng mức để xem sơ đồ, phép tính và cấu hình server thay đổi thế nào.
Nền tảng video nội bộ hoặc khóa học online. Upload thẳng lên object storage, 1-2 worker ffmpeg, phát HLS qua CDN thuê ngoài. API và Postgres gần như không chịu tải; tiền chủ yếu nằm ở băng thông.
Ước lượng
- Xem: 10.000 DAU × 20 phút = 200.000 phút/ngày; bitrate TB 1,5 Mbps → 1,5 × 60 / 8 = 11,25 MB/phút
- Băng thông: 200.000 × 11,25 MB = 2,25 TB/ngày × 30 ≈ 67,5 TB/tháng ra CDN
- Đồng thời: 200.000 / 1.440 phút ≈ 139 người, đỉnh ×3 ≈ 417 × 1,5 Mbps ≈ 625 Mbps
- Upload: 100 video × 10 phút = 1.000 phút/ngày; file gốc 8 Mbps = 60 MB/phút → 60 GB/ngày, giữ 30 ngày = 1,8 TB
- Ladder 3 mức 720p 2,5 + 480p 1 + 360p 0,6 = 4,1 Mbps → 30,75 MB/phút × 1.000 ≈ 30,75 GB/ngày ≈ 11,2 TB/năm
- Transcode ≈ 1× thời gian thực trên 4 vCPU: 1.000 / 1.440 ≈ 0,7 worker → 1-2 worker; API: 10.000 × 30 / 86.400 ≈ 3,5 req/s, đỉnh ×10 = 35 req/s → 2 instance
Nguồn con số: Grokking Modern System Design · ch.26 Design YouTube ↗ · bài "Requirements of YouTube's Design" · mục "Storage estimation", "Bandwidth estimation", "Number of servers estimation" ; Grokking Modern System Design · ch.5 Back-of-the-envelope Calculations ↗ · mục "Requests estimation", "Storage requirements", "Bandwidth requirements" ; Quy tắc ước lượng của khoá học · /hoc/chon-server (bitrate từng mức, transcode ≈ 1× thời gian thực, 600 req/s mỗi instance, Redis ×1,3 là giả định của khoá học)
Bảng hạ tầng
| Thành phần | Chọn | Số lượng | Cấu hình | Vì sao |
|---|---|---|---|---|
| CDN | Bunny CDN / CloudFront | 1 | Cache segment HLS, TTL dài | 67,5 TB/tháng nếu đi từ origin sẽ đắt và chậm; segment không đổi nên hit rate rất cao. |
| API | Node.js (NestJS) trên Cloud Run | 2 | 2 vCPU · 4 GB RAM | 35 req/s đỉnh chỉ cần 1 instance, chạy 2 để dự phòng; file video không đi qua API. |
| Database | PostgreSQL managed | 1 | 2 vCPU · 8 GB · 50 GB SSD | Metadata vài chục nghìn video là rất nhỏ; bảng job dùng luôn làm hàng đợi (pg-boss). |
| Object storage | S3 / GCS | 1 bucket raw + 1 bucket HLS | 1,8 TB raw + 11,2 TB/năm HLS | Multipart upload có sẵn, độ bền 11 số 9, không bao giờ lưu video trong DB. |
| Transcode worker | ffmpeg trong container (Cloud Run Jobs) | 1-2 | 4 vCPU · 8 GB | 1.000 phút video/ngày chỉ dùng khoảng 0,7 worker, scale về 0 khi không có job. |
| Đếm lượt xem | UPDATE trực tiếp trong Postgres | 0 (dùng DB) | Vài lượt/s | 10.000 × 4 view / 86.400 ≈ 0,5 lượt/s, chưa cần hệ thống riêng. |
- Điểm xuất phát: upload thẳng lên storage, API chỉ ký URL
- Ladder 3 mức tối đa 720p để giữ chi phí lưu trữ và băng thông thấp
- Postgres làm luôn hàng đợi job transcode
Khi upload tăng lên hàng nghìn video/ngày, encode tuần tự cả file trên 1-2 worker tạo hàng đợi dài nhiều giờ. Hóa đơn CDN cũng tăng tuyến tính theo phút xem.
Cấu hình và chi phí là ước lượng để học và trình bày trong phỏng vấn. Xem cách tính ở bài Chọn server.
So sánh nhanh ba mức
| Thành phần | Mức 1 | Mức 2 | Mức 3 |
|---|---|---|---|
| Người dùng | 10.000 DAU, 100 video upload/ngày | 1 triệu DAU, 2.000 video upload/ngày | 50 triệu DAU, 100.000 video upload/ngày |
| Chi phí | ≈ 1.000–2.000 USD/tháng (ước lượng, hơn 70% là băng thông CDN) | ≈ 40.000–80.000 USD/tháng (ước lượng, hơn 80% là băng thông CDN) | Hàng triệu USD/tháng (ước lượng); băng thông vẫn là khoản lớn nhất dù đã có cache trong ISP |
| CDN | Bunny CDN / CloudFront 1 × Cache segment HLS, TTL dài | CloudFront / Akamai + origin shield 1 × 62,5 Gbps đỉnh, URL ký | Chưa cần |
| API | Node.js (NestJS) trên Cloud Run 2 × 2 vCPU · 4 GB RAM | Node.js (NestJS), container autoscale 3-6 (autoscale) × 2 vCPU · 4 GB RAM | Node.js trên Kubernetes, 3 region 87 pod (HPA) × 2 vCPU · 4 GB mỗi pod |
| Database | PostgreSQL managed 1 × 2 vCPU · 8 GB · 50 GB SSD | PostgreSQL managed (HA) 1 primary + 2 read replica × 4 vCPU · 16 GB · 200 GB SSD | MySQL + Vitess, shard theo video_id 4 shard × (1 primary + 2 replica) × 8 vCPU · 32 GB · 1 TB SSD |
| Object storage | S3 / GCS 1 bucket raw + 1 bucket HLS × 1,8 TB raw + 11,2 TB/năm HLS | S3 + lifecycle 2 bucket × 399 TB/năm HLS; raw 30 ngày ≈ 28,8 TB | Chưa cần |
| Transcode worker | ffmpeg trong container (Cloud Run Jobs) 1-2 × 4 vCPU · 8 GB | ffmpeg trên EC2 Spot / GKE spot 11-22 (autoscale) × 8 vCPU · 16 GB | ffmpeg (H.264 + AV1 cho video hot) trên spot 556-1.100 (autoscale) × 8 vCPU · 16 GB |
| Đếm lượt xem | UPDATE trực tiếp trong Postgres 0 (dùng DB) × Vài lượt/s | Chưa cần | Chưa cần |
| Redis | Chưa cần | ElastiCache / Memorystore 1 primary + 1 replica × 2 vCPU · 8 GB | Chưa cần |
| Orchestrator | Chưa cần | AWS Step Functions / Temporal 1 × Managed | Temporal cluster 1 cluster (3 region) × History shard trên Cassandra/MySQL |
| Queue | Chưa cần | Amazon SQS 1 × Có dead-letter queue | Chưa cần |
| Edge cache | Chưa cần | Chưa cần | Cache server đặt trong ISP/IXP + CDN thuê cho vùng thiếu ≈ 150 máy cache × 40 Gbps mỗi máy, SSD cho video hot |
| Redis Cluster | Chưa cần | Chưa cần | ElastiCache Redis Cluster 6 shard × (1 primary + 1 replica) × 2 vCPU · 8 GB mỗi node |
| Blob storage | Chưa cần | Chưa cần | S3 / GCS nhiều lớp (Standard, IA, Archive) Đa region × 20,6 PB/năm HLS + raw |
| Kafka | Chưa cần | Chưa cần | MSK / Confluent 6 broker × Topic view-events 24 partition, RF 3 |
| Stream job | Chưa cần | Chưa cần | Apache Flink 1 cluster, 12 task slot × 4 vCPU · 16 GB mỗi TaskManager |
Đào sâu
Mỗi câu hỏi đi từ cách đơn giản đến cách người phỏng vấn mong đợi ở cấp senior.
1) Upload file 2 GB qua mạng di động chập chờn thế nào để không phải làm lại từ đầu?
API nhận toàn bộ file rồi mới ghi lên storage. Mất mạng ở 90% là mất hết, và mỗi upload chiếm một kết nối, bộ nhớ, băng thông của API trong nhiều phút.
Đánh đổi: Dễ viết nhất, chỉ ổn cho file vài MB.
Nguồn: Grokking Modern System Design · ch.20 Blob Store ↗ · bài "Design of a Blob Store" · mục "Write a blob" (blob lớn chia thành chunk) ; Chưa có nguồn trong thư viện: hậu quả giữ kết nối nhiều phút trên API server là suy luận của khoá học
Client cắt file 8 MB một phần, gửi kèm số thứ tự. API ghi từng phần ra đĩa tạm, lưu danh sách phần đã nhận để client hỏi và gửi tiếp.
Đánh đổi: Resume được nhưng dữ liệu vẫn chảy qua API, phải tự lo ghép file và dọn phần thừa.
Nguồn: Grokking Modern System Design · ch.20 Blob Store ↗ · mục "Write a blob" và bài "Design Considerations of a Blob Store" · mục "Blob metadata" (quản lý danh sách chunk)
API tạo multipart upload trên S3/GCS và ký URL cho từng phần. Client đẩy song song 3-4 phần thẳng lên storage, file 2 GB là 256 phần 8 MB. Trạng thái phần nào đã xong do storage giữ (ListParts), API chỉ lưu UploadSession. Thêm checksum từng phần và lifecycle rule tự hủy upload dở sau 7 ngày. Có thể kiểm tra hash file gốc để bỏ qua video trùng.
Đánh đổi: URL ký phải hết hạn ngắn và giới hạn kích thước; cần cấu hình CORS và cơ chế dọn upload bỏ dở.
Nguồn: Grokking Modern System Design · ch.20 Blob Store ↗ · mục "Write a blob" ; Grokking Modern System Design · ch.26 Design YouTube ↗ · bài "Evaluation of YouTube's Design" · mục "Duplicate videos" (chống video trùng) ; Chưa có nguồn trong thư viện: presigned URL, multipart upload, ListParts, lifecycle rule hủy upload dở
2) Pipeline transcode được tổ chức thế nào để video 1 giờ không phải chờ 1 giờ?
Một máy encode toàn bộ video ở 1080p, rồi 720p, rồi 480p. Video 60 phút với 4 mức mất vài giờ, worker chết giữa chừng thì làm lại từ đầu.
Đánh đổi: Đơn giản, chấp nhận được khi chỉ có vài chục video ngắn mỗi ngày.
Nguồn: Grokking Modern System Design · ch.26 Design YouTube ↗ · bài "The Reality Is More Complicated" · mục "Encode" (một video phải encode ra nhiều định dạng) ; Chưa có nguồn trong thư viện: thời gian encode vài giờ là ước lượng của khoá học
Upload xong thì đẩy 4 job (1080p, 720p, 480p, 360p) vào queue, 4 worker chạy song song. Mức thấp xong trước nên video có thể phát sớm ở 360p.
Đánh đổi: Nhanh hơn 4 lần nhưng mức 1080p vẫn phải encode cả file trên một máy.
Nguồn: Grokking Modern System Design · ch.17 Distributed Messaging Queue ↗ · bài "System Design: The Distributed Messaging Queue" (phân tách producer/consumer) ; Grokking Modern System Design · ch.23 Distributed Task Scheduler ↗ · mục "Queueing"
Orchestrator (Temporal, Step Functions, hay scheduler như Grokking ch.23) dựng DAG: probe, cắt video thành đoạn 10 s tại keyframe, mỗi cặp (đoạn, mức) là một job, sau đó ghép và đóng gói HLS/DASH, song song với thumbnail và audio. Video 10 phút có 60 đoạn × 4 mức = 240 job, chạy trên hàng trăm worker spot nên xong trong vài phút. Ladder chọn theo nội dung (per-title): video tĩnh dùng bitrate thấp hơn, giảm lưu trữ và băng thông. Job idempotent theo khóa (video, đoạn, mức) nên worker spot bị thu hồi chỉ chạy lại job đó.
Đánh đổi: Thêm orchestrator phải vận hành; cắt đoạn phải đúng keyframe và đồng bộ audio, nếu không sẽ có vết nối khi phát.
Nguồn: Grokking Modern System Design · ch.26 Design YouTube ↗ · bài "The Reality Is More Complicated" · mục "Encode" (encode theo từng segment/shot, segment ít chuyển động nén mạnh hơn) ; Grokking Modern System Design · ch.23 Distributed Task Scheduler ↗ · mục "Task idempotency", "Resource capacity optimization", "Execution cap" ; Chưa có nguồn trong thư viện: Temporal/Step Functions, cắt tại keyframe
3) Phát video mượt cho người xem ở mạng 3G lẫn cáp quang, với chi phí băng thông chấp nhận được?
Người dùng tải một file 1080p qua HTTP range request từ origin. Mạng yếu thì khựng liên tục, mọi byte đều đi từ data center nên băng thông origin bùng nổ.
Đánh đổi: Không cần xử lý gì thêm nhưng trải nghiệm kém và tốn kém nhất.
Nguồn: Grokking Modern System Design · ch.26 Design YouTube ↗ · bài "The Reality Is More Complicated" · mục "Deploy" (phát thẳng từ data center làm nặng origin) ; Grokking Modern System Design · ch.11 Content Delivery Network (CDN) ↗ · mục "Problem statement"
Có bản 360p, 720p, 1080p trên CDN. Người dùng chọn chất lượng bằng tay. CDN gánh phần lớn lưu lượng.
Đánh đổi: Không tự thích nghi khi mạng đổi giữa chừng; đổi chất lượng phải tải lại từ đầu file.
Nguồn: Grokking Modern System Design · ch.26 Design YouTube ↗ · bài "Design of YouTube" · mục "High-level design" (video phổ biến đẩy lên CDN) ; Grokking Modern System Design · ch.11 Content Delivery Network (CDN) ↗ · mục "Content caching strategies in CDN"
Mỗi mức là chuỗi segment 4 s, manifest liệt kê các mức. Player (hls.js, ExoPlayer) chọn mức cho từng segment theo băng thông và buffer, bắt đầu thấp để phát nhanh. Segment không bao giờ đổi nên cache TTL dài ở CDN, có origin shield gom miss. Ở quy mô rất lớn, như Grokking ch.26 mô tả, video phổ biến được đẩy sẵn vào cache đặt trong ISP/IXP, video ít xem phục vụ từ colocation site hoặc data center gốc. URL được ký và hết hạn để chặn link lậu.
Đánh đổi: Lưu nhiều bản của một video tốn storage; segment ngắn thì đổi mức nhanh nhưng nhiều request hơn.
Nguồn: Grokking Modern System Design · ch.26 Design YouTube ↗ · bài "The Reality Is More Complicated" · mục "Adaptive streaming", "Deploy" (đặt chunk video phổ biến ở ISP/IXP), "Deliver" (video ít xem phục vụ từ colocation site hoặc data center) ; Grokking Modern System Design · ch.11 Content Delivery Network (CDN) ↗ · mục "Multi-tier CDN architecture", "Time-to-live (TTL)" ; Chưa có nguồn trong thư viện: hls.js/ExoPlayer, URL ký
4) Đếm lượt xem cho hàng trăm triệu lượt mỗi ngày, và dùng dữ liệu đó để giảm chi phí lưu trữ thế nào?
Video viral nhận hàng nghìn lượt/s, tất cả tranh khóa trên cùng một hàng. Đồng thời mọi video, kể cả video 0 lượt xem trong 2 năm, vẫn nằm đủ 5 mức ở lớp lưu trữ đắt nhất.
Đánh đổi: Đúng với vài nghìn lượt/ngày; ở quy mô lớn thì DB nghẽn và hóa đơn storage tăng tuyến tính mãi.
Nguồn: Grokking Modern System Design · ch.24 Sharded Counters ↗ · mục "Problem statement" (một bộ đếm bị ghi dồn dập gây tranh chấp khóa) ; Grokking Modern System Design · ch.26 Design YouTube ↗ · bài "The Reality Is More Complicated" · mục "Deploy" (Flash servers cho video phổ biến, storage servers cho video ít xem)
Mỗi heartbeat là một INCR trên Redis, job 30 s một lần cộng dồn vào DB. Storage có rule: file gốc sau 30 ngày chuyển sang lớp archive, segment sau 1 năm sang lớp truy cập ít.
Đánh đổi: Không chống được view ảo, mất Redis là mất vài chục giây số đếm; theo tuổi thì video cũ nhưng vẫn hot cũng bị chuyển lớp.
Nguồn: Redis in Action ↗ · ch.5 · §5.2.1 Storing counters in Redis ; Chưa có nguồn trong thư viện: lifecycle rule theo tuổi file của object storage
Heartbeat vào Kafka partition theo video_id. Job Flink gom theo cửa sổ 1 phút, bỏ trùng theo session, lọc bot, rồi ghi tổng vào DB; video cực hot có thể dùng sharded counter (Grokking ch.24). Cùng dữ liệu này tính độ phổ biến: video hot được đẩy trước lên CDN/ISP cache, video ít xem chuyển sang lớp lưu trữ rẻ, video gần như không ai xem chỉ giữ 2-3 mức thấp và encode lại mức cao khi cần.
Đánh đổi: Số lượt xem hiển thị trễ 1-2 phút và hệ thống phức tạp hơn; encode lại theo yêu cầu làm lượt xem đầu tiên ở mức cao chậm hơn.
Nguồn: Grokking Modern System Design · ch.24 Sharded Counters ↗ · mục "Detailed design", "Burst of writes requests" ; Grokking Modern System Design · ch.18 Pub-sub ↗ · bài "Design of a Pub-sub System" (topic chia partition) ; Grokking Modern System Design · ch.26 Design YouTube ↗ · bài "The Reality Is More Complicated" · mục "Deploy" (độ phổ biến quyết định nơi đặt nội dung) ; Chưa có nguồn trong thư viện: Kafka, Flink và cửa sổ 1 phút (thư viện không có sách stream processing)
Trong phỏng vấn
- “File video không bao giờ đi qua API server: client upload nhiều phần thẳng lên object storage bằng presigned URL.”
- “Transcode là DAG job: cắt đoạn theo keyframe, encode song song đoạn × mức, mỗi job idempotent để chạy trên máy spot.”
- “Tôi phát bằng HLS/DASH với segment vài giây để player tự đổi chất lượng, và segment bất biến nên cache rất tốt ở CDN.”
- “Ở quy mô lớn băng thông là chi phí số một, nên tôi dùng độ phổ biến để quyết định video nào nằm ở edge cache và lớp lưu trữ nào.”
- Cho file vài GB đi qua API hoặc lưu video trong database.
- Encode cả video trên một máy, làm lại từ đầu khi máy chết.
- Quên tính băng thông phát ra, chỉ tính dung lượng lưu trữ.
- Cộng lượt xem bằng UPDATE trực tiếp trên một hàng cho video viral.
Đọc thêm
Sách trong thư viện của bạn. Số chương có thể lệch nhẹ so với bản PDF.