Fundamentalsপড়তে ১০ মিনিট লাগবে

লোড ব্যালান্সিং (Load Balancing)

কাজ ভাগ করে নেওয়া যাতে কোনো সার্ভার অতিরিক্ত চাপে না পড়ে
scope:বিল্ডিং ব্লক (Building Block)difficulty:বিগিনার-ইন্টারমিডিয়েট (Beginner-Intermediate)

লোড ব্যালান্সিং কী? (What is Load Balancing?)

কল্পনা করুন, একটি মুদি দোকানে ১০টি চেকআউট লেন আছে। ট্রাফিক নিয়ন্ত্রণ করার কেউ না থাকলে, সবাই লেন ১-এ ভিড় জমাবে এবং লেন ২-১০ খালি পড়ে থাকবে। একজন লোড ব্যাল্যান্সার হলেন সেই ব্যক্তি যিনি বলেন, "লেন ৩ খালি আছে!" এবং গ্রাহকদের সব লেনে সমানভাবে ভাগ করে দেন।

টেকনিক্যাল দিক থেকে, লোড ব্যাল্যান্সার ক্লায়েন্ট (ইউজার) এবং সার্ভারের মাঝখানে বসে। যখন কোনো রিকোয়েস্ট আসে, সে সিদ্ধান্ত নেয় কোন সার্ভার সেটা হ্যান্ডেল করবে। এর উদ্দেশ্য খুবই সহজ:

  • চাপ ভাগ করে দেওয়া (Spread the load) যাতে কোনো নির্দিষ্ট সার্ভার ওভারলোডেড না হয়ে যায়।
  • রিলায়াবিলিটি বাড়ানো (Improve reliability) — কোনো সার্ভার ডাউন হয়ে গেলে, লোড ব্যাল্যান্সার সেখানে ট্রাফিক পাঠানো বন্ধ করে দেয়।
  • থ্রুপুট বাড়ানো (Increase throughput) — একসাথে একাধিক সার্ভার পাশাপাশি কাজ করলে মোটের উপর দ্রুত ও বেশি কাজ সম্পন্ন করা যায়।

লোড ব্যাল্যান্সার বিভিন্ন লেভেলে ব্যবহার করা যেতে পারে: ইউজার এবং ওয়েব সার্ভারের মাঝে, ওয়েব সার্ভার এবং অ্যাপ্লিকেশন সার্ভারের মাঝে এবং অ্যাপ্লিকেশন সার্ভার ব্যবহার ও ডাটাবেসের মাঝে।

সমস্যা — সব ট্রাফিক একটি সার্ভারেই আসে
রিকোয়েস্ট ভাগ করে দিতে একটি লোড ব্যাল্যান্সার যোগ করুন

লোড ব্যালান্সিং অ্যালগরিদম (Load Balancing Algorithms)

পরবর্তী রিকোয়েস্ট কোন সার্ভারে যাবে লোড ব্যাল্যান্সার সেই সিদ্ধান্ত কীভাবে নেয়? এর জন্য বেশ কয়েকটি স্ট্র্যাটেজি রয়েছে:

রাউণ্ড রবিন (Round Robin) — সবচেয়ে সহজ। ক্রমানুসারে সার্ভারগুলোতে রিকোয়েস্ট পাঠায়: সার্ভার ১, সার্ভার ২, সার্ভার ৩, সার্ভার ১, সার্ভার ২, সার্ভার ৩... অনেকটা টেবিলের সবার মাঝে তাস বিলি করার মতো। এটি দারুণ কাজ করে যখন সব সার্ভারের ক্যাপাসিটি সমান থাকে এবং সব রিকোয়েস্টে প্রায় একই সময় লাগে।

ওয়েটেড রাউন্ড রবিন (Weighted Round Robin) — একই ধারণা, তবে নির্দিষ্ট কিছু সার্ভারকে বেশি বার সুযোগ দেওয়া হয়। সার্ভার ১ যদি সার্ভার ২-এর চেয়ে দ্বিগুণ শক্তিশালী হয়, তবে সেটিতে দ্বিগুণ পরিমাণ রিকোয়েস্ট পাঠানো হয়। অনেকটা দুর্বল প্লেয়ারদের ১টি তাস দেওয়ার বিপরীতে শক্তিশালী প্লেয়ারকে ২টি করে তাস দেওয়ার মতো।

লিস্ট কানেকশন (Least Connections) — বর্তমানে সবচেয়ে কম সংখ্যক রিকোয়েস্ট হ্যান্ডেল করা সার্ভারে রিকোয়েস্ট পাঠানো। এটি ধীরগতির রিকোয়েস্টগুলোতে ন্যাচারালভাবেই মানিয়ে নেয় — যদি সার্ভার ১ একটি বড় ফাইল আপলোড প্রসেস করার কারণে আটকে থাকে, তবে নতুন রিকোয়েস্টগুলো কম ব্যস্ত সার্ভারে যেতে থাকে।

আইপি হ্যাশ (IP Hash) — ক্লায়েন্টের আইপি (IP) অ্যাড্রেস হ্যাশ করে সিদ্ধান্ত নেওয়া হয় কোন সার্ভার ব্যবহার করতে হবে। একই ইউজার সবসময় একই সার্ভারেই রাউট হয়। এটি সেশন পারসিস্টেন্সের (Session persistence)-এর জন্য দারুণ (এ বিষয়ে পরে আরও আলোচনা করা হবে)। এটি কনসিস্টেন্ট হ্যাশিং-এর সাথে সম্পর্কিত একটি কৌশল ব্যবহার করে।

লিস্ট রেসপন্স টাইম (Least Response Time) — সেই সার্ভারটিতে রিকোয়েস্ট পাঠায় যার বর্তমান রেসপন্স টাইম সবচেয়ে ফাস্ট এবং যেখানে সবচেয়ে কম একটিভ কানেকশন রয়েছে। এটি বেশ স্মার্ট কিন্তু জটিল একটি পদ্ধতি।

র‍্যান্ডম (Random) — সম্পূর্ণ এলোমেলোভাবে একটি সার্ভার বেছে নেওয়া। বড় আকারের সার্ভার পুলে ব্যবহারের ক্ষেত্রে এটি বেশ চমকপ্রদ! পরিসংখ্যানগত দিক থেকে কোনো হিসেব না রেখেই এটি খুব ভালোভাবে ভারসাম্য বজায় রাখে।

রাউন্ড রবিন — ক্রমানুসারে রিকোয়েস্ট যায়
লিস্ট কানেকশন — সবচেয়ে কম ব্যস্ত সার্ভার বেছে নিন

পাইথন-এ লোড ব্যালান্সিং অ্যালগরিদম

import hashlib
from collections import defaultdict
class LoadBalancer:
def __init__(self, servers: list[str]):
self.servers = servers
self.rr_index = 0
self.connections = defaultdict(int) # server -> active count
def round_robin(self) -> str:
"""Cycle through servers in order."""
server = self.servers[self.rr_index % len(self.servers)]
self.rr_index += 1
return server
def least_connections(self) -> str:
"""Pick the server with the fewest active connections."""
return min(self.servers, key=lambda s: self.connections[s])
def ip_hash(self, client_ip: str) -> str:
"""Always route the same IP to the same server."""
hash_val = int(hashlib.md5(client_ip.encode()).hexdigest(), 16)
return self.servers[hash_val % len(self.servers)]
# Usage
lb = LoadBalancer(["server-1", "server-2", "server-3"])
# Round Robin: cycles 1 -> 2 -> 3 -> 1 -> 2...
for _ in range(5):
print(lb.round_robin())
# IP Hash: same IP always goes to same server
print(lb.ip_hash("192.168.1.42")) # Always "server-2"
print(lb.ip_hash("192.168.1.42")) # Always "server-2"
Output
server-1
server-2
server-3
server-1
server-2
server-2
server-2

লেয়ার ৪ বনাম লেয়ার ৭ লোড ব্যালান্সিং (Layer 4 vs Layer 7 Load Balancing)

লোড ব্যাল্যান্সার নেটওয়ার্ক স্ট্যাকের বিভিন্ন লেভেলের ওপর ভিত্তি করে কাজ করতে পারে। দুটি সবচেয়ে পপুলার হলো লেয়ার ৪ এবং লেয়ার ৭ (OSI মডেলের অংশ)।

লেয়ার ৪ (ট্রান্সপোর্ট লেয়ার / Transport Layer) — এটি আইপি ঠিকানা এবং TCP/UDP পোর্ট নাম্বারের ভিত্তিতে সিদ্ধান্ত নেয়। রিকোয়েস্টের ভেতর কী আছে তা এটি খতিয়ে দেখে না — আপনি কোনো ওয়েবপেজ লোড করছেন নাকি কোনো ভিডিও আপলোড দিচ্ছেন, তার কোনো ধারণাই এর নেই। এটি শুধু দেখে, "X আইপি থেকে ৪৪৩ পোর্টের জন্য ট্রাফিক আসছে", এবং সেটাকে রাউট করে। এটি বেশ ফাস্ট এবং ইফিসিয়েন্ট। কারণ একে কিছুই ডিক্রিপ্ট বা পার্স (Parse) করতে হয় না।

লেয়ার ৭ (অ্যাপ্লিকেশন লেয়ার / Application Layer) — এটি রিকোয়েস্টের ভেতরের কন্টেন্টের ভিত্তিতে সিদ্ধান্ত নেয়: ইউআরএল পাথ, হেডার্স, কুকিজ, HTTP মেথড, এমনকি রিকোয়েস্টের বডি পর্যন্ত। এটি অনেক বেশি স্মার্ট রাউটিং পদ্ধতি:

  • /api/* রিকোয়েস্টগুলো এপিআই সার্ভারে পাঠানো হয়
  • /images/* রিকোয়েস্টগুলো মিডিয়া সার্ভারে পাঠানো হয়
  • সেশন অ্যাফিনিটির (session affinity) জন্য কুকিজের ওপর ভিত্তি করে রাউট হয়
  • লোকালাইজেশনের জন্য Accept-Language হেডারের ওপর ভিত্তি করে রাউট হয়

লেয়ার ৭ তুলনামূলকভাবে ধীরগতির (যেহেতু এটি রিকোয়েস্ট পার্স করে), কিন্তু অনেক বেশি ফ্লেক্সিবল। বেশিরভাগ আধুনিক লোড ব্যাল্যান্সার, যেমন— Nginx, HAProxy এবং AWS ALB, লেয়ার ৭ সাপোর্ট করে।

হেলথ চেক (Health Checks)

কোনো ডেড সার্ভারে ট্রাফিক পাঠালে লোড ব্যাল্যান্সারের কোনো মূল্য থাকে না। এ কারণেই লোড ব্যাল্যান্সার প্রতিনিয়ত সার্ভারগুলোর হেলথ-চেক করতে থাকে।

হেলথ চেক দুই রকমের হয়:

  • প্যাসিভ হেলথ চেক (Passive health checks) — লোড ব্যাল্যান্সার সার্ভার থেকে আসা রেসপন্সগুলোকে মনিটর করে। কোনো সার্ভার এরর দিলে বা টাইমআউট হয়ে গেলে, তাকে আনহেলদি (Unhealthy) বলে চিহ্নিত করা হয় এবং পুল থেকে রিমুভ করে ফেলা হয়।
  • অ্যাক্টিভ হেলথ চেক (Active health checks) — লোড ব্যাল্যান্সার নিয়মিত প্রতিটা সার্ভারে পিং করে (যেমন: প্রতি ১০ সেকেন্ড পরপর GET /health দেয়)। কোনো সার্ভার নির্দিষ্ট সংখ্যক বার রেসপন্স করতে না পারলে, একে রোটেশন থেকে সরিয়ে দেওয়া হয়।

ফেইল করা সার্ভারটি যখন পুনরায় রিকভার করে, তখন পরবর্তী সাকসেসফুল হেলথ চেকে লোড ব্যাল্যান্সার তা বুঝতে পারে এবং আবার পুলে অ্যাড করে। পুরো প্রক্রিয়াটি অটোমেটিকভাবেই হয় — মাঝরাতে মানুষের কোনো হস্তক্ষেপের প্রয়োজন হয় না!

হেলথ চেক — ফেইলিউর থাকলে তা বুঝার ব্যবস্থা করুন
Note: হেলথ চেককে অনেকটা শিক্ষকের রোল কলের মতো বিবেচনা করুন। প্রতি ১০ সেকেন্ডে লোড ব্যাল্যান্সার প্রত্যেকটি সার্ভারের নাম ডাকে। "সার্ভার ১?" "প্রেজেন্ট স্যার!" "সার্ভার ২?" "ইয়েস স্যার!" "সার্ভার ৩?" *নীরবতা*... "সার্ভার ৩ অ্যাবসেন্ট — সবাই সার্ভার ১ এবং ২-এর কাছে যাও।"
Click chart to zoom
লোড ব্যাল্যান্সার কীভাবে প্রতিটি রিকোয়েস্ট রাউট করে: রিসিভ করা, হেলথ চেক করা, সার্ভার বেছে নেওয়া এবং রেসপন্স ফেরত দেওয়া

স্টিকি সেশন (Sticky Sessions)

কখনও কখনও আপনার প্রয়োজন হয় একজন নির্দিষ্ট ইউজারের রিকোয়েস্ট সবসময় একই সার্ভারে যাওয়ার। হতে পারে সেই সার্ভারটি ইন্টারনাল মেমরিতে ইউজারের সেশন ডাটা স্টোর করে। কিংবা আপনি অংশে অংশে একটি বড় ফাইল আপলোড দিচ্ছেন। একেই বলা হয় স্টিকি সেশন (বা সেশন অ্যাফিনিটি / Session affinity)।

লোড ব্যাল্যান্সার এই কাজটি করে থাকে:

  • প্রথম রেসপন্সের সময় একটি কুকি সেট করে (যেমন, SERVERID=server-2)
  • ইউজারদের নির্দিষ্ট সার্ভারে রাউট করতে আইপি হ্যাশিং ব্যবহার করে
  • রিকোয়েস্টের সাথে আসা একটি সেশন আইডি (Session ID) পড়ে রিকোয়েস্ট রাউট করে

এর অসুবিধা কী? স্টিকি সেশন স্কেলেবিলিটি কমিয়ে দেয়। যদি কোনো নির্দিষ্ট সার্ভারে অনেক বেশি হেভি-ওয়েট ইউজারের ট্র্যাফিক চলে যায়, সার্ভারটি ওভারলোডেড হয়ে পড়বে; যেখানে অন্যান্য সার্ভারগুলো হয়তো অলস বসে থাকবে। এটি ফেইলওভার পরিস্থিতিকে আরও কঠিন করে তোলে — ওই সার্ভারটি ডাউন হয়ে গেলে, সকল ইউজারের সেশন স্টেট হারিয়ে যাবে।

এর চেয়ে ভালো সমাধান হলো সার্ভারগুলোকে স্টেটলেস (Stateless) বানানো এবং সেশনের ডাটাগুলো এক্সটার্নাল কোনো স্টোরে (যেমন Redis, ডাটাবেস) স্টোর করে রাখা। তাহলে কোনো স্টিকি সেশন ব্যবহার করার দরকারই হবে না।

হার্ডওয়্যার বনাম সফটওয়্যার লোড ব্যাল্যান্সার (Hardware vs Software Load Balancers)

হার্ডওয়্যার লোড ব্যাল্যান্সারগুলো (Hardware load balancers) (যেমন F5, Citrix) হলো ডেডিকেটেড ফিজিক্যাল ডিভাইস (Physical devices)। এরা দারুন ফাস্ট এবং একসাথে মিলিয়ন মিলিয়ন রিকোয়েস্ট হ্যান্ডেল করতে পারে। তবে, এগুলোর দাম অনেক বেশি ($১০,০০০-$১০০,০০০+) এবং কনফিগারেশন করা বেশ কঠিন।

সফটওয়্যার লোড ব্যাল্যান্সারগুলো (Software load balancers) (যেমন Nginx, HAProxy, Envoy, AWS ELB/ALB) সাধারণ সার্ভারে রান করানো যায়। এগুলো সস্তা এবং ফ্লেক্সিবল, আপডেট করাও সহজ। আধুনিক কোম্পানিগুলো সফটওয়্যার লোড ব্যাল্যান্সারই বেশি ব্যবহার করে।

ক্লাউড প্রোভাইডাররাও ম্যানেজড লোড ব্যালান্সিং সেবা দেয়:

  • AWS ELB/ALB/NLB — ইলাস্টিক/অ্যাডভান্সড/নেটওয়ার্ক লোড ব্যাল্যান্সার (Elastic/Application/Network Load Balancer)
  • Google Cloud Load Balancing — রিজিওন (Region)-জুড়ে গ্লোবাল লোড ব্যালান্সিং (Global load balancing)
  • Azure Load Balancer — মাইক্রোসফটের লোড ব্যাল্যান্সার সেবা

এই ম্যানেজড সার্ভিসগুলো (Managed solutions) আপনার হয়ে স্কেলিং, হেলথ চেক এবং SSL টার্মিনেশন হ্যান্ডেল করে — যার ফলে আপনাকে একটি কম বিষয় নিয়ে চিন্তা করতে হয়।

Note: ইন্টারভিউ টিপস: মনে রাখবেন, লোড ব্যাল্যান্সার নিজেও কিন্তু একটি সিঙ্গেল পয়েন্ট অফ ফেইলিউর (Single Point of Failure) হতে পারে! প্রোডাকশনে সাধারণত দুটি লোড ব্যাল্যান্সারকে একটিভ-প্যাসিভ বা একটিভ-একটিভ সেটআপে ব্যবহার করা হয়। যদি প্রথমটি ফেইল করে, তবে দ্বিতীয়টি VRRP-এর মতো প্রোটোকল ব্যবহার করে একটি ভার্চুয়াল আইপির (VIP) মাধ্যমে নিয়ন্ত্রণ নিয়ে নেয়।

Key Metrics

রাউণ্ড রবিন রাউটিং (Round Robin routing)
স্রেফ কাউন্টার বৃদ্ধি করে
\(O(1)\) \(O(1)\)
লিস্ট কানেকশন্স রাউটিং (Least Connections routing)
সর্বনিম্ন (min) খুঁজে বের করতে হয়; হিপ (heap) ব্যবহার করা যেতে পারে
\(O(n)\) বা \(O(\log n)\) \(O(n)\)
আইপি হ্যাশ রাউটিং (IP Hash routing)
হ্যাশ + মডুলো (Hash + modulo)
\(O(1)\) \(O(1)\)
L4 LB ল্যাটেন্সি ওভারহেড
ভিতরের ইনফরমেশন পার্স করার দরকার নেই
~০.০১ ms —
L7 LB ল্যাটেন্সি ওভারহেড
HTTP পার্স করতে হয়
~০.১-১ ms —
হেলথ চেক ইন্টারভাল
কনফিগারযোগ্য (Configurable)
৫-৩০ sec —

ছোট কুইজ

কোন লোড ব্যালান্সিং অ্যালগরিদম নিশ্চিত করে যে একই ইউজারের রিকোয়েস্ট সবসময় একই সার্ভারে যাবে?

পড়া চালিয়ে যান