পাঠ ০২ · ৫১-এর মধ্যে · মডিউল ১
Home / Courses / System Design / ব্যাক-অফ-দ্য-এনভেলপ এস্টিমেশন

ব্যাক-অফ-দ্য-এনভেলপ এস্টিমেশন

Back-of-the-envelope capacity estimation
৯ মিনিট পড়া মধ্যম · Intermediate Python কোডসহ সম্পূর্ণ বাংলায়

এই পাঠে যা শিখবেন

  • ট্রাফিক (QPS), স্টোরেজ, ব্যান্ডউইথ ও ক্যাশ সাইজ হিসাব করার সাধারণ পদ্ধতি
  • প্রয়োজনীয় ইউনিট রেফারেন্স — KB/MB/GB/TB/PB এবং দিন/মাসে সেকেন্ডের সংখ্যা
  • একটি সম্পূর্ণ ওয়ার্কড উদাহরণ — ১ কোটি DAU ফটো-শেয়ারিং অ্যাপের বার্ষিক স্টোরেজ হিসাব
  • কেন রিড:রাইট রেশিও ও পিক ফ্যাক্টর জিজ্ঞেস করা প্রতিটি এস্টিমেশনের অপরিহার্য অংশ

১ · কেন এস্টিমেশন করি

L01-এ দেখেছি নন-ফাংশনাল রিকোয়ারমেন্টই আর্কিটেকচার ঠিক করে দেয়। কিন্তু "স্কেলেবল হতে হবে" বললে যথেষ্ট নয় — কত ইউজার, প্রতি সেকেন্ডে কত রিকোয়েস্ট, কত ডেটা জমবে — এই সংখ্যাগুলো না জানলে আপনি জানবেন না একটি সার্ভার যথেষ্ট নাকি হাজারটা লাগবে, একটি ডেটাবেস যথেষ্ট নাকি শার্ডিং লাগবে (M4)। এস্টিমেশনের লক্ষ্য নিখুঁত সংখ্যা নয় — বরং সঠিক মাত্রা (order of magnitude) বোঝা, যাতে আলোচনা "নাকি এটা একটা ছোট স্ক্রিপ্ট" বনাম "নাকি এটা একটা গ্লোবাল ডিস্ট্রিবিউটেড সিস্টেম" পর্যায়ে সঠিক দিকে যায়।

মূল কথা

এস্টিমেশনের উদ্দেশ্য ক্যালকুলেটরের মতো নিখুঁত হওয়া নয় — বরং ৫ মিনিটে বলতে পারা "এটা প্রতি সেকেন্ডে কয়েক হাজার রিকোয়েস্টের সিস্টেম, নাকি কয়েক লাখের।" এই একটি সিদ্ধান্তই বাকি পুরো ডিজাইনের দিক ঠিক করে দেয়।

২ · প্রয়োজনীয় রেফারেন্স সংখ্যা

প্রতিটি এস্টিমেশনের ভিত্তি এই কয়েকটি সংখ্যা মুখস্থ থাকা দরকার —

সেকেন্ড/দিন
২৪ × ৬০ × ৬০ = ৮৬,৪০০
সেকেন্ড/মাস
৩০ দিন ধরে ≈ ২৫,৯২,০০০
স্টোরেজ ইউনিট
১ KB=১০³ B, ১ MB=১০⁶ B, ১ GB=১০⁹ B, ১ TB=১০¹² B, ১ PB=১০¹⁵ B

লক্ষ্য করুন — সহজ হিসাবের জন্য ১০৩৬Base-1000 আনুমানিকসঠিকভাবে ১ KB = ১০২৪ বাইট (2¹⁰), কিন্তু ব্যাক-অফ-দ্য-এনভেলপ হিসাবে ১০০০ ধরে নেওয়া যথেষ্ট নির্ভুল এবং মাথায় হিসাব করা সহজ করে। এর বদলে ১০০০-ভিত্তিক (decimal) ইউনিট ধরে নেওয়া হয় — এতে সামান্য পার্থক্য হলেও মাত্রার হিসাবে কোনো প্রভাব পড়ে না।

৩ · চারটি মূল হিসাব

ক) ট্রাফিক — QPS

$$QPS_{avg} = \frac{DAU \times \text{requests per user per day}}{86400}$$ পিক ট্রাফিক সবসময় গড়ের চেয়ে বেশি — সাধারণত ২x থেকে ৫x পিক ফ্যাক্টর ধরা হয় (নির্দিষ্ট ডোমেইনের উপর নির্ভর করে): $$QPS_{peak} = QPS_{avg} \times \text{peak factor}$$

খ) স্টোরেজ

$$\text{Storage} = \text{records per day} \times \text{avg record size} \times \text{retention period}$$ রিটেনশন পিরিয়ড (কতদিন ডেটা রাখতে হবে) সবসময় জিজ্ঞেস করা জরুরি — বছরের পর বছর রাখতে হলে সংখ্যাটা দ্রুত পেটাবাইটে চলে যায়।

গ) ব্যান্ডউইথ

$$\text{Bandwidth} = QPS \times \text{avg payload size}$$ এটি নেটওয়ার্ক ইনফ্রাস্ট্রাকচার ও CDN (L20) প্রয়োজনীয়তা ঠিক করতে সাহায্য করে।

ঘ) ক্যাশ/মেমরি সাইজিং

সব ডেটা ক্যাশ করার দরকার নেই — বাস্তবে প্রতিদিনের সবচেয়ে "হট" (ঘনঘন অ্যাক্সেস হওয়া) ডেটার একটি অংশ, প্রায়ই দৈনিক ডেটার ~২০%, ক্যাশ করলেই বেশিরভাগ রিকোয়েস্ট ক্যাশ থেকে সার্ভ হয়ে যায় (এটি L19-এ বিস্তারিত দেখব) — $$\text{Cache size} \approx 0.2 \times \text{daily data volume}$$

সবসময় জিজ্ঞেস করুন

রিড:রাইট রেশিও — সোশ্যাল মিডিয়া অ্যাপে সাধারণত প্রতি রাইটের জন্য ১০০:১ বা তার বেশি রিড হয় (মানুষ পোস্ট করার চেয়ে অনেক বেশি স্ক্রল করে)। এই রেশিও না জানলে আপনি ভুল দিকে (শুধু রাইট থ্রুপুট বা শুধু রিড ক্যাপাসিটি) অপ্টিমাইজ করবেন।

DAU + ব্যবহার Input assumptions QPS Traffic স্টোরেজ Storage ব্যান্ডউইথ Bandwidth ক্যাশ সাইজ (~২০%) Cache sizing
ইনপুট অনুমান থেকে চারটি মূল এস্টিমেশন — এই চারটি সংখ্যাই বাকি পুরো আর্কিটেকচার আলোচনার ভিত্তি।

৪ · সম্পূর্ণ ওয়ার্কড উদাহরণ — ফটো-শেয়ারিং অ্যাপ

ধরুন একটি ফটো-শেয়ারিং অ্যাপের ১ কোটি (10,000,000) DAU আছে, এবং প্রতিজন গড়ে প্রতিদিন ২টি ছবি আপলোড করে, প্রতিটি ছবির গড় সাইজ ২ MB। এক বছরে মোট কত স্টোরেজ লাগবে?

  • মোট ছবি/দিন = ১,০০,০০,০০০ × ২ = ২,০০,০০,০০০ (20,000,000)
  • স্টোরেজ/দিন = ২,০০,০০,০০০ × ২ MB = ৪,০০,০০,০০০ MB = ৪০,০০,০০০ MB → ৪০ TB/দিন
  • স্টোরেজ/বছর = ৪০ TB × ৩৬৫ = ১৪,৬০০ TB = ১৪.৬ PB/বছর
Python
dau = 10_000_000              # ১ কোটি DAU
photos_per_user_per_day = 2
avg_photo_size_mb = 2

photos_per_day = dau * photos_per_user_per_day
storage_per_day_mb = photos_per_day * avg_photo_size_mb
storage_per_day_tb = storage_per_day_mb / 1_000_000   # 1 TB = 10^6 MB

storage_per_year_tb = storage_per_day_tb * 365
storage_per_year_pb = storage_per_year_tb / 1_000      # 1 PB = 1000 TB

print(f"ছবি/দিন: {photos_per_day:,}")
print(f"স্টোরেজ/দিন: {storage_per_day_tb:,.1f} TB")
print(f"স্টোরেজ/বছর: {storage_per_year_tb:,.1f} TB = {storage_per_year_pb:,.2f} PB")

assert round(storage_per_day_tb, 1) == 40.0
assert round(storage_per_year_pb, 1) == 14.6

    
লক্ষ্য করুন — এখানে শুধু নতুন আপলোড হওয়া ছবির স্টোরেজ হিসাব করা হয়েছে, রেপ্লিকেশন (L16, সাধারণত ৩x) বা একাধিক থাম্বনেইল সাইজ ধরলে বাস্তব সংখ্যা আরও কয়েকগুণ বেশি হবে। এস্টিমেশনে সবসময় স্পষ্ট করে বলা উচিত কোন অনুমানগুলো ধরা হচ্ছে।
মূল কথা · Key takeaway

ব্যাক-অফ-দ্য-এনভেলপ এস্টিমেশন কোনো একবার করার কাজ নয় — প্রতিটি ডিজাইন সিদ্ধান্তের (ক্যাশ লাগবে কি না, শার্ডিং লাগবে কি না, কত সার্ভার লাগবে) পেছনে এই সংখ্যাগুলোই যুক্তি দেয়। L03-এ আমরা দেখব শুধু গড় সংখ্যা যথেষ্ট নয় — লেটেন্সির বিতরণ (percentiles) বোঝাও সমান জরুরি।

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।

প্র ০১ এস্টিমেশনে নিখুঁত সংখ্যার বদলে "মাত্রা" (order of magnitude) নিয়ে চিন্তা করা কেন যথেষ্ট, এমনকি ভালো?

কারণ ইনপুট অনুমানগুলোই (গড় ফাইল সাইজ, ইউজার প্রতি রিকোয়েস্ট) নিজেরাই আনুমানিক — বাস্তবে এগুলো ২০-৩০% এদিক-ওদিক হতেই পারে। কিন্তু সিদ্ধান্ত নেওয়ার জন্য গুরুত্বপূর্ণ হলো সিস্টেমটি হাজার QPS-এর নাকি লাখ QPS-এর — এই পার্থক্যেই ভিন্ন আর্কিটেকচার লাগে (একটি ডেটাবেস বনাম শার্ডেড ক্লাস্টার)। নিখুঁত দশমিক বিন্দু নিয়ে সময় নষ্ট করার চেয়ে সঠিক মাত্রা ধরে দ্রুত এগিয়ে যাওয়াই ব্যবহারিক।

প্র ০২ কেন সবসময় পিক QPS ধরে সার্ভার প্ল্যান করা হয়, গড় QPS ধরে নয় — এমনকি যদি সেটা বেশিরভাগ সময় ওভার-প্রভিশনিং মনে হয়?

কারণ ট্রাফিক সারাদিন সমানভাবে আসে না — সকাল-সন্ধ্যায় স্পাইক হয়। গড় ধরে ডিজাইন করলে সিস্টেম শুধু পিক আওয়ারেই ভেঙে পড়বে, যা সাধারণত সবচেয়ে গুরুত্বপূর্ণ সময় (বেশি ইউজার সক্রিয়)। সামান্য "অপচয়" (off-peak সময়ে বাড়তি ক্যাপাসিটি বসে থাকা) মেনে নেওয়া, পিক আওয়ারে সিস্টেম ডাউন হওয়ার চেয়ে অনেক ভালো ট্রেড-অফ — বিশেষ করে যেহেতু ক্লাউড অটো-স্কেলিং (M3) দিয়ে এই অপচয় অনেকটাই কমানো যায়।

প্র ০৩ রিড:রাইট রেশিও জানা কেন গুরুত্বপূর্ণ — এটি শুধু একটি সংখ্যা হলেও পুরো আর্কিটেকচারে এর প্রভাব কী?

রিড-হেভি সিস্টেমে (যেমন ১০০:১) ক্যাশিং (M5) ও রিড রেপ্লিকা (L16) সবচেয়ে বেশি লাভ দেয়, কারণ বেশিরভাগ রিকোয়েস্ট রিড। কিন্তু রাইট-হেভি সিস্টেমে (যেমন লগিং বা IoT সেন্সর ডেটা) ক্যাশিং তেমন সাহায্য করে না — বরং রাইট থ্রুপুট বাড়ানোই আসল চ্যালেঞ্জ, যার জন্য শার্ডিং (L17) বা ব্যাচ/স্ট্রিম রাইট প্যাটার্ন (L24) লাগে। একই সংখ্যার QPS হলেও রিড:রাইট রেশিও ভিন্ন হলে সম্পূর্ণ ভিন্ন আর্কিটেকচার সঠিক হতে পারে।

অনুশীলন

  1. হিসাব করুন: একটি ভিডিও-শেয়ারিং অ্যাপে ৫০ লক্ষ (5,000,000) DAU আছে, প্রতিজন গড়ে দিনে ১টি ভিডিও আপলোড করে, প্রতিটি ভিডিওর গড় সাইজ ৫০ MB। দৈনিক ও বার্ষিক স্টোরেজ (TB ও PB-এ) হাতে হিসাব করুন।

    ভিডিও/দিন = ৫০,০০,০০০। স্টোরেজ/দিন = ৫০,০০,০০০ × ৫০ MB = ২৫,০০,০০,০০০ MB = ২৫০ TB/দিন। স্টোরেজ/বছর = ২৫০ × ৩৬৫ = ৯১,২৫০ TB ≈ ৯১.২৫ PB/বছর। লক্ষ্য করুন — কম DAU হলেও বড় ফাইল সাইজের কারণে ভিডিও অ্যাপের স্টোরেজ চাহিদা ফটো অ্যাপের চেয়ে বহুগুণ বেশি (L48-এ ভিডিও স্ট্রিমিং কেস স্টাডিতে আরও গভীরে যাব)।

  2. হিসাব করুন: একই অ্যাপের ২ কোটি DAU এবং প্রতিজন গড়ে দিনে ৫০টি রিকোয়েস্ট করে (ভিউ+আপলোড মিলিয়ে), পিক ফ্যাক্টর ৩x। গড় ও পিক QPS হিসাব করুন এবং রিড:রাইট রেশিও ৫০:১ হলে গড় রিড QPS ও রাইট QPS আলাদা করে বের করুন।

    মোট রিকোয়েস্ট/দিন = ২,০০,০০,০০০ × ৫০ = ১০,০০,০০,০০,০০০। গড় QPS = ১০,০০,০০,০০,০০০ / ৮৬,৪০০ ≈ ১১,৫৭৪। পিক QPS (৩x) ≈ ৩৪,৭২২। রিড:রাইট = ৫০:১ মানে ৫১ ভাগের ৫০ ভাগ রিড — রাইট QPS ≈ ১১,৫৭৪ / ৫১ ≈ ২২৭, রিড QPS ≈ ১১,৫৭৪ − ২২৭ ≈ ১১,৩৪৭। এই বিভাজনই বলে দেয় কেন ক্যাশ ও রিড রেপ্লিকা এখানে সবচেয়ে বেশি কাজ করবে।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

আগের পাঠ
System Design কী এবং কেন গুরুত্বপূর্ণ