9.1
একটা Stateless অ্যাপ যেভাবে বড় হয়
Elastic IP লাগানো একটা মাত্র Instance থেকে শুরু করে Load Balancer-এর পেছনে কয়েক AZ জুড়ে অনেক Instance পর্যন্ত, একটা একটা সমস্যা মেটাতে মেটাতে।
24 মিনিট পড়া + Animation
টিপস: ডটেড-আন্ডারলাইন করা যেকোনো শব্দে ট্যাপ বা Hover করলে তার অর্থ দেখবে।
এই লেসন শেষে তুমি পারবে
- Stateless application কী, সেটা সত্যিই কী দাবি করে (memory-তে session না রাখা, instance-এর ভেতরে দরকারি কোনো file না রাখা), আর stateless আর stateful কীভাবে আলাদা করে চিনতে হয়, সেটা বোঝাতে।
- একটা সাধারণ web app কীভাবে ধাপে ধাপে বড় হয়, Elastic IP সহ একটা EC2 instance থেকে load balancer-এর পেছনে multi-AZ fleet পর্যন্ত, আর প্রতিটা ধাপে কোন সমস্যা পরের ধাপে যেতে বাধ্য করে, সেটা বলতে।
- কেন vertical scaling মানেই downtime, কেন অনেকগুলো Elastic IP বা অনেকগুলো A record দিয়ে scale হয় না, আর TTL-এর caching কীভাবে একটা মরা address-কে ব্যবহারে রেখে দেয়, সেটা ব্যাখ্যা করতে।
- Standard stateless web tier design করতে: Route 53 Alias → কমপক্ষে দুটো AZ-এ health check সহ ALB → Auto Scaling group-এ private instance, আর security group-এর শিকল ALB → instance।
- সবসময় চালু থাকা minimum-টুকু commit করে (Reserved Instance বা Savings Plan) আর তার ওপরে On-Demand বা Spot চালিয়ে এই design-এর খরচ কমাতে।
- পরীক্ষার pattern চিনে ফেলতে: “data না হারিয়ে হাজারো instance-এ scale out”, “allow-list-এর জন্য static IP”, “একটা AZ নষ্ট হলেও টিকে থাকা”, “সবসময় চালু minimum-এর খরচ কমানো”।
#এই chapter-টা কীভাবে চলবে
এই chapter-এর সব service আগেই শেখা হয়ে গেছে: EC2, Elastic IP, security group, load balancer, Auto Scaling group, RDS, ElastiCache, Route 53। Chapter ৯-এর কাজ হলো এগুলোকে জোড়া লাগানো, ঠিক যেভাবে একজন solutions architect ভাবে:
- যেটা কাজ করে এমন সবচেয়ে সহজ জিনিস দিয়ে শুরু করো।
- তার নির্দিষ্ট সমস্যাটা খুঁজে বের করো: downtime, কোনো failure, bill, নাকি security-র কোনো ফুটো।
- ওই সমস্যার সবচেয়ে ছোট সমাধান লাগাও, তারপর পরের সমস্যাটা খোঁজো।
পরীক্ষাতেও ঠিক এটাই আসে: “এই হলো architecture, এই হলো নতুন requirement, এখন পরের সবচেয়ে ভালো ধাপ কোনটা?”। প্রতিটা service আলাদা করে জানা যথেষ্ট না; জানতে হবে কোন service কোন সমস্যার সমাধান। এই লেসনে আমরা একটা stateless app-এর পিছু নেব। লেসন ৯.২-তে আসবে state (shopping cart আর database), লেসন ৯.৩-এ শেয়ার করা file আর দ্রুত launch, আর লেসন ৯.৪-এ Elastic Beanstalk তোমার হয়ে পুরো stack বানিয়ে দেবে।
আমাদের app-এর নাম whatisthetime.example, ঠিকানা api.whatisthetime.example। তার কাজ একটাই: কয়টা বাজে বলে দেওয়া। Database লাগে না। মালিকেরা ছোট করে শুরু করতে চায়, শুরুতে একটু-আধটু downtime মেনে নিতে রাজি, কিন্তু শেষমেশ চায় vertical আর horizontal দুইভাবেই scale করতে, কোনো downtime ছাড়াই।
#“Stateless” মানে কী
#প্রতিটা request নিজের পায়ে দাঁড়ানো
একটা application tier তখনই stateless, যখন server দুটো request-এর মাঝখানে কোনো client সম্পর্কে কিছুই মনে রাখে না। উত্তর দেওয়ার জন্য যা লাগে, প্রতিটা request নিজেই সেটা নিয়ে আসে, আর উত্তরটা নির্ভর করে না কোন server request-টা পেল বা সেই server আগে কী সামলেছে তার ওপর।
যেকোনো instance উত্তর দিতে পারে
দুজন user, একটা load balancer আর তিনটা একই রকম instance। কোনো instance যদি কোনো user সম্পর্কে কিছু জমা না রাখে, তাহলে পরের request যেকোনোটা নিতে পারে, আর যেকোনোটা উধাও-ও হয়ে যেতে পারে।
পরিস্থিতি
যেন রাস্তায় যে সবচেয়ে কাছে আছে তাকেই সময় জিজ্ঞেস করা।
Asha জানতে চাইল কয়টা বাজে। Request-এর ভেতরেই উত্তর দেওয়ার জন্য যা লাগে সব আছে: এর বাইরে আর কিছু লাগে না।
#Stateless হতে আসলে কী কী লাগে
“আমাদের app stateless” বলাটা সহজ, ভুল করাটাও সহজ। একটা web tier তখনই stateless, যখন নিচের সবগুলো কথা সত্য:
| নিয়ম | কীভাবে ভাঙে | ওই state-এর আসল জায়গা |
|---|---|---|
| Instance-এর memory-তে user-এর session নেই | Login রাখা হয়েছে local in-memory map-এ | ElastiCache বা DynamoDB, অথবা একটা signed token যেটা client প্রতিটা request-এর সাথে পাঠায় (লেসন ৯.২) |
| Instance-এর disk-এ দরকারি কোনো file নেই | Upload রাখা হয়েছে root EBS volume বা instance store-এ | S3, আর অনেক instance-এর একসাথে file system লাগলে EFS (লেসন ৯.৩) |
| শুধু একটা instance-এ আছে এমন কোনো data নেই | Local database file, local queue, memory-তে counter | RDS, Aurora, DynamoDB, SQS |
| একেবারে আলাদা ধরনের configuration নেই | SSH করে হাতে হাতে ঠিক করা একটা instance | AMI, user data আর launch template (লেসন ৪.৩), configuration service |
| Log instance থেকে বাইরে পাঠানো হয় | Log শুধু /var/log-এ পড়ে থাকে | কেন্দ্রীয় log service (CloudWatch Logs, পরের একটা chapter-এ) |
Local cache থাকতেই পারে, যতক্ষণ সেটা হারালে শুধু গতি কমে, ভুল কিছু হয় না: database থেকে আবার বানানো যায় এমন cache কোনো state না।
#Stateless নাকি stateful? এক প্রশ্নের পরীক্ষা
Tier-টা নিয়ে নিজেকে একটাই প্রশ্ন করো: “যেকোনো instance-কে যেকোনো মুহূর্তে terminate করে পরের request অন্য কোথাও পাঠালে কোনো user কি একটা retry ছাড়া আর কিছু টের পাবে?”
- না, টের পাবে না → tier-টা stateless। তুমি এটাকে load balancer-এর পেছনে রাখতে পারো, ইচ্ছেমতো scale in আর out করতে পারো, Spot Instance ব্যবহার করতে পারো, deployment-এর সময় instance বদলে দিতে পারো।
- হ্যাঁ, টের পাবে → instance-এর ভেতরে কিছু একটা state হয়ে বসে আছে। সেটা খুঁজে বের করো (session, file, local data) আর বাইরে সরাও, নাহলে প্রতিটা scaling আর failure-এর সময় tier-টা ঝামেলা বাধাবে।
Database নিজে তো stateful, এটাই স্বাভাবিক: state হাওয়ায় মিলিয়ে যায় না, সেটা সরে যায় এমন একটা tier-এ যেটা তাকে নিরাপদে রাখার জন্যই বানানো। পুরো design-এর মূল কথা হলো, অনেকগুলো, সস্তা, বদলে ফেলা যায় এমন web instance কিছুই রাখে না, আর অল্প কয়েকটা, যত্ন করে রক্ষা করা data store সবকিছু রাখে।
#যাত্রাটা, একবারে একটা সমস্যা
নিচের animation-টায় পুরো লেসন এক জায়গায়। একটা ধাপ বেছে নাও, Request পাঠাও চেপে দেখো কীভাবে কাজ করে, তারপর লাল বোতামটা চেপে দেখো কী ভাঙে, আর এগিয়ে যাও সেই ধাপে যেটা সমস্যাটা সারায়। এর পরের অংশগুলোতে প্রতিটা ধাপ খুলে বলা হয়েছে।
whatisthetime.example বড় হচ্ছে: আটটা ধাপ
একটা ধাপ বেছে নাও। “Request পাঠাও” দেখায় ধাপটা কীভাবে কাজ করে; “এরপর কী ভাঙে” সেই সমস্যাটা ঘটিয়ে দেখায়, যেটার জন্য পরের ধাপে যেতে হয়। বোতাম না চাপলে কিছুই নড়বে না।
ধাপ
একটা public instance, সাথে একটা Elastic IP
ঢোকার পথ
১টা Elastic IP
Public IPv4 address
১টা · মাসে ≈ $৩.৬৫
একটা instance নষ্ট হলে
Site বন্ধ
একটা AZ নষ্ট হলে
Site বন্ধ
ছোট করে শুরু: public subnet-এ একটা t2.micro, সাথে একটা Elastic IP, মানে স্থির একটা public IPv4 address। App শুধু ঘড়ি দেখে উত্তর দেয়, তাই database নেই, মনে রাখারও কিছু নেই।
#ধাপ ১: Elastic IP সহ একটা instance
সবচেয়ে সহজ রূপ হলো public subnet-এ একটা ছোট instance, একটা t2.micro (১ vCPU, ১ GiB memory)। User-দের একটা স্থির address দরকার, তাই তুমি একটা Elastic IP লাগিয়ে দাও: এটা একটা static public IPv4 address, যেটা তুমি release না করা পর্যন্ত তোমার account-এর কাছেই থাকে (লেসন ৩.৬)। সাধারণ auto-assigned public IP প্রতিবার instance stop আর start করলে বদলে যেত; Elastic IP বদলায় না।
এটা চলে, সস্তা, আর এর দুটো সমস্যা শিগগিরই সামনে আসবে: একটা instance-এর capacity নির্দিষ্ট, আর একটা instance মানেই একটা single point of failure। সে নিজে, তার host বা তার AZ নষ্ট হলেই site বন্ধ।
#ধাপ ২: vertical scaling
Traffic বাড়ল, t2.micro 100% CPU-তে চলছে। সবচেয়ে দ্রুত সমাধান আরও বড় instance: scale up করে m5.large (২ vCPU, ৮ GiB)। EBS-backed instance-এ এর মানে stop, type বদল, তারপর start (লেসন ৬.১):
- Stop থাকা, boot হওয়া আর চালু হয়ে গুছিয়ে ওঠার পুরো সময়টা downtime। পরে যতবার resize করবে, ওপরে বা নিচে, ততবার আবার একটা outage।
- Stop আর start-এর মধ্যে Elastic IP লেগেই থাকে, তাই user-রা একই address পায়। (Elastic IP না থাকলে public IP বদলে যেত।)
- একটা ছাদ আছে: সবচেয়ে বড় instance type। আর সেটা যত বড়ই হোক, এখনো একটা AZ-এ একটাই instance।
Vertical scaling কাজের জিনিস (code বদলাতে হয় না, আর relational database-এর primary বড় করার সাধারণ উপায় এটাই), কিন্তু web tier-এর জন্য এটা এক সমস্যার বদলে আরেক সমস্যা আনে। মালিকেরা চেয়েছিল downtime ছাড়া scale করতে, তাই আমাদের লাগবে আরও instance, বড় instance না।
#ধাপ ৩: প্রতিটার নিজের Elastic IP দিয়ে scale out
Scale out (horizontally) মানে app-এর কয়েকটা copy চালানো। App stateless বলে প্রতিটা copy একই উত্তর দেয়, তাই এটা সাথে সাথেই কাজ করে। প্রথম চেষ্টা: তিনটা instance, প্রত্যেকটার নিজের একটা Elastic IP।
ঝামেলাটা address নিয়ে:
- User-দের, বা তাদের app-কে, তিনটা address-ই জানতে হয়, আর একটা বেছে নিতে হয়। প্রতিটা নতুন instance মানে সব client-কে নতুন address জানানো; একটা সরালে সবাইকে বলা ওটা আর ব্যবহার করো না।
- Default quota হলো account-প্রতি Region-প্রতি ৫টা Elastic IP (চাইলে বাড়ানো যায়, কিন্তু এতেই বোঝা যায় AWS এভাবে scale করার কথা ভাবেনি)।
- February ২০২৪ থেকে প্রতিটা public IPv4 address-এর দাম ঘণ্টায় $০.০০৫, Elastic হোক বা auto-assigned, লাগানো থাকুক বা অলস: প্রতিটা মাসে প্রায় $৩.৬৫।
- একটা instance মরে গেলে যারা তার address ব্যবহার করছিল, তারা সোজা fail করে। Elastic IP একটা instance-কেই দেখায়, health সম্পর্কে কিছুই জানে না। চাইলে তুমি সেটা একটা spare instance-এ সরাতে পারো (লেসন ৩.৬), কিন্তু সেটা হাতে করা, একটা একটা করে সমাধান।
আমাদের দরকার পুরো fleet-এর জন্য একটা নাম, যেটা client-এর জন্য কখনো বদলাবে না।
#ধাপ ৪: কয়েকটা value সহ Route 53 A record
তাই সামনে DNS বসাই আর Elastic IP বাদ দিই। Instance-গুলোর সাধারণ public IP থাকে, আর api.whatisthetime.example-এর একটা simple A record-এ সবগুলো লেখা থাকে, TTL ১ ঘণ্টা (৩,৬০০ সেকেন্ড)। Route 53 সব value এলোমেলো ক্রমে দেয়, আর প্রতিটা client একটা ব্যবহার করে (লেসন ৮.৩)। Client-রা এখন একটা নাম জানে, আর instance যোগ করা মানে record-এ একটা value যোগ করা।
এটা ভালো, কিন্তু DNS-এর উত্তর cache হয় (লেসন ৮.১), আর simple routing-এ কোনো health check নেই:
- Instance মরে, তার address বেঁচে থাকে। যে resolver আর client উত্তরটা cache করেছে, তারা TTL শেষ না হওয়া পর্যন্ত মরা address-এই request পাঠাতে থাকে, এক ঘণ্টা পর্যন্ত। কেউ record না বদলানো পর্যন্ত নতুন উত্তরেও সেটা থাকে।
- নতুন instance অপেক্ষা করে। যারা পুরোনো উত্তর cache করেছে, তাদের cache ফুরানোর আগে তারা নতুন address দেখেই না।
- ছোট TTL (ধরো ৬০ সেকেন্ড) সময়টা কমায়, কিন্তু DNS query বহু গুণ বাড়িয়ে দেয়, আর তবুও DNS health দেখতে পায় না, সেকেন্ডের মধ্যে সাড়াও দিতে পারে না। Multi-value answer routing অসুস্থ address বাদ দিতে পারে, কিন্তু cache-এ থাকা copy তবুও পুরোনো হয়ে যায়, আর সেটাও load balancer না (লেসন ৮.৩)।
কয়েকটা A record বনাম একটা load balancer
ধাপ ৪ আর ধাপ ৫ পাশাপাশি। A record থাকলে Route 53 instance-এর address বিলি করে, আর client TTL পর্যন্ত সেগুলো cache করে রাখে। Load balancer থাকলে Route 53 বিলি করে load balancer-কে, আর প্রতিটা request কোথায় যাবে সেটা health check দেখে ঠিক করে load balancer।
পরিস্থিতি
কোনো load balancer নেই। একটা simple record-এ প্রতিটা instance-এর public IP লেখা।
Route 53: api.whatisthetime.example (simple, type A)
| Value | TTL | Instance |
|---|---|---|
| 198.51.100.21 | 3600 | web-1 |
| 198.51.100.22 | 3600 | web-2 |
| 198.51.100.23 | 3600 | web-3 |
Client জানতে চাইল api.whatisthetime.example কোথায়। Route 53 তিনটা value-ই এলোমেলো ক্রমে দিল, TTL ৩,৬০০ সেকেন্ড।
api.whatisthetime.example একটা simple A record, তাতে তিনটা instance-এর IP আর TTL ৩,৬০০ সেকেন্ড। একটা client-এর resolver ০৯:০০-এ উত্তরটা cache করেছে। ০৯:৩০-এ একটা instance terminate হলো, আর ০৯:৩৫-এ একজন engineer record থেকে তার IP মুছে দিল। ওই client কখন পর্যন্ত মরা address-এ চেষ্টা করতে পারে?
#ধাপ ৫: health check সহ একটা load balancer
সমাধান হলো traffic-এর পথে এমন কিছু বসানো যে জানে কোন instance সুস্থ: একটা Application Load Balancer (লেসন ৬.২ আর ৬.৩)।
- Route 53-এ
api.whatisthetime.example-এর জন্য একটা Alias record বানাও, যেটা ALB-কে দেখায় (লেসন ৮.২)। ALB-র একটা DNS নাম আছে, কিন্তু স্থির কোনো IP address নেই (সে scale করলে address বদলায়), তাই কখনো তার IP হাতে লিখে A record বানাবে না। Alias zone apex-এও চলে, আর load balancer-এর দিকে Alias query-র কোনো দাম নেই। - প্রতিটা request ALB-তে পৌঁছায়, আর ALB সেটা একটা সুস্থ target-এ পাঠায়। তার health check কয়েক সেকেন্ডের মধ্যে মরা instance ধরে ফেলে আর তাকে request পাঠানো বন্ধ করে। Client cache করে শুধু ALB-র নাম আর address, কখনো instance-এর address না, তাই পুরোনো হয়ে যাওয়ার মতো কিছুই থাকে না।
- Instance-গুলোকে আর internet থেকে পৌঁছানোর দরকার নেই। ওদের সরিয়ে দাও private subnet-এ, public IP ছাড়া; public subnet-এ বসা ALB-ই একমাত্র public দরজা। তাতে ওদের public IPv4-এর খরচও উঠে যায়।
- Security group-এর শিকল বানাও (লেসন ৩.৫): ALB-র security group
0.0.0.0/0থেকে HTTP/HTTPS ঢুকতে দেয়; instance-গুলোর security group app-এর port খোলে শুধু ALB-র security group থেকে, source হিসেবে, কোনো IP range থেকে না। Load balancer ছাড়া অন্য কোনো পথে কেউ instance-এ পৌঁছাতে পারে না।
এখন একটা instance হারানো কোনো ঘটনাই না। বাকি রইল এটুকু: traffic বাড়লে instance যোগ করা, কমলে সরানো, আর মরে গেলে বদলানো, এসব এখনো কাউকে হাতে করতে হয়।
#ধাপ ৬: একটা Auto Scaling group
এই কাজটা করে একটা Auto Scaling group (লেসন ৬.৫):
- সে launch template থেকে instance চালু করে (লেসন ৪.৩-এর AMI আর user data), আর নিজে থেকেই ALB-র target group-এ register করে।
- একটা scaling policy (যেমন গড় CPU বা target-প্রতি request-এর ওপর target tracking) load অনুযায়ী desired capacity-কে min আর max-এর মধ্যে ওঠায়-নামায়। রাতে সে minimum-এ নেমে আসে, আর instance terminate করলে কিছুই হারায় না, কারণ তারা কোনো state রাখে না।
- ELB health check type চালু থাকলে যে instance ALB-র health check-এ fail করে, সেটাকে terminate করে বদলে দেওয়া হয়। শুধু default EC2 status check থাকলে ASG crash করা instance বদলাত ঠিকই, কিন্তু চালু থাকা অথচ app আটকে যাওয়া instance রেখে দিত।
শেষ দুর্বলতা হলো জায়গা। সব instance যদি একটা AZ-এ থাকে, একটা data centre-এর গোলমালেই সবাই একসাথে শেষ।
#ধাপ ৭: multi-AZ
সবকিছু ছড়িয়ে দাও কমপক্ষে দুটো Availability Zone-এ:
- ALB-কে কমপক্ষে দুটো AZ-এ চালু করতেই হয়: দুটোর কম AZ subnet দিয়ে ALB বানানোই যায় না। প্রতিটা AZ-এ তার একটা node চলে, আর cross-zone load balancing (ALB-তে সবসময় চালু) সব সুস্থ target-এর মধ্যে request সমান করে ছড়িয়ে দেয়।
- ASG-কে দুটো বা তিনটা AZ-এর subnet দাও, সে instance-গুলোকে ওগুলোর মধ্যে সমান রাখে। একটা AZ নষ্ট হলে ALB ওখানে traffic পাঠানো বন্ধ করে, আর ASG সুস্থ AZ-গুলোতে নতুন instance চালু করে (default AZ distribution strategy, balanced best effort, একটা AZ গোলমালে থাকলে launch সরিয়ে নেয় সুস্থ AZ-এ)।
- একটা AZ হারানোর হিসাব করে মাপ ঠিক করো। Peak-এ ৬টা instance লাগলে, একটা AZ হারিয়েও টিকে থাকতে দুটো AZ-এর প্রতিটায় ৬টা করে লাগবে (মোট ১২), তিনটা AZ হলে প্রতিটায় ৩টা (মোট ৯)। এটাই লেসন ৬.১-এর N+1 নিয়ম; এটা না মানলে নতুন instance তৈরি না হওয়া পর্যন্ত টিকে থাকা instance-গুলো চাপে ভেঙে পড়ে।
একটা ALB-র পেছনে multi-AZ fleet
ধাপ ৬ আর ৭। চালু করা প্রতিটা AZ-এ ALB-র একটা node থাকে, আর Auto Scaling group instance-গুলোকে AZ-গুলোর মধ্যে সমান রাখে। দেখো কোন ব্যর্থতার দাম কত।
পরিস্থিতি
User-রা api.whatisthetime.example খোঁজে ALB-র দিকে একটা Alias record দিয়ে। ALB চালু AZ a আর AZ b-তে: দুটোর কম AZ দিয়ে ALB বানানোই যায় না।
#ধাপ ৮: minimum-টা reserve করো
Design এখন available আর scalable, বাকি শুধু bill। Minimum ২ (প্রতি AZ-এ একটা) মানে দুটো instance দিনে ২৪ ঘণ্টা, বছরে ৩৬৫ দিন চলে, traffic থাকুক বা না থাকুক। যেটা কখনো বন্ধই হয় না, তার জন্য On-Demand দাম দেওয়া হলো কেনার সবচেয়ে দামি উপায়।
- সবসময় চালু minimum-টা ঢাকো ১ বা ৩ বছরের Reserved Instance বা Savings Plan দিয়ে (লেসন ৪.৪): সর্বোচ্চ প্রায় ৭২% ছাড়। এটা প্রতিটা ঘণ্টায় ব্যবহার হয়, তাই commitment-এর একটা ঘণ্টাও নষ্ট হয় না।
- Minimum-এর ওপরের instance-গুলোর জন্য দাও On-Demand দাম, বা mixed instances policy দিয়ে ওগুলো চালাও Spot-এ (সর্বোচ্চ প্রায় ৯০% ছাড়): দুই মিনিটের notice-এ ফিরিয়ে নেওয়া হলেও stateless instance-এর কিছু হারায় না।
- টাকা বাঁচাতে minimum ১ বা ০ করে দিও না: তাতে high availability চলে যায়, যেটা ছিল requirement।
লেসন ৬.৫-এর practice question-টা (ALB-র পেছনে minimum ২-এর একটা ASG; উত্তর “দুটো EC2 instance reserve করো”) ঠিক এই ধাপটাই। এখানে একই ধারণা, একটা calculator হিসেবে। প্রথমে ২টা ঢেকে দেখো, তারপর ৬টা, আর বাড়তি instance-গুলো Spot-এ সরিয়ে দেখো:
Floor-এর দাম মেটানো
একদিনের traffic, ঘণ্টায় কয়টা instance লাগে সেই হিসাবে। কয়টা instance commitment দিয়ে ঢাকবে আর বাকিগুলোর দাম কীভাবে দেবে বেছে নাও, তারপর মাসের bill মিলিয়ে দেখো সবকিছু On-Demand-এ চালানোর সাথে।
RI / Savings Plan দিয়ে ঢাকা instance
Commitment-এর মেয়াদ
Floor-এর ওপরের বাড়তি instance
মাসের bill
$৩২০
সবই On-Demand
$৩২০
সাশ্রয়
০%
দিনে অব্যবহৃত commitment-ঘণ্টা
০
সবকিছু On-Demand: নমনীয়, কিন্তু যে দুটো instance কখনো বন্ধ হয় না, সেগুলোর দাম বছরের প্রতিটা ঘণ্টায় সবচেয়ে বেশি হারে যাচ্ছে।
দামগুলো উদাহরণমাত্র: m5.large মাপের instance-এর On-Demand দাম ঘণ্টায় $০.০৯৬; আসল ছাড় নির্ভর করে মেয়াদ, payment option আর Region-এর ওপর (commitment-এ সর্বোচ্চ প্রায় ৭২%, Spot-এ সর্বোচ্চ প্রায় ৯০%)।
Floor-এর ওপরে commitment লাভ দেয় শুধু যত ঘণ্টা সেটা আসলে ব্যবহার হয়, তাই peak পর্যন্ত reserve করা মানে বাজি ধরা যে traffic-এর curve বছরের পর বছর একই থাকবে। নিশ্চিত করে জানা যায় শুধু floor-টুকুই।
#কোন ধাপ কী সারাল, কী ভাঙা রেখে গেল
| ধাপ | Design | যে সমস্যা সারাল | যে সমস্যা রয়ে গেল |
|---|---|---|---|
| ১ | একটা public EC2 + Elastic IP | এখনো কিছু না: সবচেয়ে সহজ শুরু | নির্দিষ্ট capacity, single point of failure |
| ২ | বড় instance (scale up) | Capacity | প্রতিবার resize-এ downtime, একটা ছাদ, তবুও একটাই instance |
| ৩ | কয়েকটা EC2, প্রত্যেকটার একটা Elastic IP | Resize ছাড়াই capacity | Client-কে সব IP জানতে হয়, Region-প্রতি ৫টা EIP, IPv4-এর খরচ, failover নেই |
| ৪ | কয়েকটা value সহ Route 53 A record | পুরো fleet-এর জন্য একটা নাম | TTL শেষ না হওয়া পর্যন্ত cache-এ মরা IP, health check নেই |
| ৫ | ALB + health check + Alias, private instance | সেকেন্ডে failover, একটা দরজা, আক্রমণের জায়গা কম | Capacity সামলাতে হয় হাতে |
| ৬ | Auto Scaling group (ELB health check) | নিজে থেকে scale out, scale in আর বদলানো | সব instance এক AZ-এ |
| ৭ | ≥ ২টা AZ জুড়ে ALB আর ASG | একটা AZ নষ্ট হলেও টিকে যায় | সবসময় চালু minimum-এর দাম On-Demand |
| ৮ | Minimum reserve, তার ওপরে On-Demand বা Spot | খরচ | Stateless app-এর জন্য আর কিছু না: এরপর আসবে state (লেসন ৯.২) |
#Well-Architected-এর চোখে
ভালো architecture কেমন হয়, সেটা AWS বোঝায় Well-Architected Framework-এর pillar দিয়ে। এই ছোট্ট গল্পটা তার পাঁচটা ছুঁয়ে গেছে:
- Reliability: health check, instance বদলে দেওয়া Auto Scaling group, আর দুই বা তার বেশি AZ। কোনো একটা instance বা AZ site বন্ধ করতে পারে না।
- Performance efficiency: ওপরে না বাড়িয়ে পাশে বাড়ানো, আর এমন capacity যেটা মিনিটে মিনিটে load-এর পিছু নেয়।
- Cost optimisation: রাতে scale in, সবসময় চালু minimum-এর জন্য commitment, তার ওপরে Spot, আর instance-এর যে public IPv4 লাগে না সেটা বাদ।
- Security: private instance, load balancer-ই একমাত্র public দরজা, আর security group যেটা ALB-র security group-কে source হিসেবে দেখায়।
- Operational excellence: হাতে বানানো বা হাতে বদলানো কোনো instance নেই; সবকিছু template থেকে চালু হয়, নিজে থেকেই বদলায়।
#কোথায় গোলমাল হয়
- লুকানো state। একটা instance দিয়ে পরীক্ষায় app দিব্যি পাস, তারপর কয়েকটা instance হলে বা একবার scale in হলেই user-রা logout হয়ে যায় বা upload হারায়। Scale out করার আগে খুঁজে দেখো memory-তে session বা local disk-এ file আছে কি না।
- State লুকাতে sticky session। Stickiness (লেসন ৬.৪) একজন user-কে বারবার একই instance-এ পাঠায়, তাই মনে হয় সমস্যা মিটে গেছে, যতক্ষণ না ওই instance terminate হয় আর তার session-গুলোও সাথে যায়। Load-ও এতে একপেশে হয়। Stickiness একটা জোড়াতালি, stateless design না।
- Instance এখনো public। ALB যোগ হয়েছে, কিন্তু instance-গুলোর public IP রয়ে গেছে, security group খোলা
0.0.0.0/0-এর জন্য। যে কেউ load balancer-কে পাশ কাটিয়ে ঢুকতে পারে, আর প্রতিটা public IPv4-এর দামও দিচ্ছ। - ASG শুধু EC2 health check-এ। ALB একটা instance-কে unhealthy বলছে, কিন্তু group সেটা রেখে দিচ্ছে, কারণ তার EC2 status check pass করছে। ELB health check type চালু করো (আর একটা যুক্তিসঙ্গত grace period দাও)।
- সব target এক AZ-এ, যদিও ALB দুটো AZ-এ (ওপরের সতর্কবার্তা দেখো)।
- AZ-এর মাপ কম। দুটো AZ মিলিয়ে ঠিক peak-এর সমান capacity: একটা AZ গেলে অর্ধেক capacity দিয়ে পুরো traffic সামলাতে হয়, যতক্ষণ না ASG পিছিয়ে পড়াটা পুষিয়ে নেয়।
- ALB-র IP address দিয়ে A record। ওগুলো বদলায়; Alias record ব্যবহার করো (apex না হলে CNAME-ও চলে)।
- “টাকা বাঁচাতে” minimum ১। একটা instance মানে single point of failure; minimum না কমিয়ে বরং সেটা reserve করো।
#System design-এ এর ব্যবহার
- AWS-এ একটা web বা API tier-এর default চেহারা এটাই, আর এই chapter-এর প্রায় সব scenario-র ভিত্তি: DNS নাম → load balancer → কয়েকটা AZ-এ stateless compute → state managed service-এ।
- Container আর serverless-এও একই নিয়ম: ECS task, EKS pod আর Lambda function-ও stateless আর ফেলে দেওয়ার মতো হবে, এটাই প্রত্যাশা। বদলায় শুধু fleet কে সামলায়।
- Partner-এর allow-list-এর জন্য static IP লাগবে? ALB-র তো নেই। ব্যবহার করো Network Load Balancer, যার প্রতি AZ-এ একটা করে static IP থাকে আর প্রতিটায় একটা Elastic IP লাগানো যায়, অথবা ALB-র সামনে বসাও AWS Global Accelerator (পরের একটা chapter), যেটা দুটো static anycast IP দেয়।
- সারা পৃথিবীর জন্য লাগবে? পুরো stack-টা আরেকটা Region-এ বানাও, আর Route 53-এর latency বা failover record দিয়ে কোনটায় যাবে বেছে নাও (লেসন ৮.৩)।
- Stateless হওয়ার জন্যই deployment নিরাপদ: নতুন version-এর instance যেকোনো সময় যোগ করা যায়, পুরোনোগুলো সরানো যায় (লেসন ৯.৪-এ দেখবে Beanstalk-এর rolling আর immutable deployment)।
#নিজে করে দেখো
নিচের command-গুলো AWS CLI দিয়ে হাতে ধাপ ১, ২ আর ৪–৮ বানায়। ID-গুলো বানানো; নিজেরগুলো বসিয়ে নিও।
# ধাপ ১: একটা Elastic IP নাও আর instance-এ লাগাও
aws ec2 allocate-address --domain vpc
aws ec2 associate-address --instance-id i-0abc1234567890def --allocation-id eipalloc-0abc1234567890def
# ধাপ ২: scale up (stop, type বদল, start)। Elastic IP লেগেই থাকে।
aws ec2 stop-instances --instance-ids i-0abc1234567890def
aws ec2 wait instance-stopped --instance-ids i-0abc1234567890def
aws ec2 modify-instance-attribute --instance-id i-0abc1234567890def --instance-type '{"Value": "m5.large"}'
aws ec2 start-instances --instance-ids i-0abc1234567890def
# ধাপ ৪: কয়েকটা value আর ১ ঘণ্টা TTL সহ একটা simple A record
aws route53 change-resource-record-sets --hosted-zone-id Z0EXAMPLE12345 --change-batch '{
"Changes": [{ "Action": "UPSERT", "ResourceRecordSet": {
"Name": "api.whatisthetime.example", "Type": "A", "TTL": 3600,
"ResourceRecords": [{"Value": "198.51.100.21"}, {"Value": "198.51.100.22"}, {"Value": "198.51.100.23"}] } }] }'
# ধাপ ৫: security group-এর শিকল, ALB -> instance
aws ec2 create-security-group --group-name alb-sg --description "ALB" --vpc-id vpc-0abc1234
aws ec2 authorize-security-group-ingress --group-id sg-0a11b22c33d44e55f --protocol tcp --port 443 --cidr 0.0.0.0/0
aws ec2 create-security-group --group-name web-sg --description "Web instances" --vpc-id vpc-0abc1234
aws ec2 authorize-security-group-ingress --group-id sg-0f55e44d33c22b11a --protocol tcp --port 80 \
--source-group sg-0a11b22c33d44e55f
# ধাপ ৫ আর ৭: ALB-র কমপক্ষে দুটো AZ-এর subnet লাগে
aws elbv2 create-load-balancer --name time-alb --type application \
--subnets subnet-0aaa1111 subnet-0bbb2222 --security-groups sg-0a11b22c33d44e55f
aws elbv2 create-target-group --name time-tg --protocol HTTP --port 80 --vpc-id vpc-0abc1234 \
--health-check-path /health --health-check-interval-seconds 10 --unhealthy-threshold-count 2
# ধাপ ৬ আর ৭: দুটো AZ-এর দুটো private subnet জুড়ে ASG, ELB health check সহ
aws autoscaling create-auto-scaling-group --auto-scaling-group-name time-asg \
--launch-template LaunchTemplateName=time-web,Version='$Latest' \
--min-size 2 --max-size 8 --desired-capacity 2 \
--vpc-zone-identifier "subnet-0ccc3333,subnet-0ddd4444" \
--target-group-arns arn:aws:elasticloadbalancing:us-east-1:111122223333:targetgroup/time-tg/0123456789abcdef \
--health-check-type ELB --health-check-grace-period 120
# ধাপ ৫: ALB-র দিকে Alias record (zone ID আর DNS নাম নাও describe-load-balancers থেকে)
aws elbv2 describe-load-balancers --names time-alb \
--query "LoadBalancers[0].[DNSName,CanonicalHostedZoneId]"
# ধাপ ৮: সবসময় চালু অংশের জন্য Savings Plan বা RI কত বাঁচাত?
aws ce get-savings-plans-purchase-recommendation --savings-plans-type COMPUTE_SP \
--term-in-years ONE_YEAR --payment-option NO_UPFRONT --lookback-period-in-days THIRTY_DAYS
তারপর একটা client থেকে আচরণটা দেখো:
dig +noall +answer api.whatisthetime.example # দ্বিতীয় column-এ TTL কমতে থাকে
for i in 1 2 3 4 5; do curl -s https://api.whatisthetime.example/; done # যেকোনো instance উত্তর দেয়
#সারসংক্ষেপ
- Stateless = server দুটো request-এর মাঝে client সম্পর্কে কিছুই রাখে না, তাই যেকোনো instance যেকোনো request-এর উত্তর দিতে পারে আর যেকোনো instance হারানো যায়। এর জন্য লাগে: memory-তে session নয়, local disk-এ দরকারি file নয়, শুধু একটা instance-এ থাকা data নয়। State সরে যায় শেয়ার করা store-এ (ElastiCache, DynamoDB, RDS, S3, EFS)।
- পরীক্ষার কৌশল: “data না হারিয়ে হাজারো instance-এ horizontally scale” → app stateless বানাও।
- Vertical scaling (t2.micro → m5.large)-এ EBS-backed instance stop আর start করতে হয়: downtime, একটা ছাদ, তবুও single point of failure। Elastic IP stop-এর পরেও থাকে।
- প্রতি instance-এ একটা Elastic IP দিয়ে scale হয় না: client-কে সব IP জানতে হয়, default quota Region-প্রতি ৫টা, প্রতিটা public IPv4-এর দাম ঘণ্টায় $০.০০৫, আর failover নেই।
- A record-এ কয়েকটা value দিলে একটা নাম পাওয়া যায়, কিন্তু client উত্তর cache করে TTL পর্যন্ত (TTL ৩,৬০০ হলে মরা IP এক ঘণ্টা পর্যন্ত ব্যবহার হতে পারে), আর simple routing-এ health check নেই।
- ALB + health check + Route 53 Alias: সেকেন্ডে failover, instance-এর IP কখনো cache হয় না, Alias কারণ ALB-র IP বদলায়। Instance হয়ে যায় private, তাদের security group ঢুকতে দেয় শুধু ALB-র security group থেকে।
- ASG সাথে ELB health check: নিজে থেকেই scale out, scale in আর বদলানো।
- Multi-AZ: ALB-র কমপক্ষে দুটো AZ লাগে; ASG-কে দুই বা বেশি AZ-এর subnet দাও, আর প্রতিটা AZ এমন মাপে রাখো যাতে বাকিরা peak সামলাতে পারে।
- খরচ: সবসময় চালু minimum reserve করো (RI বা Savings Plan), তার ওপরে On-Demand বা Spot; HA-র জন্য যতটা লাগে তার নিচে min কখনো নামিও না।
আগে নিজে উত্তর দাও, তারপর ব্যাখ্যাটা পড়ো। ঠিক হলেও পড়ো, কারণ ভুল Option-গুলো কেন ভুল, সেটাও ওখানে আছে।
কোন জিনিসটা একটা web application tier-কে stateless বানায়?
একটা team বলছে তাদের web tier stateless। কোন তথ্যটা প্রমাণ করে যে সেটা stateless না?
একটা stateless web tier তার instance-এ কোন দুটো জিনিস রাখা এড়িয়ে চলবে?
বেছে নাও ২
পরীক্ষায় প্রশ্ন এল, এমন application কীভাবে design করবে যেটা data না হারিয়ে হাজারো instance-এ horizontally scale করতে পারে। মূল design সিদ্ধান্ত কোনটা?
Elastic IP সহ একটা EBS-backed t2.micro-কে m5.large বানানো হচ্ছে। কী ঘটে?
whatisthetime.example চলছে Elastic IP সহ একটা m5.large-এ। রাত ০২:০০-এ নিচের host নষ্ট হলো। ফলাফল কোনটা সবচেয়ে ঠিকভাবে বলে?
চারটা web instance-এর প্রত্যেকটার একটা Elastic IP, সবগুলো পুরো মাস (৭৩০ ঘণ্টা) চলে। এখনকার দামে তাদের public IPv4 address-এর মাসিক খরচ কত?
একটা team এক Region-এ আটটা instance-এ scale out করতে চায়, প্রত্যেকটার নিজের Elastic IP সহ। প্রথমে কোন বাধায় পড়বে?
api.example.com-এর একটা simple A record-এর TTL ৩,৬০০ সেকেন্ড। একটা resolver সেটা ১৪:১০-এ cache করল। Record-এর একটা instance ১৪:২০-এ মরল, আর ১৪:২৫-এ তার value মুছে দেওয়া হলো। ওই resolver কখন পর্যন্ত মরা address বিলি করতে পারে?
একটা simple A record-এ তিনটা instance-এর IP। একটা instance নষ্ট হলো। Route 53 কী করে?
কয়েকটা A record value-র বদলে একটা load balancer আর Alias record বসালে কোন দুটো উন্নতি হয়?
বেছে নাও ২
Route 53-এ api.whatisthetime.example-কে একটা Application Load Balancer-এর দিকে কীভাবে দেখাবে?
একটা ALB-র IP address কেন A record-এ বসানো যাবে না?
Web instance-গুলো HTTP নেবে শুধু Application Load Balancer থেকে। তাদের security group-এর inbound rule কীভাবে লিখবে?
একটা security review-তে দেখা গেল, ALB-র পেছনের instance-গুলোর এখনো public IP আছে, আর security group port 80-তে 0.0.0.0/0-এর জন্য খোলা। সবচেয়ে ভালো সমাধান কোনটা?
একটা instance-এর web server আটকে গেছে। ALB তাকে unhealthy ধরে traffic পাঠানো বন্ধ করেছে, কিন্তু Auto Scaling group তাকে কখনো বদলাচ্ছে না। কেন?
একজন engineer মাত্র একটা Availability Zone-এর subnet দিয়ে একটা internet-facing Application Load Balancer বানাতে চাইল। কী হবে?
একটা ALB চালু আছে AZ a আর AZ b-তে। তার Auto Scaling group বানানো হয়েছিল একটা subnet দিয়ে, AZ a-তে। AZ a নষ্ট হলো। কী হয়, আর সমাধান কী?
Peak-এ whatisthetime.example-এর ৬টা instance লাগে। এটা ৩টা Availability Zone-এ চলে, আর যেকোনো একটা AZ নষ্ট হলেও পুরো peak capacity রাখতে হবে। মোট কমপক্ষে কয়টা instance লাগবে?
একটা Auto Scaling group চলে min ৪ (প্রতি AZ-এ ২টা, high availability-র জন্য দরকার) আর max ১২ নিয়ে, আর প্রায় প্রতি বিকেলে বেড়ে যায়। Requirement ঠিক রেখে কেনার কোন উপায়টা সবচেয়ে সাশ্রয়ী?
সবসময় চালু দুটো instance-এর On-Demand দাম প্রত্যেকটার ঘণ্টায় $০.০৯৬, মাসে চলে ৭৩০ ঘণ্টা। ৩ বছরের একটা commitment-এ দাম ৬০% কম পড়ত। মাসে মোটামুটি কত বাঁচে?
একটা stateless web tier-এর minimum-এর ওপরের instance-গুলো কেন নিশ্চিন্তে Spot-এ চালানো যায়?
whatisthetime.example-এর শেষ design নিয়ে কোন দুটো কথা সত্য?
বেছে নাও ২
একজন partner তোমার API-র জন্য শুধু স্থির IP address allow-list করতে পারে, আর API চলে একটা ALB-র পেছনে। কী করবে?
Instance-গুলোকে private subnet-এ সরানো, তাদের public IP সরিয়ে দেওয়া আর শুধু ALB-র security group থেকে traffic ঢুকতে দেওয়া মূলত কোন Well-Architected pillar-এর উন্নতি?
একটা simple Route 53 A record-এ কয়েকটা value দিয়ে web app scale করলে কোন দুটো সত্যিকারের সমস্যা?
বেছে নাও ২
রাতে Auto Scaling group scale in করার পরে কিছু user দেখল তাদের upload করা profile photo নেই। কারণ কী?
একজন developer বলছে: আমরা sticky session চালু করেছি, তাই আমাদের app এখন stateless। এই কথায় ভুলটা কোথায়?
এই web tier-এর জন্য শুধু vertical scaling কেন ভালো না, তার কারণ হিসেবে কোনটা ঠিক নয়?
একটা ALB আর তার Auto Scaling group যে দুটো AZ ব্যবহার করে, তার একটা নষ্ট হলে কোন দুটো ঘটনা ঘটে?
বেছে নাও ২
ধাপ ১-এ একমাত্র instance-টাতে সাধারণ auto-assigned public IP-র বদলে একটা Elastic IP লাগানো হয়েছে। এতে মালিকেরা কী পায়?