সেশন ০২

এক সার্ভার থেকে অনেক সার্ভার

এই সেশনের লক্ষ্য: Single-server setup কে এমন একটা system এ বদলানো, যেটা অনেক বেশি user সামলাতে পারে এবং সহজে fail করে না।

০০ যে প্রশ্নগুলোর উত্তর খুঁজবো

এই প্রশ্নগুলোর উত্তর জানার পর আপনি বুঝবেন, web layer কীভাবে scale করে। Scale করার পরেও আমাদের architecture এর কোন জায়গাটা এখনো ভাঙতে পারে, সেটাও বুঝবেন।

  • ১ Single server দিয়েই তো সবকিছু চলছে। তাহলে সমস্যা কোথায়?
  • ২ সবচেয়ে ছোট কোন পরিবর্তন থেকে শুরু করবো?
  • ৩ আলাদা তো করলাম। এখন কি system safe?
  • ৪ আরো web server যোগ করলে user কোনটার সাথে কথা বলবে?
  • ৫ Load balancer নিজেই কি Single Point of Failure?
  • ৬ একাধিক web server অ্যাড করলাম। এখন login ভাঙলো কেন?
  • ৭ System এখন দেখতে কেমন? এখনো কি breaking point আছে?

০১ Single server দিয়েই তো সবকিছু চলছে। তাহলে সমস্যা কোথায়?

শুরুতে setup টা খুব সহজ। একটাই server, তার ভেতরেই code আর database:

CLIENT SERVER (CODE + DATA) User (ফোন / browser) এক machine Website code App Server Database
একটাই machine এ website এর code আর database দুটোই চলছে। ছোট application, blog বা একদম নতুন startup এর জন্য এটুকুই যথেষ্ট।

কিন্তু user বেড়ে ১০,০০০ হলে তিনটা জিনিস ভেঙে পড়ে:

  1. CPU আর memory ফুরিয়ে যায়: একটা machine একসাথে ১০,০০০ request সামলাতে পারে না। System slow হয়ে যায়। অনেক request timeout হয়, মানে নির্দিষ্ট সময়ের মধ্যে উত্তর না পেয়ে বাতিল হয়ে যায়।
  2. পুরো system টাই একটা Single Point of Failure: ওই একটা machine crash করলে পুরো application down হয়ে যায়। Disk নষ্ট হলে data ও হারাতে পারে।
  3. দূরের user এর latency বেশি: Latency মানে request পাঠানো থেকে উত্তর পাওয়া পর্যন্ত সময়। ধরুন user আছেন US এ, আর server Bangladesh এ। তখন প্রতিটা request কে অর্ধেক পৃথিবী পার হয়ে আসতে হয়। তাই latency অনেক বেড়ে যায়।

তাহলে আমাদের কিছু একটা করতে হবে।

০২ সবচেয়ে ছোট কোন পরিবর্তন থেকে শুরু করবো?

এখন code আর database একই machine এ আছে। দুজনকেই একই CPU আর memory ভাগ করে ব্যবহার করতে হয়। একজন বেশি নিলে অন্যজন কম পায়।

সবচেয়ে ছোট পদক্ষেপ হলো: app server আর database কে আলাদা machine এ সরিয়ে নিন।

CLIENT APPLICATION DATA User Web Server code চালায় Database Server
Code আর data এখন আলাদা machine এ থাকে। প্রতিটা server নিজের কাজের জন্য tune করা।

এটা কেন ভালো? চারটা কারণ

  1. আলাদা কাজের জন্য আলাদা machine: Web Server এর বেশি দরকার CPU। Database এর দরকার memory আর fast disk। এক machine এ থাকলে দুজনকে একই resource ভাগ করে নিতে হয়। আলাদা করলে প্রতিটা server নিজের কাজের মতো করে tune করা যায়।
  2. আলাদা আলাদা scale করার স্বাধীনতা: Application server আর database একই machine এ থাকলে scale করার সময় পুরো machine টাকেই বড় করতে হয়। হয়তো load বেড়েছে শুধু web এর দিকে, কিন্তু database এর অংশও অকারণে বড় হয়ে যায়। এতে টাকার অপচয় হয়। আলাদা থাকলে যার load বেড়েছে, শুধু তাকেই বাড়ানো যায়। যেমন, traffic বাড়লে আপনি Web Server ১টা থেকে ১০টা করতে পারেন, আর database এর machine আগের মতোই থাকে।
  3. Isolation (আলাদা রাখা): Web Server এর কোনো bug তাকে crash করালেও database এর উপর কোনো প্রভাব পড়ে না। উল্টোটাও সত্যি: Database Server crash করলেও Web Server ঠিক থাকে।
  4. সহজ maintenance: Web Server restart, upgrade বা fix করার সময় database কে ছুঁতেই হয় না।

এটাকে বলে Separation of Concerns। মানে, প্রতিটা machine আলাদা একটা কাজ করে, আর নিজের কাজের জন্য optimized থাকে।

০৩ আলাদা তো করলাম। এখন কি system safe?

না।

এখানে একটা গুরুত্বপূর্ণ বিষয় বুঝতে হবে। আলাদা করে আমরা তিনটা জিনিস পেয়েছি:

কিন্তু এতে SPOF সরেনি। এখনো Web Server একটাই, database ও একটাই। এদের যেকোনো একটা down হলে পুরো system down হয়ে যায়।

শিক্ষা

আলাদা করলে specialization (প্রতিটা machine নিজের কাজে দক্ষ) পাওয়া যায়, redundancy পাওয়া যায় না। দুটোকে গুলিয়ে ফেলবেন না।

০৪ আরো web server যোগ করলে user কোনটার সাথে কথা বলবে?

একটা Web Server ১০,০০০ user সামলাতে পারে না। তাই আমরা আরো server যোগ করি।

এখন প্রশ্ন হলো: server তো এখন একাধিক। User application খুললে তার request কোন Web Server এ যাবে, সেটা কে ঠিক করবে?

CLIENT ??? APPLICATION User User User ??? Web 1 App Server Web 2 App Server Web 3 App Server
মাঝখানে এমন একটা কিছু লাগবে, যেটা ঠিক করবে কোন request কোন server এ যাবে।

উত্তর হলো Load Balancer (LB)।

Load Balancer (LB) কী?

Restaurant এর দরজায় যিনি দাঁড়িয়ে থাকেন, তাঁর কথা ভাবুন। তিনি বলেন, “Table 1 খালি, ওখানে বসুন। Table 2 তে লোক আছে, আপনি Table 3 তে যান।” Load balancer ঠিক এই কাজটাই করে। এটা আসা request গুলোকে একাধিক server এর মধ্যে ভাগ করে দেয়, যাতে কোনো একটা server এর উপর বেশি চাপ না পড়ে।

Load Balancer থেকে যা পাওয়া যায়

০৫ Load balancer কি নিজেই Single Point of Failure?

হ্যাঁ। এখানে অনেকেই ভুল করেন।

Load balancer crash করলে কোনো request আর কোনো Web Server এ পৌঁছায় না, ১০০টা web server থাকলেও না। Load balancer হলো single entry point, মানে সব traffic এই একটা জায়গা দিয়েই ঢোকে। Entry point একটাই থাকলে সেটা নিজেই SPOF।

SPOF নিয়ে একটা ভুল ধারণা

SPOF এর সাথে capacity এর কোনো সম্পর্ক নেই। সর্বোচ্চ load এ পৌঁছে যাওয়াকে বলে overload, সেটা SPOF নয়। SPOF মানে হলো, এই একটা জিনিস down হলে পুরো system down হয়ে যায়।

বাস্তবের system এ সমাধান: redundant Load Balancer

CLIENT LOAD BALANCER APPLICATION User User User LB-1 Active LB-2 Passive heartbeat Web 1 App Server Web 2 App Server Web 3 App Server
দুটো LB আছে: একটা active, আরেকটা passive (তৈরি হয়ে অপেক্ষা করে)। প্রথমটা down হলে দ্বিতীয়টা তার কাজ নিয়ে নেয়।

ছবিতে দুই LB এর মাঝে heartbeat লেখা আছে। দুই LB নিয়মিত একে অপরকে ছোট একটা signal পাঠায়, “আমি ঠিক আছি”। এই signal এর নাম heartbeat। Signal আসা বন্ধ হলে অন্য LB বুঝে যায়, প্রথমটা down হয়েছে।

দুটো LB দুইভাবে সাজানো যায়:

সেশন ০১ এর এই কথাটি এখনো সত্যি

SPOF এর সমাধান সবসময় একটাই: Redundancy।

০৬ একাধিক web server অ্যাড করলাম। এখন login ভাঙলো কেন?

প্রায় সব engineer ই কখনো না কখনো এই সমস্যায় পড়েন। চলুন বুঝি, কোথায় ভুল হচ্ছে।

একজন user login করলেন। তাঁর login request গেল Web1 এ। Web1 একটা session তৈরি করলো। Session হলো server এর কাছে রাখা একটা ছোট record, যেটা বলে “এই user logged in আছেন”। প্রতিটা session এর একটা session ID থাকে (যেমন abc123)। Browser এই ID টা মনে রাখে, আর পরের প্রতিটা request এর সাথে পাঠায়। Web1 session টা রাখলো নিজের memory তে:

Web1 এর memory: {Roy: logged in, session abc123}
Web2 এর memory: (খালি, কিছুই জানে না)
Web3 এর memory: (খালি, কিছুই জানে না)

User এর পরের request ও LB হয়ে আসে। এবার LB request টা পাঠালো Web2 তে, কারণ সে load ভাগ করছে। কিন্তু Web2 তো Roy কে চেনেই না। তার memory তে abc123 নামে কোনো session নেই। ফলে user দেখেন, তিনি logged out হয়ে গেছেন!

এটাই stateful server এর সমস্যা।

Stateful বনাম Stateless

পার্থক্য

Stateful server: User এর data নিজের local memory তে রাখে।

Stateless server: নিজের কাছে কিছুই রাখে না। প্রতিটা request এ দরকারি information সাথে করেই আসে, অথবা server সেটা একটা shared store থেকে নিয়ে আসে।

Scaling এর জন্য stateless কেন সবচেয়ে ভালো

তাহলে প্রশ্ন হলো, session data কোথায় রাখবো? এর উত্তর হলো Shared Session Store।

Shared Session Store

Session গুলো এমন একটা জায়গায় রাখা হয়, যেটা সব Web Server দেখতে পায়। এই কাজে প্রায়ই Redis ব্যবহার হয়। Redis একটা store, যেটা data memory তে রাখে, তাই খুব দ্রুত read আর write করতে পারে।

CLIENT APPLICATION (STATELESS) SHARED SESSION STORE User + token Web 1 Stateless Web 2 Stateless Web 3 Stateless Session Store (Redis) সব Web Server এর সাথে shared
User token নিয়ে যেকোনো Web Server এ যেতে পারে। সব server shared store থেকে user verify করে।

ছবিতে user এর সাথে একটা token আছে। Token হলো সেই ছোট পরিচয় চিহ্ন (এখানে session ID), যা user প্রতিটা request এর সাথে পাঠান। এখন যেকোনো Web Server এই token নিয়ে shared store এ খুঁজে user কে verify করতে পারে। তাই stateless server গুলোর একটাকে দিয়ে আরেকটার কাজ চালানো যায় (interchangeable)। অনেকগুলো machine মিলে যখন একটা system হিসেবে কাজ করে, তাকে distributed system বলে। এমন system এ এই interchangeable হওয়াটাই সবচেয়ে বড় সুবিধা।

HTTP এর ছোট্ট একটা তথ্য

Server যখন বলে “আমি আপনাকে চিনি না”, তখন সঠিক status code হলো 401 Unauthorized (মানে user logged in নেই)। আর 403 Forbidden মানে user logged in আছেন, কিন্তু এই কাজের অনুমতি তাঁর নেই।

০৭ System এখন দেখতে কেমন? এখনো কি breaking point আছে?

CLIENT LOAD BALANCER APPLICATION DATA User User User LB-1 Active LB-2 Passive heartbeat Stateless Web 1 App Server Web 2 App Server Web 3 App Server Database SPOF Session Store (Redis) সব Web Server এর সাথে shared
টানা তীরগুলো দেখায়, request কোন পথে চলে (LB-1 হয়ে)। LB-2 (dashed border) passive অবস্থায় অপেক্ষা করে। রঙিন তীরগুলো দেখায়, session data Redis এ যায়।

এখন পর্যন্ত কী কী ঠিক করা হলো?

  • LB SPOF: Redundant Load Balancer (Active-Passive)।
  • Web Server SPOF: একাধিক Web Server।
  • Stateful server এর সমস্যা: Shared Session Store (Redis)।

যা এখনো বাকি

  • Database SPOF: Database এখনো একটাই, কোনো backup নেই। Database down হলে পুরো application বন্ধ হয়ে যায়।
  • দূরের user এর latency এখনো বেশি: Request আর response কে অর্ধেক পৃথিবী পার হয়ে user এর কাছে পৌঁছাতে হয়।

Database এর SPOF হলো আমাদের পরের সমস্যা। সেশন ০৩ এ আমরা এটা নিয়েই আলোচনা করবো।

০৮ মগজে প্রেশার দিন

নিচের প্রশ্নগুলোর উত্তর আগে নিজে ভাবুন। তারপর দেখুন, সবাই সাধারণত কীভাবে ভাবে, সেটা কেন ভুল, আর সঠিক উত্তর কী।

প্রশ্ন ১: Load balancer কি নিজেই Single Point of Failure? কেন?
উত্তর দেখুন আগে নিজে ভাবুন

সবাই যেভাবে ভাবে

“হ্যাঁ। LB অনেক request handle করতে পারলেও তার একটা সর্বোচ্চ সীমা আছে। সেই সীমায় পৌঁছালে LB নিজেই fail করবে। তাই এটা SPOF।”

এই উত্তরের “হ্যাঁ” অংশটা ঠিক, কিন্তু যে কারণ দেখানো হয়েছে, সেটা ভুল।

কেন ভুল

SPOF এর সাথে capacity এর কোনো সম্পর্ক নেই। SPOF মানে একটা component এর উপর পুরো system এর নির্ভরতা: ওই component down হলে পুরো system down হয়ে যায়। সর্বোচ্চ capacity তে পৌঁছানো আলাদা একটা সমস্যা। সেটাকে বলে overload, SPOF নয়।

সঠিক উত্তর

Load Balancer SPOF, কারণ এটা single entry point (সব traffic এই একটা জায়গা দিয়েই ঢোকে)। এটা down হলে কোনো request আর কোনো web server এ পৌঁছায় না, ১০০টা Web Server চালু থাকলেও না।

Fix: Redundant load balancer রাখুন (active-passive বা active-active)।

প্রশ্ন ২: User Web1 এ login করলেন, পরের request গেল Web2 এ। কী সমস্যা হবে?
উত্তর দেখুন আগে নিজে ভাবুন

সবাই যেভাবে ভাবে

“Web2 user কে চিনতে পারবে না, তাই 403 response দেবে।”

মূল ধারণাটা ঠিক, কিন্তু এতে একটা ছোট্ট ভুল আছে।

আসল concept

এটা stateful বনাম stateless server এর সমস্যা। Web1 session টা নিজের local memory তে রেখেছিল। Web2 এই session এর কিছুই জানে না। ফলে user দেখেন, তিনি logged out হয়ে গেছেন।

Fix: Web Server গুলোকে stateless বানান। Session রাখুন একটা shared session store এ (যেমন Redis)।

HTTP status code এর ভুলটা

সঠিক status code হলো 401, 403 নয়।

  • 401 Unauthorized: User logged in নেই।
  • 403 Forbidden: User logged in আছেন, কিন্তু এই কাজের অনুমতি নেই।
প্রশ্ন ৩: একটা machine এর resource না বাড়িয়ে web আর database আলাদা করা ভালো কেন?
উত্তর দেখুন আগে নিজে ভাবুন

সবাই যেভাবে ভাবে

“SPOF কমে যাবে। Application server crash করলেও data এর ক্ষতি হবে না, কারণ server দুটো আলাদা।”

উত্তরের দুটো অংশ: একটা ভুল, একটা দুর্বল

Part A, “SPOF কমে যাবে”: ভুল। Database এখনো একটাই machine এ আছে, তাই এটা এখনো SPOF। আলাদা করায় কোনো redundancy যোগ হয়নি।

Part B, “web crash করলে data safe থাকবে”: সত্যি, কিন্তু দুর্বল যুক্তি। এটা মূল কারণ নয়, শুধু একটা বাড়তি সুবিধা।

আসল কারণ চারটা

  1. আলাদা machine আলাদা কাজের জন্য tune করা যায়: Web এর দরকার CPU, database এর দরকার disk আর memory।
  2. Independent scaling: যার load বেড়েছে, শুধু তাকেই বাড়ানো যায়।
  3. Isolation: একজন crash করলে অন্যজন ঠিক থাকে।
  4. সহজ maintenance: একজনকে restart বা upgrade করতে অন্যজনকে ছুঁতে হয় না।
শিক্ষা

আলাদা করলে specialization পাওয়া যায়, redundancy পাওয়া যায় না। দুটোকে গুলিয়ে ফেলবেন না।

০৯ যে টার্মগুলো শিখলাম

টার্মমানে
Load Balancer (LB)আসা request গুলোকে একাধিক server এ ভাগ করে দেয়।
Active-Passiveএকটা LB traffic handle করে, আরেকটা দায়িত্ব নেওয়ার জন্য অপেক্ষা করে।
Active-Activeএকাধিক LB একসাথে traffic handle করে।
Heartbeatনিয়মিত পাঠানো ছোট signal, যা জানায় machine টা চালু আছে।
LatencyRequest পাঠানো থেকে উত্তর পাওয়া পর্যন্ত সময়।
Stateful ServerUser এর data নিজের local memory তে রাখে।
Stateless ServerUser এর data নিজের কাছে রাখে না, shared store থেকে আনে।
Session Storeএকটা shared জায়গা (যেমন Redis), যেখানে যেকোনো server যেতে পারে।
Separation of Concernsআলাদা machine আলাদা কাজ করে, প্রতিটা নিজের কাজের জন্য optimized।
Single Entry Pointযে component দিয়ে সব traffic ঢোকে। Redundant না হলে এটা নিজেই SPOF।
OverloadCapacity এর সীমায় পৌঁছে যাওয়া। এটা SPOF থেকে আলাদা।
401 বনাম 403401: user logged in নেই। 403: logged in আছেন, কিন্তু অনুমতি নেই।

১০ শর্ট সামারি

  1. Scaling এর প্রথম ধাপ হলো Web Server আর database আলাদা করা, যাতে প্রতিটাকে নিজের কাজের মতো করে tune করা যায়।
  2. Horizontal scaling মানে আরো Web Server যোগ করা। Load balancer request ভাগ করে দেয়, আর web layer এর SPOF ও সরিয়ে দেয়।
  3. Stateless server (সাথে একটা shared session store) scaling সহজ করে দেয়। তখন যেকোনো server যেকোনো request handle করতে পারে।

১১ মনে রাখুন