০০ যে প্রশ্নগুলোর উত্তর খুঁজবো
আগের চারটা সেশনে আমরা ধাপে ধাপে বড় হয়েছি: URL shortener এ একটা key আর একটা cache, rate limiter আর search এ Redis আর index, feed এ fan-out, আর chat এ real-time connection। এবার আরো বড় একটা system: শূন্য থেকে একটা পুরো video streaming platform, YouTube বা Netflix এর মতো। এখানে সবচেয়ে বড় চ্যালেঞ্জ data এর পরিমাণ। প্রতিটা video কয়েক GB, আর এক রাতে পাঠাতে হয় কয়েক petabyte।
কাঠামো আগের মতোই, সেশন ২৩ এর সাতটা ধাপ। আগে জানবো কী বানাতে হবে, তারপর হিসাব করবো কত বড় বানাতে হবে। দেখবেন, এখানে হিসাবটাই সবচেয়ে বড় কথা বলবে।
- ১ "দেখো" এর জন্য ঠিক কী বানাবো? (functional ও non-functional requirements)
- ২ System টা কত বড় হতে হবে? (back-of-envelope estimation, egress)
- ৩ অ্যাপ কোন API call করবে, আর data কোথায় থাকবে? (API, data model, object storage)
- ৪ পুরো system টা এক নজরে কেমন দেখায়? (high-level design)
- ৫ Upload হওয়া video দেখার উপযোগী হয় কীভাবে? (upload pipeline, transcoding)
- ৬ দুর্বল network এও video না থেমে চলে কীভাবে? (adaptive bitrate, segment, manifest, HLS, DASH)
- ৭ ২০ লাখ মানুষকে একসাথে video পাঠাবো কোথা থেকে? (CDN, popular বনাম long-tail)
- ৮ সেকেন্ডে হাজার হাজার view এলে গুনবো কীভাবে? (view counter at scale)
- ৯ Design টা কোথায় চাপে পড়ে, আর কী ছাড় দিলাম? (bottlenecks ও trade-offs)
০১ “দেখো” এর জন্য ঠিক কী বানাবো? (functional ও non-functional requirements)
ঈদের ঠিক দুই সপ্তাহ আগের এক বিকেল। “দেখো” এর ছোট্ট অফিসে নাবিলা whiteboard এর সামনে দাঁড়িয়ে আছে। ছয় মাস আগে BSc শেষ করে সে এখানে backend engineer হিসেবে যোগ দিয়েছে। CTO ফাহিম ভাই এসে বললেন, “এবার ঈদের রাত ৯টায় আমাদের নাটক ‘ফেরা’ premiere হবে। Marketing বলছে, সেই রাতে ৫০ লাখ মানুষ দেখবে।” একটু থেমে যোগ করলেন, “গত ঈদে দুই লাখ মানুষেই অ্যাপ আটকে গিয়েছিলো, মনে আছে তো?” নাবিলার হাতের marker টা হঠাৎ ভারী মনে হলো।
“দেখো” একটা বাংলাদেশি startup। এদের অ্যাপ এ বাংলা নাটক আর টেলিফিল্ম দেখা যায়। Production house আর ছোট creator রা নিজেদের video upload করেন, আর দর্শক mobile, TV বা browser এ দেখেন।
নাবিলা সাথে সাথে box আঁকতে শুরু করলো না। প্রথমে সে লিখলো, system টা কী কী করবে। এগুলোকে বলে functional requirement। তারপর লিখলো, system টা কতটা ভালোভাবে করবে: কত দ্রুত, কত মানুষের জন্য, কতটা নির্ভরযোগ্যভাবে। এগুলোকে বলে non-functional requirement।
Functional requirement: system কী কী করবে
- Upload: Creator একটা video upload করতে পারবেন। একটা ৪৫ মিনিটের নাটকের raw file প্রায় 2 GB।
- দেখা: দর্শক mobile, TV আর browser এ video দেখতে পারবেন। Network দুর্বল হলেও video চলবে।
- View count: প্রতিটা video এর নিচে কতজন দেখেছেন, সেই সংখ্যা দেখাবে।
যা এই design এ রাখছি না, সেটাও লিখে রাখা জরুরি। Search, recommendation, comment, subscription এর payment আর DRM (video কপি হওয়া ঠেকানোর ব্যবস্থা) এই সেশনের বাইরে। Interview তেও এভাবে scope ছোট করে নিলে interviewer খুশিই হন। কারণ ৪৫ মিনিটে সবকিছু design করা যায় না।
Non-functional requirement: কতটা ভালোভাবে করবে
| বিষয় | লক্ষ্য |
|---|---|
| Scale | ঈদের রাতে ৫০ লাখ দর্শক, রাত ৯টায় একসাথে প্রায় ২০ লাখ। |
| শুরু হওয়ার সময় | Play চাপার ২ সেকেন্ডের মধ্যে video শুরু হবে। |
| Buffering | দেখার মোট সময়ের ১% এর কম সময় spinner ঘুরবে। |
| Availability | দেখার পথ ৯৯.৯% সময় চালু থাকবে (SLO, সেশন ০১)। Upload এর পথ একটু ধীর হলেও চলে। |
| Durability | একবার upload হওয়া video কখনো হারাবে না। |
| Consistency | View count কয়েক সেকেন্ড পিছিয়ে থাকলে সমস্যা নেই (eventual consistency, সেশন ০৩)। |
| খরচ | Bandwidth এর খরচ startup এর সাধ্যের মধ্যে থাকবে। |
এই table থেকে একটা বড় সত্য বেরিয়ে আসে। Upload হয় কালেভদ্রে, আর কয়েক মিনিট দেরি হলেও কেউ রাগ করেন না। কিন্তু দেখার সময় এক সেকেন্ডের আটকে যাওয়াও দর্শক টের পান। অর্থাৎ এটা একটা read-heavy system। পুরো design এর বেশিরভাগ মনোযোগ যাবে দেখার পথে।
Requirement লেখা মানে শুধু feature এর তালিকা বানানো নয়। আসল কাজ হলো আলাদা করা, কোন অংশ ধীর হলে চলে আর কোন অংশ এক মুহূর্তও ধীর হতে পারবে না। “দেখো” তে upload ধীর হলে চলে, দেখা ধীর হলে চলে না। এই একটা সিদ্ধান্তই পরের সব design ঠিক করে দেয়।
০২ System টা কত বড় হতে হবে? (back-of-envelope estimation, egress)
নাবিলা এবার একটা কাগজ টেনে নিলো। এবার back-of-envelope estimation এর পালা (সেশন ২৩)। মনে করিয়ে দিই, এর লক্ষ্য নিখুঁত সংখ্যা নয়। লক্ষ্য হলো সংখ্যাটা কোন মাপের, সেটা জানা: 3 GB নাকি 3 TB, ৩০০ request নাকি ৩ লাখ। মাপটা ঠিক থাকলে design ও ঠিক দিকে যায়।
হিসাবের আগে দুইটা শব্দ জেনে নিন। Bitrate মানে video এর প্রতি সেকেন্ডে কত bit data লাগে। 1080p এর একটা video তে সাধারণত প্রায় 5 Mbps (প্রতি সেকেন্ডে ৫০ লাখ bit) লাগে। আর egress মানে আপনার server থেকে বাইরের দুনিয়ায় যাওয়া data। Cloud এ ভেতরে data আনা প্রায় বিনা পয়সায় হয়, কিন্তু বাইরে পাঠানো প্রতিটা GB এর জন্য টাকা দিতে হয়।
এখানে ছয়টা ধাপে পুরো হিসাব। প্রথম ধাপের সংখ্যাগুলো নাবিলা ফাহিম ভাইয়ের সাথে কথা বলে ধরে নিয়েছে। বাকি সব ঐ সংখ্যা থেকে গুণ-ভাগ করে বের করা:
# ধাপ 0: ধরে নেওয়া সংখ্যা (assumption)
upload / দিন = 1,000 টা video
গড় দৈর্ঘ্য = 30 মিনিট = 1,800 সেকেন্ড
original bitrate = 8 Mbps
rendition ladder = 1080p 5 + 720p 3 + 480p 1.2 + 360p 0.6 + 240p 0.2
= 10 Mbps (পাঁচটা মিলিয়ে)
# ধাপ 1: একটা video কত জায়গা নেয়
original = 8 Mbps × 1,800 s = 14,400 Mb ÷ 8 = 1,800 MB ≈ 1.8 GB
renditions = 10 Mbps × 1,800 s = 18,000 Mb ÷ 8 = 2,250 MB ≈ 2.25 GB
মোট ≈ 4 GB প্রতি video
# ধাপ 2: storage
প্রতিদিন = 1,000 × 4 GB = 4 TB
প্রতি বছর = 4 TB × 365 ≈ 1,460 TB ≈ 1.5 PB
# ধাপ 3: upload এর হার (write)
1,000 ÷ 86,400 s ≈ 0.012 upload/s (দেড় মিনিটে প্রায় একটা)
ingress = 1,800 GB ÷ 86,400 s ≈ 21 MB/s ≈ 167 Mbps
# ধাপ 4: peak egress (read), ঈদের রাত 9টা
একসাথে দর্শক = 20 লাখ = 2,000,000
গড় bitrate = 1.5 Mbps (বেশিরভাগ mobile, 480p থেকে 720p)
peak egress = 2,000,000 × 1.5 Mbps = 3,000,000 Mbps = 3 Tbps
এক server ≈ 10 Gbps পাঠাতে পারে
server লাগবে = 3 Tbps ÷ 10 Gbps = 300 টা, শুধু bandwidth এর জন্য
# ধাপ 5: এক রাতের মোট egress আর খরচ
প্রতি দর্শক = 1 ঘণ্টা × 1.5 Mbps = 3,600 s × 1.5 = 5,400 Mb = 675 MB
50 লাখ দর্শক = 5,000,000 × 675 MB ≈ 3,400,000 GB ≈ 3.4 PB
খরচ ($0.02/GB) = 3,400,000 × 0.02 ≈ $68,000 ≈ ৳80 লাখ (1 $ ≈ ৳120)
# ধাপ 6: view counter (write, একটাই নাটক)
20 লাখ মানুষ 10 মিনিটের মধ্যে play চাপে
2,000,000 ÷ 600 s ≈ 3,333 view/s, সবগুলো একই row এ
হিসাব শেষে নাবিলা কিছুক্ষণ চুপ করে বসে রইলো। তিনটা সংখ্যা তার চোখে আটকে গেছে।
- Storage এ প্রতিদিন 4 TB: এত বড় file database এ রাখার জিনিস নয়। এর জন্য আলাদা ধরনের storage লাগবে।
- রাত ৯টায় 3 Tbps egress: ভেতরে আসে মাত্র 167 Mbps, আর বাইরে যায় তার প্রায় ১৮,০০০ গুণ। এক data center থেকে এটা পাঠাতে শুধু bandwidth এর জন্যই ৩০০টা server লাগবে। তার উপর ঢাকার এক জায়গা থেকে সিলেটের গ্রাম পর্যন্ত প্রতিটা segment কে লম্বা পথ পাড়ি দিতে হবে।
- একটা row এ সেকেন্ডে ৩,৩৩৩ write: ‘ফেরা’ এর view count এর row টা একাই পুরো database কে ব্যস্ত রাখবে।
এই তিনটা সংখ্যা থেকেই পরের তিনটা বড় design সিদ্ধান্ত আসে:
এক রাতের egress প্রায় 3.4 PB। প্রতি GB তে মাত্র দুই cent ধরলেও সেটা প্রায় $68,000, মানে প্রায় ৮০ লাখ টাকা। অথচ সারা বছরে জমানো 1.5 PB video এক মাস রাখতে খরচ এর অর্ধেকেরও কম। Video platform এ storage নয়, bandwidth ই সবচেয়ে বড় খরচ। তাই যে design প্রতিটা GB কে দর্শকের কাছাকাছি থেকে পাঠায়, সেটাই টিকে থাকে।
০৩ অ্যাপ কোন API call করবে, আর data কোথায় থাকবে? (API, data model, object storage)
API: অ্যাপ আর server এর চুক্তি
API হলো অ্যাপ আর server এর মধ্যে কথা বলার নিয়ম। কোন URL এ কী পাঠালে কী ফেরত আসবে, সেটা আগে থেকে ঠিক করা থাকে। “দেখো” এর জন্য পাঁচটা call যথেষ্ট:
# 1. Upload শুরু: video_id আর upload URL চাওয়া
POST /v1/videos
body: { "title": "ফেরা", "size_bytes": 1932735283 }
response: { "video_id": "v_8f3k2",
"upload_url": "https://store.dekho.example/raw/v_8f3k2?sig=..." }
# 2. File পাঠানো: সরাসরি object storage এ, 5 MB এর টুকরো করে
PUT {upload_url}
Content-Range: bytes 0-5242879/1932735283
# 3. Upload শেষ হয়েছে জানানো
POST /v1/videos/v_8f3k2/complete
response: { "status": "PROCESSING" }
# 4. দেখার আগে metadata আর manifest এর ঠিকানা নেওয়া
GET /v1/videos/v_8f3k2
response: { "title": "ফেরা", "status": "READY", "view_count": 1240000,
"manifest_url": "https://cdn.dekho.example/v_8f3k2/master.m3u8" }
# 5. Player প্রতি 30 সেকেন্ডে জানায়: "এখনো দেখছি"
POST /v1/videos/v_8f3k2/heartbeat
body: { "session_id": "s_91c", "position_s": 1830 }
দুইটা জিনিস খেয়াল করুন। প্রথমত, 2 GB এর file টা আমাদের app server এর ভেতর দিয়ে যায় না। Upload API শুধু একটা pre-signed URL দেয়। এটা object storage এর একটা বিশেষ link, যেটা কিছুক্ষণের জন্য শুধু এই একটা file লেখার অনুমতি দেয়। অ্যাপ সেই link এ সরাসরি file পাঠায়। ফলে আমাদের server গুলো GB ভর্তি upload সামলাতে গিয়ে আটকে থাকে না।
দ্বিতীয়ত, file টা যায় 5 MB এর টুকরো করে। একে বলে resumable upload। মাঝপথে network কেটে গেলে creator কে পুরো 2 GB আবার পাঠাতে হয় না। শুধু যে টুকরোটা অসম্পূর্ণ ছিলো, সেখান থেকে আবার শুরু হয়।
আর দেখার সময় video এর আসল টুকরোগুলো এই API থেকে আসে না। API শুধু manifest_url দেয়। বাকিটা player সরাসরি CDN থেকে নেয়। সেটা আমরা ০৬ নম্বর প্রশ্নে খুলে দেখবো।
Data model: কোন data কোথায় থাকবে
“দেখো” তে দুই রকম data আছে। এদের স্বভাব একদম আলাদা, তাই এরা আলাদা জায়গায় থাকে।
| Data | উদাহরণ | কোথায় থাকে | কেন |
|---|---|---|---|
| Metadata | title, status, view_count | SQL database, video_id দিয়ে shard করা (সেশন ০৫), সাথে Redis cache (সেশন ০৪) | ছোট, ঘনঘন পড়া হয়, query লাগে |
| Video file | raw file, segment, manifest | Object storage | বিশাল, একবার লেখা হয়, বদলায় না |
Object storage আমরা সেশন ২৩ এ Pastebin এর জন্য, আর সেশন ২৫ এ ছবির জন্য দেখেছি। মনে করিয়ে দিই: এটা বিশাল file রাখার service (যেমন Amazon S3), যেখানে প্রতিটা file একটা key দিয়ে রাখা আর পড়া যায়, জায়গা প্রায় অসীম, আর প্রতিটা file এর কয়েকটা কপি থাকে। Video এর জন্য এটাই সবচেয়ে স্বাভাবিক জায়গা।
-- Metadata: SQL database, video_id দিয়ে shard করা (সেশন ০৫)
CREATE TABLE videos (
video_id VARCHAR(16) PRIMARY KEY, -- 'v_8f3k2'
creator_id VARCHAR(16) NOT NULL,
title TEXT NOT NULL, -- 'ফেরা'
duration_s INT, -- 2700
status VARCHAR(12) NOT NULL, -- UPLOADING, PROCESSING, READY, FAILED
manifest_path TEXT, -- 'hls/v_8f3k2/master.m3u8'
view_count BIGINT DEFAULT 0, -- কয়েক সেকেন্ড পিছিয়ে থাকতে পারে
publish_at TIMESTAMP, -- 'ফেরা': ঈদের রাত 9টা
created_at TIMESTAMP NOT NULL
);
-- আসল file: object storage এ, key দিয়ে রাখা
raw/v_8f3k2/original.mp4 1.8 GB
hls/v_8f3k2/master.m3u8 1 KB
hls/v_8f3k2/720p/index.m3u8 14 KB
hls/v_8f3k2/720p/seg_00001.ts 2.25 MB (3 Mbps × 6 s ÷ 8)
০৪ পুরো system টা এক নজরে কেমন দেখায়? (high-level design)
নাবিলা এবার whiteboard এ ফিরে গেলো। Requirement থেকে সে জানে, system এ দুইটা আলাদা পথ আছে। একটা লেখার পথ (upload), যেটা দিনে মাত্র ১,০০০ বার চলে। আরেকটা পড়ার পথ (দেখা), যেটা ঈদের রাতে ২০ লাখ মানুষ একসাথে ব্যবহার করে।
দুই পথে কী কী হয়, এক নজরে দেখে নিন:
- লেখার পথ (১ থেকে ৪): Creator Upload API থেকে URL নিয়ে file পাঠান। File পৌঁছালে queue তে একটা job যায় (সেশন ০৮)। Worker রা job তুলে video কে নানা quality তে বানিয়ে storage এ রাখে, আর database এ status
READYলিখে দেয়। - পড়ার পথ (৫ আর ৬): দর্শক আগে Play API থেকে নাটকের তথ্য আর manifest এর ঠিকানা নেন। এটা ছোট একটা request, বেশিরভাগ সময় Redis cache থেকেই উত্তর আসে। তারপর player CDN থেকে video এর টুকরোগুলো একটা একটা করে আনে।
লেখার পথে গতির চেয়ে নির্ভরযোগ্যতা জরুরি, তাই সেখানে queue, retry আর ধীরস্থির worker। পড়ার পথে গতিই সব, তাই সেখানে cache আর CDN। একই system এর দুই অংশে দুই রকম নিয়ম চালানো যায়, কারণ পথ দুটো একে অন্যের উপর নির্ভর করে না। এদের একমাত্র মিলনস্থল object storage।
এবার এই ছবির চারটা কঠিন অংশ একটা একটা করে খুলে দেখবো। এগুলোই case study এর deep dive।
০৫ Upload হওয়া video দেখার উপযোগী হয় কীভাবে? (upload pipeline, transcoding)
Raw file কেন সরাসরি দেখানো যায় না
‘ফেরা’ এর editor শুভ ভাই export করা file টা upload করলেন: ৪৫ মিনিট, 1080p, প্রায় 8 Mbps। এই file টাই কি দর্শককে পাঠিয়ে দেওয়া যায়? তিনটা কারণে যায় না।
- Bitrate বেশি: সিলেটের গ্রামে নাবিলার খালার phone এ ইন্টারনেটের গতি অনেক সময় 1 Mbps এর কাছাকাছি। 8 Mbps এর video সেখানে প্রতি কয়েক সেকেন্ডে আটকে যাবে।
- Format মেলে না: Editing software যে format এ file বানায়, সব phone বা TV সেটা চালাতে পারে না। Video কে ছোট করে রাখার নিয়মকে বলে codec (যেমন H.264)। সব device এ চলে, এমন codec এ নতুন করে বানাতে হয়।
- একটা বড় file: পুরো 2 GB একটা file হলে, দর্শক মাঝখান থেকে দেখতে চাইলে বা network বদলালে মানিয়ে নেওয়ার কোনো উপায় থাকে না।
তাই raw file থেকে নতুন করে কয়েকটা version বানাতে হয়। একটা video কে অন্য codec, resolution বা bitrate এ নতুন করে encode করার কাজকে বলে transcoding। প্রতিটা version কে বলে একটা rendition। “দেখো” প্রতিটা video থেকে পাঁচটা rendition বানায়: 1080p, 720p, 480p, 360p আর 240p।
Upload থেকে READY পর্যন্ত: upload pipeline
পুরো পথটাকে বলে upload pipeline। শুভ ভাই upload চাপার পর থেকে ‘ফেরা’ দর্শকের কাছে পৌঁছানো পর্যন্ত ছয়টা ধাপ:
তিন নম্বর ধাপটা এই pipeline এর প্রাণ। Upload শেষ হওয়ামাত্র Upload API একটা job queue তে রেখে দেয়, আর creator কে সাথে সাথে “পেয়েছি” জানায়। ভারী কাজটা হয় পরে, worker দের হাতে। এটা ঠিক সেশন ০৮ এর asynchronous processing। Job retry, worker pool এর আকার আর timeout এর খুঁটিনাটি সেশন ০৯ এ আছে।
দেড় ঘণ্টার কাজ বারো মিনিটে: টুকরো করে transcoding
Transcoding ধীর কাজ। ধরুন একটা worker এ সব rendition বানাতে video এর দৈর্ঘ্যের দ্বিগুণ সময় লাগে। তাহলে ৪৫ মিনিটের ‘ফেরা’ তে লাগবে দেড় ঘণ্টা। কিন্তু video টাকে ছোট টুকরো করে আলাদা worker এ দিলে সব টুকরো একসাথে তৈরি হতে পারে:
টুকরো করার আরেকটা লাভ আছে। কোনো worker মাঝপথে crash করলে শুধু তার ৫ মিনিটের টুকরোটা আবার করতে হয়, পুরো নাটক নয়। আর প্রতিটা টুকরোর output এর নাম আগে থেকেই ঠিক করা (যেমন 720p/part_04.ts)। তাই একই টুকরো দুইবার transcode হলেও একই file আবার লেখা হয়, ভুল কিছু তৈরি হয় না। এটাই সেশন ০৮ এর idempotency।
Transcoding যত দ্রুতই হোক, শূন্য সেকেন্ডে হয় না। তাই ‘ফেরা’ ঈদের তিন দিন আগেই upload করা হয়, publish_at এ রাত ৯টা লিখে। এতে pipeline শান্তভাবে শেষ হয়, আর premiere এর আগে video টা সব edge এ পৌঁছে দেওয়ার সময়ও পাওয়া যায়।
০৬ দুর্বল network এও video না থেমে চলে কীভাবে? (adaptive bitrate, segment, manifest, HLS, DASH)
নাবিলার খালা থাকেন সিলেটের এক গ্রামে। ঈদের রাতে উঠানে সবাই মিলে phone এ ‘ফেরা’ দেখবেন। ঘরের ভেতরে signal ভালো, উঠানে গেলে কমে যায়। নাবিলা চায় না খালা একবারও spinner দেখুন।
Video কে ছোট টুকরো করা: segment
প্রথম কৌশল হলো প্রতিটা rendition কে ছোট ছোট টুকরো করে কাটা। প্রতিটা টুকরোকে বলে segment। “দেখো” প্রতিটা segment ৬ সেকেন্ডের রাখে। ৪৫ মিনিটের ‘ফেরা’ তে তাই প্রতিটা rendition এ ৪৫০টা segment হয়।
Player এখন পুরো নাটক একবারে নামায় না। সে segment #1 আনে, চালায়, ততক্ষণে #2 আর #3 আনতে থাকে। হাতে কয়েকটা segment জমা থাকে, যাকে বলে buffer। Network কিছুক্ষণের জন্য থমকে গেলেও buffer থেকে video চলতে থাকে।
কোন segment কোথায়: manifest
Player জানবে কীভাবে, কোন কোন quality আছে আর কোন segment এর পর কোনটা? এর জন্য থাকে একটা তালিকা, যাকে বলে manifest। Master manifest বলে কোন কোন rendition আছে। প্রতিটা rendition এর নিজের manifest বলে, তার segment গুলো কোন ক্রমে চালাতে হবে:
বাস্তবের একটা manifest দেখতে এমন। এটা HLS format এর, যার কথা একটু পরেই আসছে:
# master.m3u8: কোন কোন quality আছে #EXTM3U #EXT-X-STREAM-INF:BANDWIDTH=5000000,RESOLUTION=1920x1080 1080p/index.m3u8 #EXT-X-STREAM-INF:BANDWIDTH=3000000,RESOLUTION=1280x720 720p/index.m3u8 #EXT-X-STREAM-INF:BANDWIDTH=1200000,RESOLUTION=854x480 480p/index.m3u8 #EXT-X-STREAM-INF:BANDWIDTH=600000,RESOLUTION=640x360 360p/index.m3u8 #EXT-X-STREAM-INF:BANDWIDTH=200000,RESOLUTION=426x240 240p/index.m3u8 # 720p/index.m3u8: এই quality র segment গুলো, ক্রম অনুযায়ী #EXTM3U #EXT-X-VERSION:3 #EXT-X-TARGETDURATION:6 #EXT-X-MEDIA-SEQUENCE:1 #EXTINF:6.0, seg_00001.ts #EXTINF:6.0, seg_00002.ts ... #EXTINF:6.0, seg_00450.ts #EXT-X-ENDLIST
Network বুঝে quality বদলানো: adaptive bitrate
এবার আসল কৌশল। প্রতিটা segment নামাতে কত সময় লাগলো, player সেটা মাপে। তা থেকে সে বোঝে, এই মুহূর্তে network এর গতি কেমন। তারপর পরের segment টা সেই অনুযায়ী quality থেকে চায়। Network ভালো থাকলে 720p, দুর্বল হলে 360p। এই কৌশলের নাম adaptive bitrate streaming, সংক্ষেপে ABR।
খালার phone এ ঈদের রাতের প্রথম এক মিনিটে ঠিক এমনটাই ঘটলো:
খেয়াল করুন, quality নামে দ্রুত কিন্তু ওঠে ধীরে। কারণটা সহজ। Network দুর্বল হলে quality না নামালে buffer খালি হয়ে spinner চলে আসে। আবার signal একটু ভালো হতেই 1080p এ লাফ দেওয়াও বিপদ। পরের মুহূর্তে signal আবার পড়ে গেলে বড় segment টা সময়মতো আসে না, আর video আটকে যায়। তাই player সাবধানে এক ধাপ এক ধাপ করে ওঠে।
HLS আর DASH: দুইটা প্রচলিত নিয়ম
Segment আর manifest কোন format এ হবে, তার দুইটা প্রচলিত নিয়ম আছে:
| বিষয় | HLS (HTTP Live Streaming) | DASH (Dynamic Adaptive Streaming over HTTP) |
|---|---|---|
| কে বানিয়েছে | Apple | MPEG, একটা আন্তর্জাতিক standard |
| Manifest file | .m3u8 | .mpd (XML) |
| কোথায় চলে | iPhone আর Safari তে নিজে থেকেই; অন্য জায়গায় player library দিয়ে | Android, Smart TV আর browser এ player library দিয়ে |
দুটোর মূল ধারণা একই: ছোট segment, একটা manifest, আর player নিজেই quality বেছে নেয়। আজকাল CMAF নামের একটা format দিয়ে একই segment file দুই নিয়মেই চালানো যায়। তাই “দেখো” segment একবারই বানায়, শুধু দুই রকম manifest লেখে।
HLS আর DASH এর segment গুলো সাধারণ HTTP file, ঠিক একটা ছবির মতো। তাই CDN এগুলো অন্য যেকোনো file এর মতোই cache করতে পারে। Streaming এর জন্য আলাদা কোনো বিশেষ server লাগে না। এই একটা সুবিধার জন্যই পরের প্রশ্নের CDN কৌশল এত সহজে কাজ করে।
০৭ ২০ লাখ মানুষকে একসাথে video পাঠাবো কোথা থেকে? (CDN, popular বনাম long-tail)
সেশন ০৬ এ আমরা CDN দেখেছি। মনে করিয়ে দিই: edge হলো দর্শকের কাছাকাছি বসানো cache server, আর origin হলো যেখানে আসল file থাকে। আমাদের origin হলো object storage।
এখানে সুখবর হলো, ‘ফেরা’ আকারে ছোট। পাঁচটা rendition মিলিয়ে পুরো নাটক মাত্র প্রায় 3.4 GB (10 Mbps × 2,700 সেকেন্ড ÷ 8)। ২০ লাখ দর্শক এই একই 3.4 GB এর segment গুলোই বারবার চাইছেন। তাই প্রতিটা edge এ পুরো নাটকটা অনায়াসে রাখা যায়। তখন প্রায় ৯৯% request edge এই শেষ হয়ে যায়।
তিন স্তরের CDN
- Edge, ISP এর ভেতরে: বড় video কোম্পানিগুলো নিজের cache server সরাসরি ইন্টারনেট সেবাদাতা প্রতিষ্ঠানের (ISP) ভেতরে বসায়। Netflix এই ব্যবস্থার নাম দিয়েছে Open Connect। “দেখো” ও দেশের বড় ISP গুলোর সাথে চুক্তি করে তাদের ভেতরে cache রাখে। ফলে segment দর্শকের ISP থেকেই চলে যায়। Data কে লম্বা পথ পাড়ি দিতে হয় না, আর egress এর খরচও অনেক কমে।
- Origin shield: Edge আর origin এর মাঝে একটা মধ্যবর্তী cache স্তর। সব edge এর miss প্রথমে এখানে আসে। দশটা edge একই segment না পেলে origin এ দশবার যেতে হয় না। Shield একবার এনে সবাইকে দিয়ে দেয়।
- Origin: Object storage। এখানে সব video এর সব segment আছে, কিন্তু খুব কম request ই এত দূর পৌঁছায়।
জনপ্রিয় বনাম long-tail video
সব video তো ‘ফেরা’ এর মতো জনপ্রিয় নয়। “দেখো” তে কয়েক হাজার নাটক আছে। তার মধ্যে ২০১৫ সালের এমন নাটকও আছে, যেটা দিনে তিনজন দেখেন। সব নাটকের সব segment সব edge এ রাখার জায়গা নেই, দরকারও নেই।
Video platform এ view এর ছবিটা প্রায় সবসময় এমন হয়। অল্প কিছু video পায় বেশিরভাগ view। আর লম্বা একটা লেজ জুড়ে থাকে হাজার হাজার video, যাদের প্রত্যেকের view খুব কম। এই লেজকে বলে long tail। দুই দলের জন্য কৌশলও দুই রকম:
| বিষয় | জনপ্রিয় video (‘ফেরা’) | Long-tail video (২০১৫ এর নাটক) |
|---|---|---|
| কোথা থেকে যায় | Edge থেকে | Shield বা origin থেকে |
| কখন cache হয় | Premiere এর আগেই push করা হয় | কেউ চাইলে তখন cache হয়, পরে মুছে যায় |
| প্রথম segment আসার সময় | ~10-20 ms | কয়েকশো ms পর্যন্ত |
রাত ৯টা ০০ মিনিট ০০ সেকেন্ডের বিপদ
একটা বিপদ এখনো বাকি। রাত ঠিক ৯টায় ২০ লাখ মানুষ একসাথে play চাপবেন। সবাই চাইবেন একই file: ‘ফেরা’ এর segment #1। কোনো edge এ সেটা তখনো না থাকলে সব miss একসাথে origin এর দিকে ছুটবে। এটা সেশন ০৪ এর cache stampede, শুধু অনেক বড় আকারে।
এর দুইটা সমাধান, আর “দেখো” দুটোই ব্যবহার করে:
- আগে থেকে পৌঁছে দেওয়া (pre-warm): রাত ৮টার মধ্যেই ‘ফেরা’ এর সব segment সব edge এ push করে রাখা হয়। ৯টায় কেউ চাওয়ার আগেই cache ভর্তি।
- একই miss একবার (request coalescing): তবু কোনো edge এ segment না থাকলে, প্রথম request টাই শুধু origin এ যায়। একই segment এর বাকি request গুলো কয়েক millisecond অপেক্ষা করে, আর ঐ একই উত্তর পায়।
Edge এ HIT মানে দ্রুত video, আর origin এ শান্তি। ISP এর ভেতরে HIT মানে তার চেয়েও বেশি: data দেশের বাইরের বা শহরের বাইরের লম্বা পথ পাড়ি দেয় না, তাই bandwidth এর খরচও কমে। Video platform এর design এর বড় অংশই হলো এই প্রশ্নের উত্তর: কোন byte কোথায় আগে থেকে রেখে দেবো।
০৮ সেকেন্ডে হাজার হাজার view এলে গুনবো কীভাবে? (view counter at scale)
সহজ উপায়, আর সেটা কেন ভাঙে
প্রথমে ঠিক করতে হবে, একটা “view” মানে কী। কেউ play চেপে দুই সেকেন্ড পর বন্ধ করলে কি সেটা view? “দেখো” ঠিক করলো, কেউ টানা ৩০ সেকেন্ড দেখলে তবেই একটা view গোনা হবে।
সবচেয়ে সহজ উপায় হলো, প্রতিটা view এ database এ একটা update চালানো:
-- প্রতিটা view এ একবার করে চলে UPDATE videos SET view_count = view_count + 1 WHERE video_id = 'v_8f3k2';
কম traffic এ এটা দিব্যি চলে। কিন্তু ২ নম্বর প্রশ্নের হিসাব মনে করুন। রাত ৯টার পরের দশ মিনিটে ২০ লাখ মানুষ ‘ফেরা’ চালু করেন। মানে সেকেন্ডে প্রায় ৩,৩৩৩টা update, আর সবগুলো একই row তে। একটা row একবারে একটাই transaction বদলাতে পারে। বাকিরা lock এর জন্য লাইনে দাঁড়ায়।
সেশন ০৫ এ এর নাম শিখেছিলাম: hot key। Shard বাড়িয়েও লাভ নেই, কারণ ‘ফেরা’ এর row থাকে একটাই shard এ। পুরো চাপ সেই একটা shard এর উপরেই পড়ে।
সমাধান: আগে জমানো, পরে একবারে লেখা
মূল কৌশল হলো প্রতিটা view আলাদা করে না লিখে, কয়েক সেকেন্ডের view জমিয়ে একবারে লেখা:
- ৩০ সেকেন্ড দেখা হলে player একটা ছোট view event পাঠায়।
- Event টা Kafka তে যায়। Kafka একটা লম্বা খাতার মতো: event গুলো আসার ক্রমে লেখা থাকে, আর অনেক reader একসাথে পড়তে পারে। Kafka আর event-driven design এর বিস্তারিত সেশন ১০ এ।
- কয়েকটা aggregator process event গুলো পড়ে। প্রত্যেকে ৫ সেকেন্ড ধরে memory তে গোনে: ‘ফেরা’ +১৬,৬৬৫, অন্য নাটক +১২।
- ৫ সেকেন্ড পর প্রতিটা aggregator প্রতিটা video এর জন্য database এ একটাই update চালায়।
ফলে ৩,৩৩৩টা write এর জায়গায় প্রতি ৫ সেকেন্ডে কয়েকটা write হয়। দর্শক যে সংখ্যা দেখেন, সেটা Redis cache থেকে আসে, আর কয়েক সেকেন্ড পুরোনো থাকে। Requirement এ আমরা এটা আগেই মেনে নিয়েছিলাম। সেশন ২৫ এ like গোনার সময়ও ঠিক এই কৌশলটাই দেখেছিলাম, এখানে শুধু সংখ্যাটা অনেক বড়।
একটা ছোট ফাঁদ আছে। Kafka তে event গুলোকে video_id দিয়ে ভাগ করলে ‘ফেরা’ এর সব event একটাই partition এ (Kafka topic এর একটা ভাগ, সেশন ১০) যাবে। সেই partition আর তার aggregator আবার hot হয়ে যাবে। তাই event গুলো session_id দিয়ে ছড়িয়ে দেওয়া হয়। প্রত্যেক aggregator ‘ফেরা’ এর একটা অংশ গোনে, আর database এ সবার যোগফল জমা হয়।
দুইটা আলাদা গণনা
শেষ কথা। Screen এ দেখানো সংখ্যাটা একটু পিছিয়ে থাকলে ক্ষতি নেই। কিন্তু মাস শেষে production house কে view অনুযায়ী টাকা দিতে হলে প্রতিটা view নির্ভুল হওয়া চাই। Bot দিয়ে বানানো ভুয়া view বাদ দিতে হয়। একই session থেকে আসা duplicate event একবারই গুনতে হয় (idempotency, সেশন ০৮)।
তাই “দেখো” দুইটা গণনা রাখে। দ্রুত গণনা চলে aggregator দিয়ে, শুধু দেখানোর জন্য। আর Kafka তে জমা সব event থেকে রাতে একটা আলাদা job নির্ভুল হিসাব করে, টাকার জন্য।
View count এর মতো সংখ্যা দুই রকম কাজে লাগে। দর্শককে দেখানোর জন্য দ্রুত আর মোটামুটি ঠিক সংখ্যাই যথেষ্ট। টাকা দেওয়ার জন্য লাগে ধীর কিন্তু নির্ভুল সংখ্যা। দুটো কাজের জন্য দুটো পথ রাখলে কোনোটাতেই ছাড় দিতে হয় না।
০৯ Design টা কোথায় চাপে পড়ে, আর কী ছাড় দিলাম? (bottlenecks ও trade-offs)
পুরো ছবি
চারটা deep dive জোড়া লাগালে “দেখো” এর পুরো architecture এমন দাঁড়ায়:
কোথায় চাপ পড়ে, আর কী দিয়ে সামলালাম
| চাপের জায়গা | কী হতে পারতো | কী দিয়ে সামলালাম |
|---|---|---|
| রাত ৯টায় 3 Tbps egress | Origin আর তার network বসে যেতো | ISP এর ভেতরে edge, ৯৯% HIT |
| ৯টা ০০ মিনিটে segment #1 | সব miss একসাথে origin এ | Pre-warm আর request coalescing |
| দুর্বল mobile network | বারবার spinner | ছোট segment আর ABR |
| ৪৫ মিনিটের transcoding | Premiere এর আগে video ready না | টুকরো করে অনেক worker এ, আর আগেভাগে upload |
| ‘ফেরা’ এর metadata, সেকেন্ডে হাজারো read | একটা DB row এ hot key | Redis cache (সেশন ০৪) |
| ‘ফেরা’ এর view count | একটা row এ সেকেন্ডে ৩,৩৩৩ write | Kafka আর aggregator দিয়ে জমিয়ে লেখা |
এই design আমাদের যা দিলো
- 3 Tbps সামলানো যায়: প্রায় সব segment দর্শকের কাছের edge থেকে যায়, origin এ আসে শুধু miss।
- দুর্বল network এও video চলে: ABR প্রতি ৬ সেকেন্ডে quality ঠিক করে নেয়, তাই spinner খুব কম দেখা যায়।
- Upload আর দেখা একে অন্যকে আটকায় না: transcoding এর ভারী কাজ queue আর worker এ আলাদা চলে।
- View গোনা database কে বসিয়ে দেয় না: ৩,৩৩৩টা write এর বদলে প্রতি ৫ সেকেন্ডে একটা write।
- Video হারায় না: object storage নিজেই প্রতিটা file এর একাধিক copy রাখে।
Trade-off গুলো
- Storage দ্বিগুণের বেশি: raw 1.8 GB এর পাশে আরো 2.25 GB rendition রাখতে হয়। মসৃণ playback পেতে বাড়তি জায়গা লাগে।
- Upload এর পরেই দেখা যায় না: transcoding শেষ হতে কয়েক মিনিট লাগে। তাই premiere এর video আগেভাগে upload করতে হয়।
- View count একটু পিছিয়ে থাকে: দর্শক যে সংখ্যা দেখেন, সেটা কয়েক সেকেন্ড পুরোনো (eventual consistency)।
- Bandwidth ই সবচেয়ে বড় খরচ: ঈদের এক রাতের egress (প্রায় $68,000) সারা বছরে জমানো 1.5 PB video এক মাস রাখার খরচের (প্রায় $30,000) দ্বিগুণের বেশি।
- চালানোর মতো অংশ অনেক: queue, worker, Kafka, aggregator, CDN চুক্তি; প্রতিটা আলাদাভাবে monitor করতে হয়।
ঈদের রাত, ৯টা বেজে ৩ মিনিট
নাবিলা অফিসের বড় screen এর সামনে বসে আছে। Dashboard এ একসাথে দর্শক ১৯ লাখ ৬০ হাজার। Edge এর hit rate ৯৮.৭%। Origin এর graph টা প্রায় সমতল, যেন কিছুই হচ্ছে না। ফাহিম ভাই পেছন থেকে চায়ের কাপ এগিয়ে দিলেন। ঠিক তখন phone এ খালার message এলো: “নাটকটা খুব সুন্দর হইছে। উঠানে বসেও একবারও আটকায় নাই।” নাবিলা এবার নিশ্চিন্তে চায়ে চুমুক দিলো।
১০ মগজে প্রেশার দিন
আগে নিজে ভাবুন। তারপর দেখুন: সবাই যেভাবে ভাবে, কেন সেটা অসম্পূর্ণ, আর আসল insight টা কোথায়।
উত্তর দেখুন আগে নিজে ভাবুন
সবাই যেভাবে ভাবে
“প্রথমে একটা load balancer আঁকবো, তার পেছনে কয়েকটা app server, একটা database, আর video রাখার জন্য storage। তারপর scale এর জন্য cache আর CDN যোগ করবো।”
এখানে কোনো box ভুল নয়। কিন্তু শুরুটা ভুল জায়গা থেকে।
যে জায়গাটা যোগ করা দরকার
প্রথম পাঁচ মিনিট যায় প্রশ্ন করায়। কোন feature লাগবে আর কোনটা লাগবে না? কতজন user, কতগুলো upload? কোন অংশ ধীর হলে চলে? তারপর মোটামুটি হিসাব। এই সেশনে হিসাবটাই দেখিয়ে দিয়েছে যে আসল চাপ upload এ নয়, egress এ: ভেতরে আসে 167 Mbps, বাইরে যায় 3 Tbps। এই সংখ্যা জানার পর CDN আর ABR কে design এর কেন্দ্রে রাখার পক্ষে আপনার কাছে শক্ত যুক্তি থাকে।
Box আঁকার আগে requirement আর হিসাব। হিসাবটাই বলে দেয়, interview এর বাকি সময় কোন অংশে খরচ করতে হবে।
উত্তর দেখুন আগে নিজে ভাবুন
সবাই যেভাবে ভাবে
“ছোট file তাড়াতাড়ি load হয়। তাই video তাড়াতাড়ি শুরু হয়।”
কথাটা ঠিক, কিন্তু segment এর আসল কাজের অর্ধেকও এতে আসেনি।
যে জায়গাটা যোগ করা দরকার
Segment এর সীমানাই হলো quality বদলানোর সুযোগ। পুরো 2 GB একটা file হলে network দুর্বল হওয়ার পর quality নামানোর কোনো উপায় থাকে না। ৬ সেকেন্ডের segment হলে player প্রতি ৬ সেকেন্ডে নতুন করে সিদ্ধান্ত নিতে পারে। তাছাড়া ছোট segment CDN এ সাধারণ file এর মতো cache হয়। মাঝখান থেকে দেখা শুরু করলে শুধু সেই জায়গার segment আনলেই চলে।
Segment এর দৈর্ঘ্যেও একটা trade-off আছে। খুব ছোট (১ সেকেন্ড) হলে request অনেক বেড়ে যায়, আর manifest লম্বা হয়। খুব বড় (৩০ সেকেন্ড) হলে quality বদলাতে দেরি হয়, আর video শুরু হতেও দেরি হয়। ২ থেকে ১০ সেকেন্ডের মধ্যে বেশিরভাগ platform এর পছন্দ।
Segment শুধু ছোট file নয়। প্রতিটা segment এর সীমানায় player quality বদলানোর সুযোগ পায়। আর CDN প্রতিটা segment কে আলাদা file হিসেবে cache করে।
উত্তর দেখুন আগে নিজে ভাবুন
সবাই যেভাবে ভাবে
“Redis এর একটা node সেকেন্ডে লাখখানেক INCR সামলাতে পারে। ৩,৩৩৩ তো তার কাছে কিছুই না। তাই Kafka আর aggregator বাড়তি ঝামেলা।”
আংশিক ঠিক। শুধু screen এ সংখ্যা দেখানোর জন্য Redis এর একটা counter এই scale এ সত্যিই কাজ করবে।
যে জায়গাটা যোগ করা দরকার
প্রথমত, ঐ counter একটাই key, তাই সেটা থাকে একটাই Redis node এ। আরো বড় কোনো event এ, বা প্রতি ৩০ সেকেন্ডের heartbeat ও গুনতে চাইলে (২০ লাখ ÷ ৩০ ≈ সেকেন্ডে ৬৬,৬৬৭) সেই node টাই আবার hot key হয়ে যায়। দ্বিতীয়ত, Redis এর counter শুধু একটা সংখ্যা। কোন view bot এর, কোনটা duplicate, সেটা পরে আর যাচাই করা যায় না। টাকার হিসাবের জন্য প্রতিটা event এর রেকর্ড লাগে। Kafka সেই রেকর্ড রাখে, আর দরকার হলে আবার শুরু থেকে পড়ে হিসাব মেলানো যায়।
দেখানোর জন্য Redis এর counter চলতে পারে। কিন্তু সত্যের উৎস হলো event এর রেকর্ড। Counter হারালে event থেকে আবার বানানো যায়, উল্টোটা যায় না।
১১ যে টার্মগুলো শিখলাম
| টার্ম | মানে |
|---|---|
| Functional requirement | System কী কী করবে: upload, দেখা, view count। |
| Non-functional requirement | System কতটা ভালোভাবে করবে: কত দ্রুত, কত মানুষের জন্য, কতটা নির্ভরযোগ্যভাবে। |
| Back-of-envelope estimation | কাগজে মোটামুটি হিসাব করে storage, bandwidth আর request এর মাপ বের করা। নিখুঁত সংখ্যা নয়, ঠিক মাপটা জানাই লক্ষ্য। |
| Bitrate | Video এর প্রতি সেকেন্ডে কত bit data লাগে, যেমন 720p তে প্রায় 3 Mbps। |
| Egress | Server থেকে বাইরে যাওয়া data। Cloud এ এর জন্য প্রতি GB টাকা দিতে হয়। |
| Object storage | বিশাল file রাখার service (যেমন S3)। প্রতিটা file একটা key দিয়ে রাখা হয়, আর নিজেই একাধিক copy রাখে। |
| Pre-signed URL | Object storage এর একটা অস্থায়ী link, যেটা দিয়ে অ্যাপ সরাসরি একটা নির্দিষ্ট file লিখতে বা পড়তে পারে। |
| Resumable upload | File টুকরো করে পাঠানো, যাতে network কাটলে শুধু বাকি অংশটা পাঠাতে হয়। |
| Codec | Video ছোট করে রাখার নিয়ম, যেমন H.264। |
| Transcoding | একটা video কে অন্য codec, resolution বা bitrate এ নতুন করে encode করা। |
| Rendition | একই video এর একটা নির্দিষ্ট quality এর version, যেমন 720p। |
| Upload pipeline | Upload থেকে READY পর্যন্ত ধাপগুলো: জমা নেওয়া, transcode, segment বানানো, প্রকাশ করা। |
| Segment | Video এর ছোট একটা টুকরো, সাধারণত ২ থেকে ১০ সেকেন্ডের। |
| Manifest | কোন quality আছে আর কোন segment কোন ক্রমে চলবে, তার তালিকা। |
| Adaptive bitrate (ABR) | Network এর গতি মেপে player প্রতিটা segment এর quality নিজেই বেছে নেয়। |
| HLS | Apple এর বানানো streaming নিয়ম, manifest হয় .m3u8 file। |
| DASH | আন্তর্জাতিক standard streaming নিয়ম, manifest হয় .mpd file। |
| Origin shield | Edge আর origin এর মাঝের cache স্তর, যেটা সব edge এর miss এক করে origin কে বাঁচায়। |
| Long tail | কম জনপ্রিয় হাজার হাজার video, যাদের প্রত্যেকের view কম কিন্তু সংখ্যায় অনেক। |
| Pre-warm | চাওয়ার আগেই জনপ্রিয় content edge এ পৌঁছে দেওয়া। |
| Request coalescing | একই জিনিসের অনেকগুলো miss এক করে origin এ একবারই যাওয়া। |
| Aggregator | Event গুলো কিছুক্ষণ memory তে জমিয়ে যোগ করে, তারপর database এ একবারে লেখে। |
১২ শর্ট সামারি
- Case study শুরু হয় requirement আর back-of-envelope estimation দিয়ে। “দেখো” এর হিসাব দেখিয়েছে, upload এ ভেতরে আসে মাত্র 167 Mbps কিন্তু ঈদের রাতে egress 3 Tbps, তাই design এর কেন্দ্র হলো দেখার পথ।
- Upload হওয়া video queue আর worker দিয়ে asynchronous ভাবে transcode হয়। একটা raw file থেকে পাঁচটা rendition তৈরি হয়, প্রতিটা ৬ সেকেন্ডের segment এ কাটা হয়, আর manifest এ তালিকা থাকে।
- Adaptive bitrate এ player প্রতিটা segment এর আগে network মেপে quality বেছে নেয়। HLS আর DASH এই কাজের দুইটা প্রচলিত নিয়ম, আর segment সাধারণ HTTP file বলে CDN সহজেই cache করে।
- জনপ্রিয় video premiere এর আগেই ISP এর ভেতরের edge এ পৌঁছে যায়, long-tail video আসে shield আর origin থেকে। আর view গোনা হয় Kafka আর aggregator দিয়ে জমিয়ে, যাতে একটা row এ হাজারো write না পড়ে।
১৩ মনে রাখুন
- Box আঁকার আগে requirement আর হিসাব। হিসাবটাই বলে দেয় design এর কোন অংশ সবচেয়ে কঠিন।
- Video platform এ সবচেয়ে বড় খরচ bandwidth। তাই প্রতিটা byte দর্শকের যত কাছ থেকে পাঠানো যায়, ততই ভালো।
- বড় file database এ নয়, object storage এ। Database এ থাকে শুধু metadata আর file এর ঠিকানা।
- ভারী কাজ queue তে দিন, আর টুকরো করে একসাথে করুন। দেড় ঘণ্টার transcoding তখন বারো মিনিটে নেমে আসে।
- প্রতিটা segment এর সীমানায় quality বদলানো যায়। ছোট segment আর ABR মিলে দুর্বল network এও video চালু রাখে।
- জনপ্রিয় content আগে থেকে edge এ রাখুন। Long-tail content চাওয়া হলে তখন আনুন।
- Hot counter কে প্রতিবার লিখবেন না, জমিয়ে লিখুন। দেখানোর সংখ্যা আর টাকার সংখ্যা আলাদা পথে গুনুন।