Case Study: Video Streaming (YouTube ধরনের)

Upload, transcoding, adaptive streaming

রোডম্যাপের মাস ১২পড়তে প্রায় ৭ মিনিট

YouTube এর মতো video platform এ দুইটা বিশাল কাজ: creator এর upload করা বড় file কে নানা মানের আর format এ process করা, আর সারা পৃথিবীর কোটি দর্শককে, দুর্বল আর শক্তিশালী সব ধরনের network এ, buffering ছাড়া video দেখানো। এখানে storage, CDN আর background processing এর সবচেয়ে বড় রূপ দেখবো। (শেখার জন্য design, আসল YouTube এর ব্যবস্থা না।)

#ধাপ ১: Requirement

Functional:

  • Video upload (কয়েক GB পর্যন্ত), শিরোনাম, বর্ণনা, thumbnail
  • দেখা: বিভিন্ন মান (240p থেকে 1080p/4K), network অনুযায়ী নিজে থেকে মান বদল
  • খোঁজা, view count, like, comment
  • Upload এর অবস্থা ("process হচ্ছে...")

Non-functional:

  • দেখা শুরু দ্রুত (২ সেকেন্ডের মধ্যে), buffering কম
  • Upload নির্ভরযোগ্য (দুর্বল network এ মাঝপথে কাটলে আবার শুরু থেকে না)
  • বিশাল storage আর bandwidth, খরচ নিয়ন্ত্রণ
  • View count কিছুটা দেরিতে হলেও চলে

#ধাপ ২: Estimation

  • DAU ২ কোটি, প্রতিজন দিনে ৫টা video, গড় ৫ মিনিট
  • দেখা: ১০ কোটি view/দিন; ৫ মিনিট × ~৫ Mbps (720p) ≈ ১৮৭ MB প্রতি view → দিনে ~১৮ PB বের হওয়া data
  • Upload: দিনে ৫ লাখ video, গড় ১ GB মূল → ৫০০ TB/দিন মূল; সব মানের copy মিলিয়ে আরও বেশি

সিদ্ধান্ত: Bandwidth এর প্রায় সবটা CDN থেকে, নাহলে অসম্ভব আর অকল্পনীয় খরচ। Storage বিশাল, তাই object storage আর পুরনো/কম দেখা video সস্তা storage এ। Processing বিশাল CPU এর কাজ, তাই queue আর worker এর বড় বহর।

#ধাপ ৩: API

HTTP
POST /v1/uploads                       → {upload_id, part_urls[]}   (multipart pre-signed)
POST /v1/uploads/{id}/complete         → {video_id, status: "processing"}
GET  /v1/videos/{id}                   → {title, status, manifest_url, thumbnails}
GET  {cdn}/videos/{id}/master.m3u8     (HLS manifest)
POST /v1/videos/{id}/views             (batch করে)

#ধাপ ৪ ও ৫: Upload আর processing এর pipeline

Creator resumable Object storage মূল file টুকরো টুকরো Queue Worker: 1080p, 720p, 480p, 240p Worker: thumbnail, preview Worker: যাচাই (নীতিমালা, copyright) Segment + manifest ৪ সেকেন্ডের টুকরো CDN দর্শকের কাছে Metadata DB status: ready
মূল file সরাসরি storage এ, তারপর queue হয়ে অনেক worker সমান্তরালে বিভিন্ন মানে রূপান্তর করে। ফলাফল ছোট টুকরো আর manifest হয়ে CDN এর মাধ্যমে দেখানো হয়।

#Resumable upload

১ GB এর file এক request এ দুর্বল network এ প্রায় কখনো শেষ হয় না। File কে ৮-১৬ MB এর টুকরো করে প্রতিটা আলাদা pre-signed URL এ (S3 multipart upload)। কোনো টুকরো ব্যর্থ হলে শুধু সেটা আবার। সব শেষে complete। App বন্ধ হলেও পরে বাকি টুকরো থেকে শুরু।

#Transcoding

একটা মূল video কে কয়েকটা মান (resolution আর bitrate) আর format এ রূপান্তর (ffmpeg এর মতো tool দিয়ে)। খুব CPU-ভারী, তাই:

  • Video কে কয়েক সেকেন্ডের অংশে ভাগ করে অনেক worker এ সমান্তরালে, তারপর জোড়া (DAG ধরনের workflow)
  • প্রতিটা ধাপ idempotent আর retry যোগ্য; worker spot/সস্তা machine এ চালালে খরচ কম
  • আগে কম মান (360p) তৈরি করে video প্রকাশ, বেশি মান পরে যোগ (creator কে কম অপেক্ষা)

#ধাপ ৬: Deep dive

#Adaptive bitrate streaming (HLS/DASH)

Video কে ছোট টুকরোয় (২-৬ সেকেন্ড) ভাগ করা হয়, প্রতিটা মানের জন্য আলাদা টুকরো। একটা manifest file বলে কোন মানের টুকরো কোথায়:

Text
#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=800000,RESOLUTION=640x360
360p/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2800000,RESOLUTION=1280x720
720p/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5000000,RESOLUTION=1920x1080
1080p/index.m3u8

Player প্রতিটা টুকরো নামানোর সময় network এর গতি মাপে আর পরের টুকরো সেই অনুযায়ী মানের নেয়। মোবাইল data দুর্বল হলে নিজে থেকে 360p, WiFi তে 1080p। Buffering এর বদলে মান সামান্য কমে। বাংলাদেশের অস্থির mobile network এ এটাই মসৃণ অভিজ্ঞতার চাবি।

#CDN আর খরচ

  • প্রায় সব video টুকরো CDN থেকে; জনপ্রিয় video edge এ থাকে
  • পুরনো, কম দেখা video (long tail) এর প্রথম দেখা origin থেকে, তাই origin এর সামনে একটা মাঝের cache স্তর
  • ISP এর ভেতরে cache server (বড় platform গুলো ISP দের সাথে চুক্তি করে তাদের data center এ নিজেদের cache বসায়), যাতে আন্তর্জাতিক bandwidth বাঁচে আর গতি বাড়ে
  • Storage এর স্তর: নতুন/জনপ্রিয় video দ্রুত storage এ, পুরনো সস্তা (cold) storage এ

#View count

প্রতিটা view এ database row আপডেট অসম্ভব (প্রতি সেকেন্ডে লাখো)। Player view event পাঠায় → Kafka → stream processing এ গোনা আর ফাঁকি বাদ (একই user বারবার, bot) → কিছুক্ষণ পর পর মোট সংখ্যা আপডেট। তাই নতুন video তে view count কিছুক্ষণ আটকে থাকা স্বাভাবিক।

#খোঁজা আর recommendation

  • শিরোনাম, বর্ণনা, transcript (স্বয়ংক্রিয় subtitle) Search engine এ index
  • Recommendation: দেখার ইতিহাস থেকে ML; প্রার্থী তৈরি আর ranking দুই ধাপে (news feed এর মতো)

#অনুশীলন

#নিজেকে যাচাই করো

Adaptive bitrate streaming কীভাবে buffering কমায়?

Video ছোট টুকরোয় আর কয়েকটা মানে রাখা থাকে। Player network এর গতি মেপে প্রতিটা পরের টুকরো উপযুক্ত মানের নেয়; network দুর্বল হলে কম মানে চলে যায়, থেমে থাকে না।

বড় video upload কে টুকরো করে (multipart) পাঠানোর লাভ কী?

কোনো টুকরো ব্যর্থ হলে শুধু সেটা আবার পাঠাতে হয়, পুরো file না। দুর্বল network এ আর app বন্ধ হলেও পরে বাকি অংশ থেকে চালিয়ে যাওয়া যায়, আর টুকরোগুলো সমান্তরালে পাঠানো যায়।

Transcoding এ video কে অংশে ভাগ করে অনেক worker এ চালানোর কারণ কী?

একটা বড় video এক machine এ রূপান্তর করতে অনেক সময় লাগে। অংশে ভাগ করে সমান্তরালে চালালে মোট সময় অনেক কমে, আর একটা অংশ ব্যর্থ হলে শুধু সেটা আবার করা যায়।

চিহ্ন দিলে sidebar আর রোডম্যাপে এই অধ্যায়ের station ভরে যাবে।