Load Balancing
Load Balancer কী?
ধরুন একটা bank এ ১০টা counter আছে, কিন্তু সবাই একটা counter এ গিয়ে দাঁড়াচ্ছে। বাকি ৯টা counter খালি পড়ে আছে। এটা কি বোকামি না?
Load Balancer হলো সেই manager যে দরজায় দাঁড়িয়ে বলে — "আপনি counter 3 এ যান, আপনি counter 7 এ যান।" প্রতিটা counter সমান কাজ পায়, কেউ overwhelmed না।
সেরকমভাবে, যখন লক্ষ লক্ষ user আপনার app এ request পাঠায়, Load Balancer সেই request গুলো বিভিন্ন server এ distribute করে দেয়।
DEFINITION
Load Balancer হলো এমন একটি component যা incoming network traffic কে multiple servers এর মধ্যে distribute করে। এটা নিশ্চিত করে যে কোনো একটা server অতিরিক্ত load এ overwhelmed না হয়।
Load Balancer এর Benefits
- High Availability: একটা server down হলেও app চলতে থাকে
- Scalability: নতুন server যোগ করে traffic handle করা সহজ
- Performance: Load সমান ভাগ হওয়ায় response time কমে
- Zero-downtime deployment: একে একে server update করা যায়, app বন্ধ হয় না
L4 vs L7 Load Balancing
LAYER 4 Transport Layer
শুধু IP address + Port দেখে routing করে। HTTP content দেখে না। অনেক fast কারণ packet inspect করে না। কিন্তু content-aware না — URL বা header দেখে decision নিতে পারে না।
LAYER 7 Application Layer
পুরো HTTP request পড়তে পারে — URL, headers, cookies, body। Smart routing করতে পারে। যেমন /api/* → API servers, /static/* → CDN।
| Feature | Layer 4 | Layer 7 |
|---|---|---|
| OSI Layer | Transport (L4) | Application (L7) |
| Speed | অনেক Fast | Slightly Slower |
| Content Awareness | না — IP+Port only | হ্যাঁ — URL, Header, Cookie |
| SSL Termination | না | হ্যাঁ |
| Path-based Routing | না | হ্যাঁ |
| Best For | Ultra-low latency, TCP/UDP | HTTP apps, Microservices |
| Tools | AWS NLB, HAProxy (TCP mode) | Nginx, AWS ALB, Traefik |
Load Balancing Algorithms
Round Robin
সব server কে sequentially request পাঠাও। Server 1 → Server 2 → Server 3 → Server 1 → ... Simple এবং equal distribution। সব server একই capacity হলে ভালো।
Weighted Round Robin
Server এর capacity অনুযায়ী weight assign করুন। Server A (weight=3) → Server B (weight=1)। বড় server বেশি traffic পাবেন। Mixed hardware এ ভালো।
Least Connections
যে server এর active connections সবচেয়ে কম, তাকে request পাঠাও। Long-lived connections (WebSocket, database) এর জন্য সবচেয়ে ভালো। Variable request duration handle করে।
IP Hash
Client এর IP address hash করে always same server এ পাঠাও। Session persistence এর জন্য দরকার। Same user সবসময় same server এ যাবেন।
Random
Randomly একটা server select করুন। Simple কিন্তু uneven distribution হতে পারে। Production এ rarely ব্যবহার হয়।
| Algorithm | কীভাবে কাজ করে | Best For | Problem |
|---|---|---|---|
| Round Robin | Sequential rotation | Equal capacity servers | Load consider করে না |
| Weighted RR | Capacity-based weight | Mixed hardware | Static weight, dynamic load না |
| Least Connections | Lowest active connections | Long-lived connections | Connection count != actual load |
| IP Hash | IP → same server | Session persistence | Uneven distribution possible |
| Random | Random selection | Simple testing | Production এ unpredictable |
Health Check ও Failover
Load Balancer periodically সব servers কে ping করে দেখে তারা alive আছে কিনা। কোনো server respond না করলেন সেটাকে automatically rotation থেকে বাদ দেয়। Server ঠিক হলে আবার যোগ করে নেয়। এটাই Automatic Failover।
Health Check এর ধরন
- TCP Check: শুধু port open আছে কিনা check করে। দ্রুত কিন্তু app actually কাজ করছে কিনা বলে না।
- HTTP Check: নির্দিষ্ট URL এ request পাঠিয়ে 200 OK আশা করে। App level check — বেশি reliable।
- Custom Script: Database connection, disk space ইত্যাদি check করতে পারে। সাধারণত
/healthবা/pingendpoint ব্যবহার করুন।
upstream backend {
# Least connections algorithm
least_conn;
# Weighted servers — server1 বেশি powerful
server 192.168.1.10:3000 weight=3;
server 192.168.1.11:3000 weight=1;
server 192.168.1.12:3000 weight=1;
# Health check settings
# max_fails: এতবার fail হলে server বাদ দিন
# fail_timeout: এই সময়ের মধ্যে fail হলে count করুন
server 192.168.1.13:3000 max_fails=3 fail_timeout=30s;
}
server {
listen 80;
location / {
proxy_pass http://backend;
proxy_connect_timeout 5s;
proxy_read_timeout 30s;
# Health check endpoint
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# Active health check (Nginx Plus feature)
# location /health {
# health_check interval=5s fails=3 passes=2;
# }
}Popular Load Balancers — তুলনা
| Tool | Type | Layer | Performance | কখন ব্যবহার |
|---|---|---|---|---|
| Nginx | Open Source | L7 | Excellent | বেশিরভাগ web apps, reverse proxy |
| HAProxy | Open Source | L4+L7 | Industry Best | High performance TCP, financial systems |
| AWS ALB | Managed Cloud | L7 | Excellent | AWS microservices, containers |
| AWS NLB | Managed Cloud | L4 | Ultra Fast | Ultra-low latency, video streaming |
| Cloudflare LB | CDN+LB | L7 | Global | Global apps, DDoS protection দরকার |
| Traefik | Open Source | L7 | Good | Kubernetes, Docker environments |
Load Balancer Code Implementation
Concept বোঝার জন্য নিজে implement করে দেখা সবচেয়ে ভালো। নিচে Python এবং Node.js এ Load Balancer algorithms দেওয়া হলো।
import itertools
import requests
import threading
import time
class RoundRobinLoadBalancer:
def __init__(self, servers: list[str]):
self.servers = servers
self.healthy_servers = list(servers)
self._cycle = itertools.cycle(self.healthy_servers)
self._lock = threading.Lock()
def get_next_server(self) -> str | None:
"""Round Robin: পরবর্তী healthy server return করুন"""
with self._lock:
if not self.healthy_servers:
return None # সব server down!
return next(self._cycle)
def health_check(self):
"""প্রতি 5 সেকেন্ডে সব server check করুন"""
while True:
for server in self.servers:
try:
response = requests.get(f"{server}/health", timeout=2)
if response.status_code == 200:
if server not in self.healthy_servers:
self.healthy_servers.append(server)
self._cycle = itertools.cycle(self.healthy_servers)
print(f"✅ {server} back online")
except Exception:
if server in self.healthy_servers:
self.healthy_servers.remove(server)
self._cycle = itertools.cycle(self.healthy_servers)
print(f"❌ {server} removed — unhealthy")
time.sleep(5)
def forward_request(self, request_data: dict) -> dict:
"""Request কে next available server এ forward করুন"""
server = self.get_next_server()
if not server:
return {"error": "No healthy servers available", "status": 503}
try:
response = requests.post(f"{server}/handle", json=request_data, timeout=10)
return response.json()
except Exception as e:
return {"error": str(e), "status": 500}
# Usage
lb = RoundRobinLoadBalancer([
"http://server1:3000",
"http://server2:3000",
"http://server3:3000",
])
# Background এ health check চালাও
health_thread = threading.Thread(target=lb.health_check, daemon=True)
health_thread.start()
# Request handle করুন
result = lb.forward_request({"user_id": 123, "action": "get_profile"})class LeastConnectionsLB {
constructor(servers) {
// প্রতিটা server এর active connection count track করুন
this.servers = servers.map(server => ({
url: server,
connections: 0,
healthy: true,
}));
}
getServer() {
// শুধু healthy servers এর মধ্যে least connections ওয়ালাটা নাও
const healthyServers = this.servers.filter(s => s.healthy);
if (healthyServers.length === 0) {
throw new Error('No healthy servers available');
}
// Least connections server খুঁজুন
return healthyServers.reduce((min, server) =>
server.connections < min.connections ? server : min
);
}
async handleRequest(requestData) {
const server = this.getServer();
// Connection শুরু হলে count বাড়াও
server.connections++;
console.log(`Routing to ${server.url} (connections: ${server.connections})`);
try {
const response = await fetch(`${server.url}/handle`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(requestData),
});
return await response.json();
} finally {
// Request শেষ হলে count কমাও (success বা fail উভয় ক্ষেত্রে)
server.connections--;
}
}
markUnhealthy(serverUrl) {
const server = this.servers.find(s => s.url === serverUrl);
if (server) {
server.healthy = false;
console.log(`❌ ${serverUrl} marked as unhealthy`);
}
}
markHealthy(serverUrl) {
const server = this.servers.find(s => s.url === serverUrl);
if (server) {
server.healthy = true;
server.connections = 0;
console.log(`✅ ${serverUrl} back online`);
}
}
}
// Usage
const lb = new LeastConnectionsLB([
'http://server1:3000',
'http://server2:3000',
'http://server3:3000',
]);
// Multiple concurrent requests — সবচেয়ে কম busy server পাবেন প্রতিটা
Promise.all([
lb.handleRequest({ userId: 1 }),
lb.handleRequest({ userId: 2 }),
lb.handleRequest({ userId: 3 }),
]).then(results => console.log('All done:', results));Real World Use Cases
🎵 Spotify
AWS ALB (L7) ব্যবহার করে microservices routing এর জন্য। /stream/* → Streaming service, /search/* → Search service। Path-based routing দিয়ে হাজারো microservice manage করে।
🛍️ Shopify
Nginx + HAProxy combination। Black Friday তে traffic ১০x বাড়ে। HAProxy L4 দিয়ে initial connection, Nginx L7 দিয়ে content routing। Weighted Round Robin দিয়ে traffic ভাগ করে।
🎬 Netflix
Video streaming এর জন্য AWS NLB (L4) — ultra-low latency দরকার। API requests এর জন্য AWS ALB (L7)। দুটো আলাদা use case এর জন্য দুটো আলাদা Load Balancer।
🏦 Banks
IP Hash algorithm ব্যবহার করে session persistence এর জন্য। একবার login করলেন same server এ থাকো — session data consistent থাকে। Security এবং compliance এর জন্য critical।
Interview এ যা জিজ্ঞেস করে
Q1: L4 vs L7 — কখন কোনটা?
L7 ব্যবহার করুন যখন: Path-based routing দরকার (
/api vs /web)। SSL termination করতে হবে। Microservices architecture। Cookie/header based routing।Q2: Sticky Session কী এবং কেন problem?
সমস্যা হলো: (১) Uneven load distribution — একটা server এ সব heavy users গেলে সে overloaded। (২) ঐ server down হলে user এর session হারিয়ে যায়। (৩) Horizontal scaling এর benefit কমে।
Better solution: Session data Redis এ রাখুন — যেকোনো server request handle করতে পারবেন।
Q3: Load Balancer নিজে Single Point of Failure না?
Active-Active: দুটো LB একসাথে কাজ করে, traffic ভাগ করে নেয়। একটা down হলে অন্যটা সব traffic নেয়।
Active-Passive: একটা primary, একটা standby। Primary down হলে automatically failover। AWS ALB/NLB এগুলো automatically managed — আপনাকে চিন্তা করতে হয় না।
SUMMARY — আজকে যা শিখলাম
| Concept | এক লাইনে |
|---|---|
| Load Balancer | Traffic multiple servers এ distribute করে |
| L4 LB | IP+Port দেখে route করে, ultra-fast কিন্তু content-blind |
| L7 LB | HTTP content পড়ে smart routing করে, SSL terminate করে |
| Round Robin | Sequential server rotation — equal capacity এর জন্য |
| Least Connections | সবচেয়ে কম busy server কে request দিন |
| IP Hash | Same client IP → Same server (session persistence) |
| Health Check | Unhealthy server automatically বাদ, ঠিক হলে ফিরিয়ে আনে |