What is System Design?

Why is it important?

সিস্টেম ডিজাইন ছাড়া একটি বড় প্রজেক্ট তৈরি করা অসম্ভব। এর প্রধান কারণগুলো হলো:

সিস্টেম ডিজাইনের প্রধান দুটি ধরন

সিস্টেম ডিজাইনকে মূলত দুই ভাগে ভাগ করা যায়:

alt text

Key Components

একটি সিস্টেমে সাধারণত নিচের জিনিসগুলো নিয়ে কাজ করতে হয়:

Scalability

আপনার সিস্টেমে ইউজারের সংখ্যা বাড়লে সিস্টেমটি সেই চাপ নিতে পারছে কি না, সেটাই হলো স্কেলেবিলিটি।

ধরুন, আপনি একটি চায়ের দোকান দিলেন যেখানে ১ জন কর্মচারী প্রতিদিন ১০০ কাপ চা বানাতে পারে। হঠাৎ একদিন ১০০০ জন কাস্টমার চলে এলো। এখন ওই ১ জন কর্মচারী কিন্তু হিমশিম খাবে, কাস্টমাররা চা পাবে না। সিস্টেমের ক্ষেত্রেও তাই। যখন আপনার অ্যাপে ট্রাফিক (ইউজার) বাড়ে, তখন সেই লোড সামলানোর জন্য সিস্টেমের ক্ষমতা বাড়ানোকেই বলে Scaling।

Types of Scaling

স্কেলিং প্রধানত দুই প্রকার। সিস্টেম ডিজাইনে এই দুটি পার্থক্য বোঝা সবচেয়ে জরুরি:

Vertical Scaling (Scaling Up)

  1. সুবিধা: ম্যানেজ করা সহজ।
  2. অসুবিধা: একটি নির্দিষ্ট সীমার পর হার্ডওয়্যার আর বাড়ানো যায় না (Limit আছে) এবং সার্ভার নষ্ট হলে পুরো সিস্টেম বন্ধ হয়ে যায়।

কখন ব্যবহার করবেন?

Pros (সুবিধা):

Cons (অসুবিধা):

Horizontal Scaling (Scaling Out)

যখন একটি বিশাল শক্তিশালী সার্ভারও ট্রাফিকের চাপ নিতে পারে না বা যখন আপনি চান না যে একটি সার্ভার নষ্ট হলে পুরো সিস্টেম বন্ধ হয়ে যাক, তখনই Horizontal Scaling প্রয়োজন হয়।

এখানে একটি শক্তিশালী সার্ভার কেনার বদলে আমরা অনেকগুলো সাধারণ (Commodity) সার্ভার যোগ করি। গুগল, নেটফ্লিক্স বা অ্যামাজনের মতো কোম্পানিগুলো এভাবেই কোটি কোটি রিকোয়েস্ট হ্যান্ডেল করে। একটি Load Balancer এই সার্ভারগুলোর মধ্যে কাজ ভাগ করে দেয়।

  1. সুবিধা:
    • কোনো লিমিট নেই: আপনি যত খুশি সার্ভার যোগ করতে পারেন। ক্লাউড প্রোভাইডারদের (যেমন AWS, Google Cloud) কারণে এটি প্রায় অসীম।
    • ফল্ট টলারেন্স (Fault Tolerance): একটি সার্ভার নষ্ট হলেও অন্যগুলো কাজ চালিয়ে যায়। কোনো ‘Single Point of Failure’ থাকে না।
    • সাশ্রয়ী: একটি দানবীয় সার্ভার কেনার চেয়ে অনেকগুলো ছোট সার্ভার কেনা অনেক সময় সস্তা হয়।
    • ভৌগোলিক সুবিধা: ইউজারের কাছাকাছি লোকেশনে সার্ভার রাখা যায়, ফলে অ্যাপ ফাস্ট চলে।
  2. অসুবিধা:
    • জটিলতা: অনেকগুলো সার্ভার একসাথে ম্যানেজ করা এবং সেগুলোর মধ্যে যোগাযোগ রক্ষা করা বেশ কঠিন।
    • ডাটা কনসিস্টেন্সি: সব সার্ভারে যেন একই তথ্য থাকে (Synchronization), সেটা নিশ্চিত করা চ্যালেঞ্জিং।
    • নেটওয়ার্ক ওভারহেড: সার্ভারগুলো একে অপরের সাথে কথা বলার সময় কিছুটা সময় (Latency) নষ্ট হয়।
    • স্টেটলেসনেস: এর জন্য আপনার অ্যাপ্লিকেশনকে অবশ্যই ‘Stateless’ হতে হয়।

কখন ব্যবহার করবেন?

Pros (সুবিধা):

Cons (অসুবিধা):

আপনি কখন বুঝবেন কোনটা দরকার? নিচের ৩টি প্রশ্ন নিজেকে করলেই উত্তর পেয়ে যাবেন:

  1. আপনার সিস্টেম কি ডাউন হওয়া একদমই মানা? যদি উত্তর হয় “হ্যাঁ”, তবে Horizontal এ যান।
  2. আপনার সার্ভারের CPU/RAM কি ৯০% এর বেশি ইউজ হচ্ছে? যদি বাজেট থাকে এবং দ্রুত সমাধান চান, তবে সাময়িকভাবে Vertical করুন।
  3. ফিউচার প্ল্যান কি? যদি মনে করেন ইউজার অনেক বাড়বে, তবে শুরু থেকেই অ্যাপকে Horizontal স্কেলিংয়ের উপযোগী (Stateless) করে বানান।

এদের সাথে আর কী কী কানেক্টেড? স্কেলিং করার সময় আপনাকে নিচের বিষয়গুলো নিয়ে ভাবতে হবে:

alt text

Scalability কিসের ওপর নির্ভর করে? (Key Factors)

একটি সিস্টেম কতটা স্কেলেবল হবে তা প্রধানত ৩টি জিনিসের ওপর নির্ভর করে:

  1. Load (লোড): ইউজার সংখ্যা কত? প্রতি সেকেন্ডে কতগুলো রিকোয়েস্ট (Requests per second - RPS) আসছে? ডাটাবেসে কত ডাটা রিড/রাইট হচ্ছে?
  2. Performance (পারফরম্যান্স): লোড বাড়লে সিস্টেম কি স্লো হয়ে যাচ্ছে? ল্যাটেন্সি (Latency) কেমন?
  3. Resources (রিসোর্স): আপনার কাছে কতটুকু CPU, RAM, Network Bandwidth এবং স্টোরেজ আছে।

Scalability-র সাথে অন্যান্য জিনিসের কানেকশন

স্কেলেবিলিটি একা কাজ করে না, এর সাথে আরও কিছু কম্পোনেন্ট যুক্ত থাকে:

স্কেলেবিলিটি পরিমাপ (Measuring Scalability)

স্কেল করার আগে, এটি কীভাবে পরিমাপ করতে হয় তা বোঝা জরুরি। আপনি যা পরিমাপ করতে পারেন না, তা উন্নত করাও সম্ভব নয়। সুনির্দিষ্ট সংখ্যা বা ডেটা ছাড়া “আমাদের স্কেল করা দরকার” এর মতো অস্পষ্ট বক্তব্যের কোনো ভিত্তি থাকে না।

স্কেলেবিলিটি সাধারণত নিচের বিষয়গুলোর ওপর ভিত্তি করে মূল্যায়ন করা হয়:

লোড মেট্রিক্স (Load Metrics)

মেট্রিক (Metric) বর্ণনা (Description) উদাহরণ (Example)
রিকোয়েস্ট পার সেকেন্ড (RPS) সিস্টেমটি প্রতি সেকেন্ডে কতগুলো API কল হ্যান্ডেল করতে পারে ১০,০০০ RPS
কনকারেন্ট ইউজার (Concurrent users) একই সময়ে কতজন ব্যবহারকারী সক্রিয় আছেন ৫০,০০০ জন
ডেটা ভলিউম (Data volume) প্রসেস করা বা স্টোর করা ডেটার পরিমাণ ১০ TB স্টোরেজ
থ্রুপুট (Throughput) প্রতি ইউনিট সময়ে কতটুকু ডেটা ট্রান্সফার হচ্ছে ১ GB/s
কুয়েরি রেট (Query rate) প্রতি সেকেন্ডে ডাটাবেস কুয়েরির সংখ্যা ৫০,০০০ QPS
মেসেজ রেট (Message rate) কিউ (Queue) এর মাধ্যমে প্রসেস হওয়া মেসেজের সংখ্যা ১০০,০০০ msg/s

লোডের বিপরীতে পারফরম্যান্স (Performance Under Load)

একটি সিস্টেম তখনই ভালোভাবে স্কেল করে যখন লোড বাড়ার সাথে সাথে এটি গ্রহণযোগ্য পারফরম্যান্স বজায় রাখতে পারে। ভালো এবং খারাপ স্কেলিংয়ের পার্থক্য নিচে দেখানো হলো:

লোড বৃদ্ধি (Load Increase) রেসপন্স টাইম (Response Time) আচরণ (Behavior) এর অর্থ কী (What It Means)
১x (বেজলাইন) ৫০ms বেজলাইন স্বাভাবিক কার্যক্রম
২x ৫৫ms চমৎকার সাব-লিনিয়ার গ্রোথ, ক্যাশিং ভালো কাজ করছে
৫x ৭০ms ভালো সিস্টেম দক্ষতার সাথে লোড সামলাচ্ছে
১০x ১৫০ms গ্রহণযোগ্য লিনিয়ার ডিগ্রেডেশন, পারফরম্যান্স অনুমানযোগ্য
১০x ৫০০ms উদ্বেগজনক সুপার-লিনিয়ার ডিগ্রেডেশন, বটলনেক তৈরি হচ্ছে
১০x টাইমআউট (Timeout) সংকটপূর্ণ সিস্টেম ভেঙে পড়ার পর্যায়ে আছে

মূল লক্ষ্য হলো লোড বাড়লেও পারফরম্যান্স তুলনামূলক স্থিতিশীল রাখা। আদর্শভাবে, আপনি Linear বা Sublinear Degradation চাইবেন, যেখানে লোড দ্বিগুণ হলেও রেসপন্স টাইম দ্বিগুণ হবে না। যখন রেসপন্স টাইম হঠাৎ বেড়ে যায় বা সিস্টেম টাইমআউট হতে শুরু করে, তখন বুঝতে হবে আপনি স্কেলেবিলিটির শেষ সীমায় পৌঁছেছেন।

Bottlenecks সিস্টেমের যে অংশটি সবচেয়ে দুর্বল এবং যার কারণে পুরো সিস্টেমের স্পিড কমে যায়, তাকেই Bottleneck বলে।

সিস্টেম ডিজাইনে Bottlenecks কোথায় কোথায় হয়?

সিস্টেমের মূলত এই জায়গাগুলোতে বোটলনেক দেখা দেয়:

Database Bottleneck (সবচেয়ে কমন) আপনার অ্যাপ্লিকেশন সার্ভার হয়তো সেকেন্ডে ১০,০০০ রিকোয়েস্ট নিতে পারে, কিন্তু আপনার ডাটাবেস সেকেন্ডে মাত্র ৫০০টি তথ্য সেভ করতে পারে। এখানে ডাটাবেস হলো বোটলনেক।

CPU/RAM Bottleneck আপনার কোড যদি খুব জটিল হয় (যেমন: ভিডিও প্রসেসিং বা ভারী ক্যালকুলেশন), তবে প্রসেসর বা র‍্যামের কারণে সিস্টেম স্লো হয়ে যেতে পারে।

Network Bottleneck সার্ভার এবং ডাটাবেসের মধ্যে যদি ডাটা আদান-প্রদানের রাস্তা (Bandwidth) সরু হয়, তবে ডাটা আসতে দেরি হবে। একে বলে নেটওয়ার্ক ল্যাটেন্সি।

Disk I/O Bottleneck যদি হার্ডডিস্ক থেকে ডাটা পড়তে অনেক সময় লাগে (পুরানো HDD ব্যবহার করলে এমন হয়)।

Bottleneck কীভাবে খুঁজে বের করবেন?

ইঞ্জিনিয়াররা সাধারণত কিছু জিনিস মনিটর করে বোটলনেক খুঁজে পান:

Single Point of Failure (SPOF)

Single Point of Failure (SPOF) কথাটির অর্থ হলো পুরো সিস্টেমের এমন একটি দুর্বল জায়গা বা অংশ, যা নষ্ট হয়ে গেলে পুরো সিস্টেমটিই অকেজো হয়ে যায়।

সহজ কথায়, আপনার সিস্টেমে যদি এমন কোনো “একমাত্র” কম্পোনেন্ট থাকে যার ওপর পুরো সিস্টেম নির্ভর করছে এবং সেটির কোনো ব্যাকআপ নেই, তবে তাকেই SPOF বলা হয়। এটি সিস্টেম ডিজাইনের একটি বড় ঝুঁকি।

  1. বাস্তব উদাহরণ (Real-life Example) ধরুন, আপনার বাসায় একটিই পানির লাইন আছে এবং সেটি দিয়ে পুরো বাসায় পানি আসে। কোনো কারণে যদি সেই পাইপটি ফেটে যায়, তবে পুরো বাসার পানি বন্ধ হয়ে যাবে। এখানে ওই একটি পাইপ হলো Single Point of Failure।

কিন্তু যদি আপনার বাসায় দুটি আলাদা পানির লাইন থাকতো, তবে একটি নষ্ট হলেও অন্যটি দিয়ে কাজ চলতো। সেখানে কোনো SPOF থাকতো না।

  1. সিস্টেম ডিজাইনে SPOF এর উদাহরণ সিস্টেম ডিজাইনে সাধারণত নিচের জায়গাগুলোতে SPOF হতে পারে:
  1. কীভাবে SPOF দূর করা যায়? (Redundancy) SPOF দূর করার একমাত্র উপায় হলো Redundancy (রেডান্ডান্সি) বা ব্যাকআপ রাখা।

কেন এটি গুরুত্বপূর্ণ? সিস্টেম ডিজাইনের লক্ষ্য হলো High Availability (সিস্টেম যেন সবসময় সচল থাকে)। যদি সিস্টেমে একটিও SPOF থাকে, তবে সেই সিস্টেমকে কখনোই ১০০% নির্ভরযোগ্য বলা যাবে না।

Stateless মানে কী? (The Concept)

state মানে হলো "অবস্থা" বা "তথ্য"। আর Stateless মানে হলো এমন এক অবস্থা যেখানে সার্ভার ইউজারের আগের কোনো তথ্য বা "ইতিহাস" নিজের কাছে জমা রাখে না।

প্রতিটি রিকোয়েস্ট (Request) সার্ভারের কাছে একদম নতুন হিসেবে আসে। সার্ভার শুধু জানে বর্তমান রিকোয়েস্টে কী চাওয়া হয়েছে, এর আগে ইউজার কী করেছিল তা সে মনে রাখে না।

একটি বাস্তব উদাহরণ:

  1. Stateless Architecture কেন দরকার? হরিজন্টাল স্কেলিংয়ের সময় আমাদের অনেকগুলো সার্ভার থাকে (Server A, Server B, Server C)।

যদি আপনার সিস্টেম Stateful হয় (মানে ইউজার ১-এর তথ্য শুধু Server A মনে রাখে), আর কোনো কারণে পরের রিকোয়েস্টটি Server B-তে যায়, তখন Server B ওই ইউজারকে চিনবে না। ইউজারকে বলবে “আবার লগইন করো”। এটা ইউজারের জন্য বিরক্তিকর।

কিন্তু সিস্টেম যদি Stateless হয়, তবে ইউজার যে সার্ভারেই যাক না কেন, রিকোয়েস্টের সাথেই প্রয়োজনীয় সব তথ্য (যেমন Token) পাঠিয়ে দেওয়া হয়। ফলে যেকোনো সার্ভার তাকে চিনতে পারে।

  1. Stateless Architecture-এর গঠন সিস্টেমকে Stateless রাখার জন্য আমরা তথ্যগুলো সার্ভারের নিজের হার্ডড্রাইভ বা র‍্যামে না রেখে আলাদা জায়গায় রাখি:

alt text

Scaling Different Components

একটি আধুনিক অ্যাপ্লিকেশন শুধু একটি কোডবেস নয়, এর ভেতরে অনেকগুলো স্তর বা Tier থাকে (যেমন: ওয়েব সার্ভার, ডাটাবেস, ইমেজ প্রসেসর)। একেক স্তরের কাজের ধরন একেক রকম, তাই তাদের Scaling Strategy-ও আলাদা হয়।

  1. ওয়েব বা অ্যাপ্লিকেশন লেয়ার (The Stateless Tier) এটি হলো আপনার সিস্টেমের সবচেয়ে সহজ অংশ স্কেল করার জন্য।

alt text

  1. ডাটাবেস লেয়ার (The Stateful Tier) এটি স্কেল করা সবচেয়ে কঠিন। কারণ এখানে “State” বা ডাটা থাকে।

alt text

Read Replicas বা Master-Slave Architecture

বেশিরভাগ জনপ্রিয় অ্যাপ্লিকেশনে (যেমন: Facebook, Twitter) Read-to-Write Ratio থাকে ১০০:১ বা তারও বেশি। অর্থাৎ ১০০ জন মানুষ যখন নিউজফিড দেখছে (Read), তখন হয়তো মাত্র ১ জন একটা পোস্ট করছে (Write)।

এখন যদি আপনার সব ইউজার একটিমাত্র ডাটাবেস সার্ভারে গিয়ে ডাটা পড়তে শুরু করে, তবে ডাটাবেসের CPU এবং RAM জ্যাম হয়ে যাবে। ফলে কেউ নতুন পোস্ট করতে গেলে সেটা অনেক স্লো হয়ে যাবে। এই বোটলনেক দূর করার জন্যই রিড রিপ্লিকা ব্যবহার করা হয়।

  1. কীভাবে কাজ করে? (Mechanism) এখানে কাজগুলোকে দুই ভাগে ভাগ করা হয়:
  1. কী কারণে এটি গুরুত্বপূর্ণ? (Key Benefits)

একটি বড় চ্যালেঞ্জ: Replication Lag (ল্যাটেন্সি)

এটি ইন্টারভিউতে খুব বেশি জিজ্ঞেস করা হয়। মাস্টার থেকে রিপ্লিকাতে ডাটা কপি হতে কয়েক মিলিসেকেন্ড সময় লাগে।

  1. কখন এটি ব্যবহার করবেন না? যদি আপনার অ্যাপটি এমন হয় যেখানে ডাটা পড়ার চেয়ে লেখার চাপ বেশি (যেমন: শেয়ার বাজারের রিয়েল-টাইম প্রাইস আপডেট বা কোনো সেন্সর ডাটা ট্র্যাকিং), তবে সেখানে Read Replicas খুব একটা কাজে আসবে না। সেখানে আপনাকে Sharding করতে হবে।