এই পর্বে যা শিখবেন
- Block, file আর object storage-এর মডেল, আর কোন provider-এ কোনটির কী নাম
- IOPS, throughput আর latency থেকে হিসাব করে বলা, কোন সীমায় কাজ আটকে আছে
- Database-এর একটি লেখা, দুই VM-এর ভাগ করা ফাইল আর একটি PUT-এর পথ ধাপে ধাপে
- Durability আর availability-র পার্থক্য, আর “এগারো nine”-এর আসল অর্থ
- ১ TB ডেটার মাসিক বিল আর ছয়টি সাধারণ কাজের জন্য ঠিক storage বাছাই
১ · তিন রকম storage, তিনটি আলমারি
পর্ব ১৯ পর্যন্ত আমরা বারবার বলেছি, state বাইরে রাখুন। Autoscaling একটি VM মুছে দিতে পারে, container যেকোনো সময় নতুন করে উঠতে পারে। তাহলে ডেটা থাকবে কোথায়? Cloud এখানে একটি নয়, তিন রকম উত্তর দেয়। একটি অফিসের কথা ভাবলে তিনটিই সহজ হয়ে যায়।
নিজের আলমারি (block): আপনার ঘরে তাক-নম্বর দেওয়া একটি আলমারি। আপনি যেভাবে খুশি গোছাবেন, যেকোনো তাক থেকে একটি কাগজ বদলাবেন। চাবি শুধু আপনার কাছে, আর আলমারিটি এই ঘর ছেড়ে নড়ে না।
অফিসের ভাগ করা আলমারি (file): সবার জন্য লেবেল-লাগানো ফোল্ডার। “হিসাব/২০২৬/অক্টোবর” বললেই সবাই একই কাগজ পান। তবে দুজন একই কাগজে লিখতে গেলে নিয়ম লাগে, আর আলমারি থেকে হেঁটে আনতে একটু সময় যায়।
গুদামের রসিদ-নম্বর দেওয়া বাক্স (object): বিশাল গুদামে পুরো বাক্স জমা দিলেন, একটি রসিদ-নম্বর পেলেন। ওই নম্বর দেখালে পুরো বাক্স ফেরত আসে। গুদাম প্রায় সীমাহীন আর সস্তা। কিন্তু বাক্সের ভেতরের একটি কাগজ বদলাতে চাইলে নতুন একটি পুরো বাক্স জমা দিতে হয়।
তিনটি মডেল পাশাপাশি
Block, file and object: who connects, and how data is addressed
img/ দেখতে ফোল্ডারের মতো, কিন্তু আসলে পুরো নামটিই একটি key.একই তিন মডেলের নাম provider-ভেদে আলাদা। নিচের টেবিলটি সবচেয়ে পরিচিত সেবাগুলোর একটি মানচিত্র। নাম আর ধরন সময়ের সাথে বদলায়, তাই provider-এর পাতা দেখে নেবেন।
| মডেল | AWS | Azure | Google Cloud |
|---|---|---|---|
| Block | EBS | Managed Disks | Persistent Disk |
| File | EFS | Azure Files | Filestore |
| Object | S3 | Blob Storage | Cloud Storage |
Amazon S3 চালু হয় ২০০৬ সালে, EC2-র কয়েক মাস আগে। মজার ব্যাপার, EC2-র শুরুতে টেকসই disk ছিল না: VM-এর সাথে ছিল শুধু instance store, VM গেলে ডেটাও যেত। EBS আসে ২০০৮ সালে। আর ফাইল ভাগ করার ধারণাটি cloud-এর চেয়ে অনেক পুরোনো: NFS Sun Microsystems আনে ১৯৮০-র দশকে।
২ · Block storage — VM-এর নিজের disk
Block storage VM-কে একটি সাধারণ disk দেখায়। VM জানে শুধু “block ৪-এ এই ৮ KB লেখা হবে”। ফাইল, ফোল্ডার, নাম, এগুলো disk জানে না। সেগুলো VM-এর ভেতরের filesystem (ext4, xfs, NTFS) বানায়। এজন্য block storage-এর ওপর আপনি যা খুশি চালাতে পারেন: filesystem, database, এমনকি পুরো OS. Boot volume-ও এমনই একটি disk.
Cloud-এ একটি block disk-কে বলে volume. বাস্তবে সেটি সাধারণত VM-এর host-এ লাগানো নয়। ডেটা থাকে আলাদা storage server-এ, network পেরিয়ে। এই বিচ্ছিন্নতা থেকেই তিনটি বড় সুবিধা:
- VM মরলেও ডেটা থাকে: Volume খুলে আরেকটি VM-এ লাগানো যায়।
- আকার বদলানো যায়: VM না থামিয়েই অনেক সময় volume বড় করা যায়, তারপর ভেতরের filesystem-ও বড় করতে হয়। ছোট করা সাধারণত যায় না।
- Snapshot: Volume-এর একটি মুহূর্তের ছবি রাখা যায়। AWS-এর ডকুমেন্টেশন অনুযায়ী EBS snapshot জমা থাকে S3-তে, আর incremental হয়, অর্থাৎ পরের snapshot-এ শুধু বদলানো block যায়।
দুটি সীমাও মনে রাখুন। প্রথমত, সাধারণ volume একটি zone-এ বাঁধা, অর্থাৎ ঠিক যে availability zone-এ VM, সেখানেই থাকতে হয়। অন্য zone-এ নিতে হলে snapshot থেকে নতুন volume বানানোই সাধারণ পথ। Azure-এর zone-redundant disk আর Google-এর regional Persistent Disk-এর মতো ব্যতিক্রম আছে, যাদের দাম আর আচরণ আলাদা।
দ্বিতীয়ত, সাধারণত এক সময়ে এক VM. Provider-রা multi-attach সুবিধা দেন, কিন্তু দুই VM একই ext4 একসাথে mount করলে দুজনেই নিজের মতো metadata বদলাবে, আর filesystem নষ্ট হবে। এটি নিরাপদ শুধু ক্লাস্টার-সচেতন সফটওয়্যারের সাথে। ভাগ করাই লক্ষ্য হলে file storage নিন।
লোকাল instance store আর network volume এক জিনিস নয়। প্রথমটি দ্রুত, কিন্তু VM বন্ধ বা host ছাড়লে ডেটা হারাতে পারে (পর্ব ১৫)। Instance type-এর নামে “d” বা “NVMe disk” দেখে সেখানে database রাখার আগে নিশ্চিত হোন, ডেটা কোন disk-এ যাচ্ছে।
একটি volume বানানো আর লাগানো
নিচে AWS CLI-র উদাহরণ, মূল ধাপগুলো দেখানোর জন্য। Azure আর Google Cloud-এ ধাপ একই, কমান্ড আলাদা। এটি চালানোর দরকার নেই। চালালে volume-এর বিল শুরু হবে, এমনকি VM বন্ধ থাকলেও।
# Fake ids. Costs money if run on a real account.
aws ec2 create-volume --availability-zone ap-south-1a \
--size 100 --volume-type gp3 --iops 3000 --throughput 125
aws ec2 attach-volume --volume-id vol-0123456789abcdef0 \
--instance-id i-0123456789abcdef0 --device /dev/sdf
# Inside the VM. mkfs ERASES the disk: check the name first.
lsblk
sudo mkfs.ext4 /dev/nvme1n1
sudo mkdir -p /data
sudo mount /dev/nvme1n1 /data
# Clean up
sudo umount /data
aws ec2 detach-volume --volume-id vol-0123456789abcdef0
aws ec2 delete-volume --volume-id vol-0123456789abcdef0একটি বাস্তব ফাঁদ: --device /dev/sdf লিখলেও ভেতরে নাম হতে পারে /dev/nvme1n1. তাই mkfs-এর আগে lsblk দেখে নিশ্চিত হোন। আর স্থায়ী mount-এর জন্য /etc/fstab-এ device-এর নাম নয়, UUID লিখুন, কারণ reboot-এ নাম বদলাতে পারে। /etc/fstab নিয়ে বিস্তারিত আছে পর্ব ৮-এ।
Volume-এর ধরন: সাধারণ বনাম provisioned
প্রতিটি provider কয়েক ধরনের volume দেন। মূল ভাগ দুটি। General-purpose volume বেশিরভাগ কাজের জন্য। Provisioned IOPS volume-এ আপনি ঠিক করে দেন কত IOPS চান, আর তার জন্য আলাদা দাম দেন। HDD-ভিত্তিক সস্তা ধরনও আছে, লম্বা sequential পড়ার জন্য।
| ধরন | উদাহরণ (লেখার সময়ে) | কখন |
|---|---|---|
| General-purpose SSD | gp3, Standard/Premium SSD, pd-balanced | Boot, ওয়েব অ্যাপ, ছোট-মাঝারি database |
| Provisioned IOPS SSD | io2, Premium SSD v2, Ultra Disk, Hyperdisk Extreme | মাপা চাহিদায় ব্যস্ত database |
| Throughput HDD | st1, Standard HDD, pd-standard | লম্বা sequential log বা batch |
পুরোনো প্রজন্মে IOPS volume-এর আকারের সাথে বাঁধা থাকত, আর burst credit ফুরোলে গতি হঠাৎ পড়ে যেত। নতুন অনেক ধরনে আকার আর গতি আলাদা করে কেনা যায়। আপনার ধরনে কোনটি প্রযোজ্য, সেটি ডকুমেন্টেশনে দেখে নেবেন।
Database-এর একটি লেখার যাত্রা
একটি অ্যাপ COMMIT বলল। “সফল” উত্তর আসার আগে ঠিক কী ঘটে? নিচের ঘড়ির মানগুলো অনুমিত, শুধু আকার বোঝানোর জন্য। বাস্তবে যন্ত্র আর ধরনভেদে আলাদা। শেষ সারিটি খেয়াল করুন: এই মুহূর্তে VM মরলে কী হতো।
- Database
WAL bufferRAM - VM-এর OS
page cacheRAM - Host
NVMe queueপথে - Network
storage linkপথে - Storage server
৩ কপিটেকসই
| ঘড়ি (ms) | |
| ডেটা কোথায় | |
| এখন VM মরলে | |
| অ্যাপ কী জানে |
- WAL record তৈরি। Database আগে মূল টেবিল বদলায় না। সে পরিবর্তনের বিবরণ WAL (write-ahead log)-এ লেখে। ঘড়ি 0.00 ms, ডেটা শুধু database-এর RAM-এ।
write()call. Record গেল OS-এর page cache-এ। প্রোগ্রাম ভাবতে পারে লেখা শেষ, কিন্তু এটি এখনো RAM. ঘড়ি 0.02 ms.fsync()call. fsync মানে “ডেটা disk-এ না পৌঁছানো পর্যন্ত প্রোগ্রাম অপেক্ষা করবে”। OS volume-কে NVMe command পাঠাল। ঘড়ি 0.05 ms.- Network পার। VM-এর কাছে এটি disk, কিন্তু host command-টি network-এ storage server-এর দিকে পাঠায়। ঘড়ি 0.30 ms. এই পথটুকুই লোকাল disk-এর সাথে মূল পার্থক্য।
- কপিগুলো লেখা হলো। Storage server একই zone-এর একাধিক যন্ত্রে ডেটা রাখল (“৩ কপি” এখানে উদাহরণ)। ঘড়ি 0.90 ms. VM এখনো উত্তর পায়নি, তবু এখন VM মরলেও ডেটা volume-এ আছে।
- Ack ফিরল।
fsync()ফিরল। ঘড়ি 1.15 ms. অনুমিত হিসাবে এর প্রায় পুরোটাই network আর storage-এর সময়। - COMMIT সফল। ঘড়ি 1.20 ms-এ অ্যাপ উত্তর পেল। মূল টেবিলের ৮ KB page পরে ধীরে লেখা হবে। Crash হলে নতুন VM-এ এই volume লাগিয়ে database WAL থেকে পরিবর্তনটি আবার প্রয়োগ করবে (DBMS কোর্সের recovery).
৩ · IOPS, throughput আর latency — তিনটি আলাদা সীমা
একটি ঘাটের কথা ভাবুন। IOPS হলো প্রতি সেকেন্ডে কতবার নৌকা ছাড়ে। Block size হলো প্রতি নৌকায় কত মাল। Throughput হলো সেকেন্ডে মোট কত মাল পার হলো। আর latency হলো একটি নৌকার পার হতে কত সময় লাগে। ছোট নৌকা ঘনঘন চললেও মাল কম পার হয়। আবার ঘাট চওড়া হলেও পন্টুন সরু হলে আটকে যায়।
৩,০০০ IOPS × ১৬ KB = ৪৮ MB/s
একটি volume-এ সাধারণত দুটি সীমাই থাকে, আর যেটিতে আগে ঠেকে সেটিই আপনার আসল সীমা। ধরি ৩,০০০ IOPS আর ১২৫ MB/s. ৪ KB-তে ৩,০০০ × ৪ KB = ১২ MB/s, অর্থাৎ IOPS আগে ফুরায়। ২৫৬ KB-তে IOPS-এর হিসাবে ৭৬৮ MB/s হওয়ার কথা, কিন্তু throughput ১২৫ MB/s-এ থামে, তাই আসল IOPS ১২৫,০০০ ÷ ২৫৬ ≈ ৪৮৮. দুই সীমা মেলে ১২৫,০০০ ÷ ৩,০০০ ≈ ৪১.৭ KB-তে।
কোন সীমা কোথায় ধরে
Achievable MB/s vs I/O size on a 3,000 IOPS, 125 MB/s volume (assumed)
আরও দুটি সীমা, যা বিলে লেখা থাকে না
VM-এর নিজের সীমা: প্রতিটি instance type-এর storage bandwidth-এর একটি সীমা আছে। ৫০০ MB/s-এর volume ছোট VM-এ লাগালে VM-ই থামিয়ে দেবে।
Queue depth: Little's law বলে, IOPS = একসাথে চলা I/O ÷ latency. Database যদি একটির পর একটি fsync করে, queue depth ১, latency ১ ms, তবে সর্বোচ্চ ১,০০০ IOPS. Volume ১৬,০০০ IOPS দিলেও লাভ নেই। নিচের সিমুলেটরে চারটি সীমাই আছে। সবচেয়ে ছোটটিই জেতে।
// Which limit binds? Every number is an ASSUMED example
const vol = { iops: 3000, mbps: 125 }; // general-purpose volume
const vmMbps = 250; // the VM's own storage limit
const cases = [ // queue depth, latency in ms
{ name: "db 8 KB, 1 thread", kb: 8, qd: 1, ms: 1.0 },
{ name: "db 8 KB, 32 queued", kb: 8, qd: 32, ms: 1.0 },
{ name: "mixed 16 KB", kb: 16, qd: 32, ms: 1.0 },
{ name: "scan 64 KB", kb: 64, qd: 32, ms: 1.0 },
{ name: "backup 256 KB", kb: 256, qd: 16, ms: 1.0 },
];
function solve(v, vm, c) {
const limits = [ // each limit, as I/O per second
["queue", c.qd * 1000 / c.ms], // Little: depth / latency
["volume IOPS", v.iops],
["volume MB/s", v.mbps * 1000 / c.kb],
["VM MB/s", vm * 1000 / c.kb],
].sort((a, b) => a[1] - b[1]);
const iops = limits[0][1];
return { iops, mbps: iops * c.kb / 1000, binds: limits[0][0] };
}
function report(title, v) {
console.log(title + ": " + v.iops + " IOPS, " + v.mbps + " MB/s, VM " + vmMbps + " MB/s");
for (const c of cases) {
const r = solve(v, vmMbps, c);
console.log(c.name.padEnd(20) + String(Math.round(r.iops)).padStart(6) + " IOPS"
+ r.mbps.toFixed(1).padStart(7) + " MB/s binds: " + r.binds);
}
}
report("general", vol);
report("provisioned", { iops: 16000, mbps: 500 });
console.log("knee block size = " + (vol.mbps * 1000 / vol.iops).toFixed(1) + " KB");general: 3000 IOPS, 125 MB/s, VM 250 MB/s
db 8 KB, 1 thread 1000 IOPS 8.0 MB/s binds: queue
db 8 KB, 32 queued 3000 IOPS 24.0 MB/s binds: volume IOPS
mixed 16 KB 3000 IOPS 48.0 MB/s binds: volume IOPS
scan 64 KB 1953 IOPS 125.0 MB/s binds: volume MB/s
backup 256 KB 488 IOPS 125.0 MB/s binds: volume MB/s
provisioned: 16000 IOPS, 500 MB/s, VM 250 MB/s
db 8 KB, 1 thread 1000 IOPS 8.0 MB/s binds: queue
db 8 KB, 32 queued 16000 IOPS 128.0 MB/s binds: volume IOPS
mixed 16 KB 15625 IOPS 250.0 MB/s binds: VM MB/s
scan 64 KB 3906 IOPS 250.0 MB/s binds: VM MB/s
backup 256 KB 977 IOPS 250.0 MB/s binds: VM MB/s
knee block size = 41.7 KB
দুটি জায়গায় চোখ রাখুন। প্রথম সারি দুই volume-এই ১,০০০ IOPS: দামি volume একক-থ্রেডের কাজে কিছুই বদলায়নি। আর provisioned অংশের শেষ তিন সারিতে সীমা volume নয়, VM. vmMbps ১০০০ করে আবার চালান: তখন scan আর backup-এর সীমা ৫০০ MB/s হবে। এখানে latency স্থির ধরা হয়েছে। বাস্তবে queue ভরলে latency বাড়ে, তাই এটি উপরের সীমা, নিশ্চিত গতি নয়।
লোকাল NVMe বনাম network storage
VM-এর সাথে লাগানো NVMe SSD-তে network-এর পথটুকু নেই। নিচের সংখ্যাগুলো শুধু মাত্রা বোঝানোর জন্য, যন্ত্র আর ধরনভেদে অনেক আলাদা হতে পারে।
| Storage | একটি ছোট I/O (আনুমানিক) | queue depth ১-এ সর্বোচ্চ IOPS |
|---|---|---|
| লোকাল NVMe | প্রায় ১০০ µs | প্রায় ১০,০০০ |
| Network block SSD | প্রায় ১ ms | প্রায় ১,০০০ |
| Network file share | কয়েক ms | কয়েকশো |
| Object (প্রথম বাইট) | দশ থেকে শতাধিক ms | প্রযোজ্য নয়, অনেক কাজ সমান্তরালে চলে |
তাহলে সব database লোকাল NVMe-তে নয় কেন? কারণ সেই disk host-এর ভাগ্যের সাথে বাঁধা। Host নষ্ট হলে ডেটাও যায়। তাই যেসব সিস্টেম নিজেরাই একাধিক node-এ ডেটা replicate করে, তারাই লোকাল NVMe-তে স্বচ্ছন্দ। আর cache, scratch ডেটা, সাময়িক ফাইল, এগুলোও ভালো প্রার্থী।
৪ · File storage — অনেক VM, একটি ফোল্ডার
File storage একটি পুরো filesystem network-এ দেয়। VM-এ একটি share mount করলে সেটি সাধারণ ফোল্ডারের মতো দেখায়। open, read, rename, ls সবই চলে, তাই পুরোনো সফটওয়্যার না বদলেই কাজ করে। Filesystem-এর দায়িত্ব এখানে VM-এ নয়, সার্ভারে। এই কারণেই অনেক VM একসাথে নিরাপদে ব্যবহার করতে পারে।
প্রোটোকল দুটি প্রধান। NFS এসেছে Unix জগৎ থেকে, Linux-এ সাধারণ। SMB মূলত Windows জগতের, ফাইল-শেয়ারিংয়ের পরিচিত পথ। AWS EFS মূলত NFS দেয়, Azure Files SMB আর NFS দুটোই দেয়, আর Google Filestore NFS দেয়। অনেক সেবা zone-জুড়ে mount করা যায়, তবে ধরনভেদে আলাদা।
# Fake hostname. Needs a real NFS share and firewall access.
sudo mkdir -p /mnt/shared
sudo mount -t nfs4 fs.example.internal:/ /mnt/shared
df -h /mnt/shared # now looks like a normal folder
ls -l /mnt/shared
sudo umount /mnt/sharedএটি জাদু নয়। প্রতিটি metadata-র কাজ, যেমন “এই ফাইল আছে কি না”, একটি network যাত্রা। তাই হাজার হাজার ছোট ফাইলের ls -R বা npm install এখানে হতাশাজনকভাবে ধীর। আর সেবাভেদে throughput আকারের সাথে বাঁধা থাকতে পারে: কম ডেটা রাখলে কম গতি।
দুই VM একই ফাইল খুললে কী হয়
ধরি web-1 একটি ৩ MB ইনভয়েস লিখছে, আর web-2 সেটি খুলতে চায়। NFS-এর সাধারণ আচরণের নাম close-to-open consistency: একজনের লেখা অন্যজন নিশ্চিতভাবে দেখবেন প্রথমজন বন্ধ করার পর দ্বিতীয়জন আবার খুললে। ক্লায়েন্টের cache এর কারণ। Provider আর mount option ভেদে সময় আলাদা হতে পারে।
| সার্ভারে | |
| web-1 দেখছে | |
| web-2 দেখছে |
- দুজনই mount করল।
web-1আরweb-2-এ একই share বসল/mnt/shared-এ। ফাইলটি এখনো নেই। - web-1 ফাইল বানাল।
open-এর অনুরোধ সার্ভারে গেল, সার্ভারে ফাইলটি হলো, আকার 0 B. - web-1 লিখল। ৩ MB গেল ক্লায়েন্টের cache-এ।
web-1নিজে 3 MB দেখছে, সার্ভারে এখনো 0 B. (ডেটা বড় হলে অংশবিশেষ আগেই সার্ভারে যেতে পারে, কিন্তু নিশ্চয়তাcloseপর্যন্ত নেই।) - web-2 খুলল। সে ফাইলটি পেল, কিন্তু আকার 0 B. ভুল নয়, close-to-open-এর প্রতিশ্রুতি এখনো শুরুই হয়নি।
- web-1 বন্ধ করল।
close-এ জমা ডেটা সার্ভারে গেল, এখন সেখানে 3 MB. কিন্তু আগে খোলাweb-2এখনো 0 B দেখছে। - web-2 আবার খুলল। নতুন
open-এ ক্লায়েন্ট সার্ভারে ফাইলের অবস্থা যাচাই করল, আর পুরো 3 MB দেখল। এই “close তারপর open”-ই নিয়মের কেন্দ্র। - দুজনই লিখতে চায়।
web-1lock পেল,web-2অপেক্ষায়। কিন্তু এটি advisory lock: যে প্রোগ্রাম lock চায় না, সে সরাসরি লিখতে পারবে। তাই দুজনের কোডকেই নিয়মটি মানতে হবে।
নিচু স্তরের কারণটি জানতে চাইলে OS কোর্সের file system interface দেখুন। মনে রাখার কথা একটিই: file share-এ “ফাইল সেভ হলো” আর “অন্য VM দেখল”-এর মাঝে অল্প ফাঁক থাকতে পারে।
৫ · Object storage — key, HTTP আর পুরো জিনিস
Object storage-এ আপনি একটি bucket-এর ভেতরে key দিয়ে পুরো জিনিস রাখেন। চারটি বৈশিষ্ট্য একে আলাদা করে:
- সমতল নামের জগৎ (flat namespace): ফোল্ডার নেই।
img/2026/a.pngএকটিই লম্বা key. Console যে ফোল্ডার দেখায়, সেটি/দিয়ে বানানো একটি সুবিধা মাত্র। - HTTP API: Mount নয়,
PUT,GET,DELETE,LIST. তাই যেকোনো ভাষা, যেকোনো জায়গা থেকে চলে, অনুমতি থাকলে। - অপরিবর্তনীয় (immutable) object: এক বাইট বদলাতেও পুরো object আবার লিখতে হয়। মাঝখানে লেখা বা append সাধারণত নেই। পড়ার বেলায় অংশবিশেষ (range request) আনা যায়।
- বিশাল মাপ: মোট জায়গার ব্যবহারিক সীমা প্রায় নেই। আপনাকে আগে থেকে আকার বলতে হয় না, যা রাখেন তারই বিল। তবে একটি object-এর সর্বোচ্চ আকার, প্রতি সেকেন্ডের অনুরোধ, এগুলোর সীমা আছে, যা provider-ভেদে আলাদা।
এই সীমাবদ্ধতাগুলো দুর্বলতা নয়, বরং দাম। Object বদলায় না বলে কপি মেলানো সহজ, আর hierarchy নেই বলে একটি metadata সার্ভারে ভিড় হয় না। ভেতরের নকশা, chunk, placement আর erasure coding দেখুন System Design কোর্সের Object storage পর্বে। এখানে আমরা API-র দিক থেকে দেখি।
- Client
HTTPSreport.csv - API gateway
signatureঅনুমতি - Storage
কয়েক deviceবাইট - Metadata
key → locationসূচি
PUT /reports/2026-10.csv HTTP/1.1 Host: example-bucket.objects.example.com Authorization: (signed request) Content-Length: 5000000 (৫ MB বাইট)
signature মিলল OK policy: PutObject OK bucket আছে OK
device-a zone-1 লেখা হলো device-b zone-2 লেখা হলো device-c zone-3 লেখা হলো metadata এখনো পুরোনো, GET নতুনটি পাবে না
reports/2026-10.csv -> version 1
HTTP/1.1 200 OK
ETag: "a1b2c3d4e5f6"
GET /reports/2026-10.csv HTTP/1.1
HTTP/1.1 200 OK
Content-Length: 5000000
ETag: "a1b2c3d4e5f6"
GET পুরো ৫ MB আনা লোকালে এক লাইন বদলানো PUT পুরো ৫ MB আবার পাঠানো ETag: "f6e5d4c3b2a1" (নতুন)
- Client PUT করল। অনুরোধের URL-এই bucket আর key. সাথে একটি signed request, যা প্রমাণ করে কে পাঠাচ্ছে। চাবিটি নিজে network-এ যায় না।
- Gateway যাচাই করল। Signature, IAM policy আর bucket, তিনটিই ঠিক আছে কি না। অনুমতি না থাকলে এখানেই
403. - বাইট লেখা হলো। কয়েকটি device-এ, সাধারণত একাধিক zone-এ। মোট ৩টি device এখানে উদাহরণ। Metadata এখনো বদলায়নি, তাই অর্ধেক-লেখা জিনিস কেউ দেখে না।
- Metadata বদলাল, উত্তর গেল। Key এখন নতুন জিনিসকে দেখায়। Client পেল
200 OKআর একটি ETag, এই সংস্করণের ছাপ। PUT পুরোটা সফল, অথবা কিছুই না। - অন্য VM GET করল। লেখা শেষ হওয়ার পরের পড়া, তাই একই ETag আর পুরো ৫ MB এলো। এই প্রতিশ্রুতির নাম read-after-write consistency.
- বদলাতে গেলে? এক লাইনের জন্যও পুরো ৫ MB আবার PUT. ETag বদলাল। Versioning বন্ধ থাকলে আগেরটি আর নেই। ঘনঘন বদলানো ডেটার জন্য object storage তাই ভুল জায়গা। বড় ফাইলের জন্য multipart upload আছে, পর্ব ২১-এ দেখবেন।
Consistency — সংক্ষেপে
তিন মডেলের প্রতিশ্রুতি আলাদা। Block-এ একজনই লেখেন, তাই প্রশ্ন সহজ: fsync ফিরলে ডেটা নিরাপদ। File-এ সাধারণত close-to-open. Object-এ এক key-এর জন্য read-after-write. AWS-এর ঘোষণা অনুযায়ী S3-এ এটি পুরোপুরি এসেছে ডিসেম্বর ২০২০ থেকে, আর লেখার সময়ে Azure Blob আর Google Cloud Storage-ও একই ধরনের প্রতিশ্রুতি দেয়। তবু দুটি ফাঁক থাকে: দুটি object একসাথে atomically বদলানোর ব্যবস্থা নেই, আর সামনে CDN থাকলে পুরোনো কপি কিছুক্ষণ আসতে পারে। তত্ত্বের জন্য System Design-এর CAP ও consistency দেখুন।
৬ · Durability বনাম availability — “এগারো nine” আসলে কী
দুটি প্রশ্ন আলাদা। Durability জিজ্ঞেস করে: ডেটা আছে তো? Availability জিজ্ঞেস করে: ডেটা এখন পাওয়া যাচ্ছে তো? ব্যাংকের লকারে গয়না নিরাপদ, কিন্তু ব্যাংক বন্ধের দিনে পাবেন না। সেদিন durability পুরো, availability শূন্য।
AWS তার প্রকাশিত FAQ-এ বলে, S3-এর সাধারণ storage এক বছরে ৯৯.৯৯৯৯৯৯৯৯৯% durability-র জন্য নকশা করা, অর্থাৎ এগারোটি nine. অন্য বড় provider-রাও একই ধরনের লক্ষ্য বলেন। সূত্রটি সরল: প্রতি object-এর বছরে হারানোর সম্ভাবনা p = ১০−১১, আর N সংখ্যক object-এ প্রত্যাশিত ক্ষতি N × p.
// Expected yearly loss from a durability figure (a design target)
function loss(objects, nines) {
const p = Math.pow(10, -nines); // chance one object is lost in a year
const expected = objects * p;
const atLeastOne = -Math.expm1(objects * Math.log1p(-p));
return { expected, atLeastOne, years: 1 / expected };
}
const fmt = (x) => x.toExponential(1);
console.log("objects nines lost/year P(any) one per years");
for (const [n, label] of [[1e7, "10 million"], [1e9, "1 billion"], [1e12, "1 trillion"]]) {
for (const nines of [9, 11]) {
const r = loss(n, nines);
console.log(label.padEnd(12) + String(nines).padStart(4) + fmt(r.expected).padStart(11)
+ fmt(r.atLeastOne).padStart(9) + fmt(r.years).padStart(14));
}
}
// A block volume fails as one unit, so the unit of loss is much larger
const afr = 0.002, volumes = 100, sizeGB = 500; // assumed yearly failure rate
const pAny = 1 - Math.pow(1 - afr, volumes);
console.log("100 volumes at AFR 0.2%: expected " + (afr * volumes).toFixed(1)
+ " per year, P(any) " + (pAny * 100).toFixed(1) + "%");
console.log("one failure takes " + sizeGB + " GB; a snapshot is the way back");
// Human error is outside the durability figure
const bad = 1e7 * 0.001; // a bad script deletes 0.1%
console.log("bad delete of 0.1% of 10 million: " + bad + " objects, at once");objects nines lost/year P(any) one per years
10 million 9 1.0e-2 1.0e-2 1.0e+2
10 million 11 1.0e-4 1.0e-4 1.0e+4
1 billion 9 1.0e+0 6.3e-1 1.0e+0
1 billion 11 1.0e-2 1.0e-2 1.0e+2
1 trillion 9 1.0e+3 1.0e+0 1.0e-3
1 trillion 11 1.0e+1 1.0e+0 1.0e-1
100 volumes at AFR 0.2%: expected 0.2 per year, P(any) 18.1%
one failure takes 500 GB; a snapshot is the way back
bad delete of 0.1% of 10 million: 10000 objects, at once
১ কোটি object আর এগারো nine-এ বছরে ০.০০০১টি, অর্থাৎ গড়ে ১০,০০০ বছরে একটি। এটিই AWS-এর FAQ-এর পরিচিত উদাহরণ। কিন্তু ১ লক্ষ কোটি (১ trillion) object-এ বছরে ১০টি, তাই “কখনো হারাবে না” ধরে নকশা করবেন না।
Block volume-এর হিসাবের একক আলাদা: annual failure rate (AFR) বলে পুরো volume ব্যর্থ হওয়ার হার। ০.২% (অনুমিত) হলে ১০০টি volume-এ এক বছরে কমপক্ষে একটি যাওয়ার সম্ভাবনা ১৮.১%. আর শেষ লাইনটি আসল শিক্ষা: নিজের ভুল স্ক্রিপ্ট এক সেকেন্ডে যা করে, তা এগারো nine ঢেকে রাখে না।
তিনটি সতর্কতা:
- এটি নকশার লক্ষ্য, চুক্তি নয়। সংখ্যাটি একটি মডেলের ফল, যা স্বাধীন ব্যর্থতা ধরে নেয়। SLA সাধারণত availability নিয়ে হয়, আর ক্ষতিপূরণ সাধারণত service credit.
- বাস্তবের ঝুঁকি একসাথে আসে। একই ব্যাচের disk, একটি ভুল release, এগুলো correlated failure, যা মডেলের অনুমান ভাঙে।
- Durability ভুল মোছা ঠেকায় না। আপনার
DELETE-ও store নিখুঁতভাবে মানে। Versioning আর আলাদা account-এ backup দেখবেন পর্ব ২১ আর পর্ব ২৪-এ।
Availability-র সংখ্যা সাধারণত অনেক কম, যেমন তিন বা চার nine-এর ঘরে, আর storage class-ভেদে আলাদা। ফেব্রুয়ারি ২০১৭-র S3 ঘটনাটি এর ক্লাসিক উদাহরণ। AWS-এর প্রকাশিত বিবরণ অনুযায়ী, একটি কমান্ডে ভুল ইনপুটের কারণে একটি region-এ প্রয়োজনের চেয়ে বেশি server সরে যায়, আর কয়েক ঘণ্টা S3 ব্যাহত হয়। ডেটা হারানোর কথা সেখানে বলা হয়নি: availability গিয়েছিল, durability নয়।
৭ · খরচ — জায়গা, অনুরোধ আর বাইরে পাঠানো ডেটা
“প্রতি GB কত” দেখে storage বাছলে ভুল হবে। বিলের তিনটি অংশ:
- জায়গা: Block-এ আপনি যত GB কিনেছেন তার দাম, ভেতরে অর্ধেক ফাঁকা থাকলেও। File আর object-এ সাধারণত যত GB রেখেছেন তার দাম।
- অনুরোধ ও গতি: Object-এ প্রতি PUT আর GET-এর দাম। Provisioned volume-এ কেনা IOPS-এর দাম, ব্যবহার হোক বা না হোক।
- Data transfer: Internet-এ বাইরে যাওয়া ডেটা, অর্থাৎ egress. Zone-এর মধ্যে চলাচলেও অনেক সময় দাম লাগে।
নিচের সব দাম আমাদের ধরে নেওয়া গোল সংখ্যা, কোনো provider-এর বর্তমান দাম নয়। আসল হিসাবের আগে pricing পাতা দেখে নেবেন। ধরি ১ TB (১,০০০ GB) ডেটা এক মাস রাখব, আর ১,০০০ GB-র volume কিনেছি।
// One month, 1 TB of data. All prices are ASSUMED round numbers.
const P = { gp: 0.08, piopsGB: 0.12, perIops: 0.05, file: 0.30, obj: 0.02,
putM: 5, getM: 0.5, egress: 0.10 }; // $ per GB, per IOPS, per million
const GB = 1000, IOPS = 10000;
const patterns = [
{ name: "web files", put: 1, get: 20, out: 200 }, // millions, millions, GB
{ name: "tiny hot objects", put: 100, get: 1000, out: 200 },
];
function bill(p) {
const out = p.out * P.egress;
return {
"block general": GB * P.gp + out,
"block provisioned": GB * P.piopsGB + IOPS * P.perIops + out,
"file share": GB * P.file + out,
"object": GB * P.obj + p.put * P.putM + p.get * P.getM + out,
};
}
const usd = (x) => "$" + x.toFixed(2).padStart(8);
for (const p of patterns) {
console.log(p.name + ": PUT " + p.put + "M, GET " + p.get + "M, out " + p.out + " GB");
for (const [k, v] of Object.entries(bill(p)))
console.log(" " + k.padEnd(18) + usd(v) + " " + usd(v / GB) + " per GB");
}
// Object storage's request budget before it costs more than a general volume
const gap = GB * (P.gp - P.obj);
console.log("storage gap $" + gap + " = " + (gap / P.getM) + "M GET or "
+ (gap / P.putM) + "M PUT");web files: PUT 1M, GET 20M, out 200 GB
block general $ 100.00 $ 0.10 per GB
block provisioned $ 640.00 $ 0.64 per GB
file share $ 320.00 $ 0.32 per GB
object $ 55.00 $ 0.06 per GB
tiny hot objects: PUT 100M, GET 1000M, out 200 GB
block general $ 100.00 $ 0.10 per GB
block provisioned $ 640.00 $ 0.64 per GB
file share $ 320.00 $ 0.32 per GB
object $ 1040.00 $ 1.04 per GB
storage gap $60 = 120M GET or 12M PUT
প্রথম ধরনে object সবচেয়ে সস্তা: $২০ জায়গা, $৫ PUT, $১০ GET, $২০ egress, মোট $৫৫. দ্বিতীয় ধরনে একই ১ TB-র বিল $১,০৪০, কারণ $৫০০ PUT আর $৫০০ GET. একই ডেটা, অনুরোধের ধরন বদলাতেই সবচেয়ে সস্তাটি সবচেয়ে দামি হলো। শেষ লাইন বলে: এই দামে জায়গার সাশ্রয় ($৬০) ১২ কোটি GET বা ১.২ কোটি PUT-এই শেষ।
দুটি কথা হিসাবে নেই। Block আর file-এ ডেটা পরিবেশনের জন্য VM লাগবে, সেই বিল এখানে যোগ করিনি। আর আপনার নিজের চাহিদায় IOPS কম লাগলে provisioned-এর দাম নাটকীয়ভাবে কমবে। IOPS ৩,০০০ করে আবার চালান।
খরচের আরও গভীরে, যেমন storage class, ঠান্ডা ডেটা আর lifecycle, পর্ব ২১-এ। পুরো cloud বিলের ছবি পাবেন পর্ব ৭২-এ।
৮ · কোন কাজে কোনটি — access pattern দিয়ে বাছাই
ঠিক প্রশ্নটি “কোন storage ভালো” নয়। প্রশ্ন হলো ডেটা কীভাবে ব্যবহার হবে, অর্থাৎ access pattern. চারটি জিনিস জিজ্ঞেস করুন: কে কে পড়বে ও লিখবে? ডেটা বদলায় নাকি শুধু জমে? প্রতিটি I/O কত ছোট? আর latency কতটা জরুরি?
| কাজ | ধরন | বাছাই | কেন |
|---|---|---|---|
| Database | ছোট random I/O, fsync, কম latency | Block (অথবা managed database) | এক লেখক, অংশবিশেষ বদলানো, স্থির গতি। NFS-এ অনেক database চলতে পারে, কিন্তু নির্মাতার ডকুমেন্টেশন না দেখে নয় |
| ভাগ করা CMS আপলোড | অনেক VM পড়ে-লেখে, ফাইল বদলায় কম | Object, সামনে CDN. পুরোনো অ্যাপ হলে file share | Object-এ যেকোনো VM পায়, autoscaling সহজ। অ্যাপ path চাইলে file share না বদলেই চলে |
| Log | অবিরাম ছোট লেখা, পড়া কদাচিৎ | লোকাল/block-এ অল্প সময়, তারপর object | Object-এ append নেই, তাই ব্যাচ করে পাঠান। পর্ব ৬৪-তে পাইপলাইন |
| Backup | বড়, পড়া বিরল, হারানো চলবে না | Object, আলাদা region বা account-এ | সস্তা, টেকসই, VM থেকে আলাদা। পর্ব ২৪-এ RPO আর RTO |
| Static website | অনেক পড়া, কম বদল | Object, সামনে CDN | VM লাগে না, প্রায় সীমাহীন পাঠক। পর্ব ৩০ |
| ML dataset | বড় ফাইল, লম্বা পড়া, অনেক GPU node | Object মূল কপি, সাথে লোকাল NVMe cache | GPU অলস বসে থাকা দামি। অনেক সময় parallel file system-ও লাগে |
একজন লেখক, ছোট বদল, কম latency: block. অনেকে একই path চান: file. বাকি সব, বিশেষ করে বড়, প্রায়-না-বদলানো, অনেক পাঠকের ডেটা: object. সন্দেহ হলে object দিয়ে শুরু করুন।
Kubernetes-এ এই তিনটিই ফিরে আসবে PV আর PVC হয়ে, পর্ব ৪৭-এ। আর database নিজে চালাবেন কি না, সেই প্রশ্ন পর্ব ২২-এর।
আরও গভীরে: অনেক SSD volume-এ বড় I/O-র হিসাব সরল গুণের চেয়ে জটিল। যেমন AWS-এর ডকুমেন্টেশন বলে, পরপর ছোট sequential I/O একসাথে জুড়ে একটি IOPS গোনা হতে পারে, আর SSD-তে সর্বোচ্চ ২৫৬ KiB-কে একটি I/O ধরা হয়। তাই মাপার সেরা হাতিয়ার fio, আর আপনার নিজের অ্যাপ। p99 latency গড়ের চেয়ে বেশি কথা বলে, কারণ network storage-এর ধীরতম কয়েকটি I/O-ই database-কে আটকে রাখে।
পরীক্ষা ও ইন্টারভিউতে:
- Block, file, object-এর মূল পার্থক্য? ঠিকানা: block নম্বর, path, key. আর ভাগ করার ধরন: এক VM, অনেক VM, HTTP-তে যে কেউ।
- ৩,০০০ IOPS আর ১৬ KB-তে throughput? ৩,০০০ × ১৬ KB = ৪৮ MB/s, যদি volume-এর MB/s সীমা তার বেশি হয়।
- Durability আর availability-র পার্থক্য? প্রথমটি ডেটা টিকে থাকা, দ্বিতীয়টি এখন পাওয়া।
- এগারো nine মানে কী? বছরে প্রতি object-এ ১০−১১ ক্ষতির নকশা-লক্ষ্য। ১ কোটি object-এ গড়ে ১০,০০০ বছরে একটি।
- Object storage-এ database নয় কেন? অংশবিশেষ বদলানো যায় না, latency বেশি, আর প্রতি অনুরোধে দাম লাগে।
৯ · AI-এর যুগে storage বাছাই
AI সহজেই বলে দেয় “S3 ব্যবহার করুন”, কিন্তু সে আপনার access pattern, বিল আর ডেটার গুরুত্ব দেখে না। এই বিষয়ে তার সাধারণ ভুলগুলো হলো:
| AI-এর ভুল | ঝুঁকি | যাচাই |
|---|---|---|
| ছবি দেখাতে পুরো bucket public করে দেয় | ব্যক্তিগত ডেটা ফাঁস | Public access block চালু রাখা, CDN বা presigned URL ব্যবহার |
Policy-তে s3:* আর Resource: * | একটি চাবি চুরিতে সব গেল | নির্দিষ্ট bucket, নির্দিষ্ট কাজ (পর্ব ৩২) |
| কোডে access key বসিয়ে দেয় | Git-এ গোপন চাবি | Role আর temporary credential |
| না মেপেই provisioned IOPS | অকারণ বড় বিল | আগে metric দেখা: কোন সীমায় ঠেকেছে? |
| Egress আর request-এর দাম বাদ দেয় | বিল হিসাবের কয়েক গুণ | তিন অংশ আলাদা হিসাব, budget alert |
সতর্কতা ছাড়া aws s3 rm --recursive বা sync --delete | ডেটা মুছে যাওয়া | আগে --dryrun, versioning, ছোট prefix-এ পরীক্ষা |
| Mount option বা CLI flag বানিয়ে লেখে | Error, বা ভুল আচরণ | অফিসিয়াল ডকুমেন্টেশন, ফেলে-দেওয়া পরিবেশে পরীক্ষা |
AI-কে আগে সংখ্যা দিন, তারপর তুলনা চান। শেষের দাবিটি খেয়াল করুন: সে যেন ধরে নেওয়া জিনিসগুলো নিজেই বলে দেয়।
AI-এর storage-পরিকল্পনা হাতে পেলে — যাচাইয়ের চেকলিস্ট
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিয়ে নিজে কিছুক্ষণ ভাবুন, তারপর “→ উত্তর” চাপুন।
প্র ০১Amazon object storage আগে আনল, টেকসই disk দুই বছর পরে। সাধারণ disk তো সহজ মনে হয়, তাহলে উল্টো কেন?
দেখতে সরল হলেও টেকসই network disk বানানো object store-এর চেয়ে কঠিন। কারণটি প্রতিশ্রুতিতে।
S3 (২০০৬) খুব ছোট একটি প্রতিশ্রুতি দিয়েছিল: পুরো জিনিস রাখুন, পুরো জিনিস আনুন, মাঝে বদলানো নেই। অপরিবর্তনীয় জিনিসের কপি মেলানো সহজ, কারণ একবার লেখা হলে সেটি আর বদলাবে না। Latency-ও দশ বা শত ms হলে কেউ রাগ করে না। আর একটি ব্যর্থ PUT client আবার পাঠাতে পারে।
Block disk-এর প্রতিশ্রুতি বিশাল। যেকোনো block যেকোনো সময় বদলাতে পারে, প্রায় ১ ms-এ উত্তর চাই, আর fsync ফিরলে ডেটা নিরাপদ। উপরে একটি filesystem বা database বসে আছে, যে disk-এর উত্তরকে অন্ধভাবে বিশ্বাস করে। একটি লেখা হারালে পুরো filesystem-এর কাঠামো ভাঙতে পারে। আর বহু VM, বহু host-এ এই disk চালাতে হবে, ব্যর্থ server-এ চলমান disk সরিয়ে, ভেতরে কপি মিলিয়ে।
EC2-এর প্রথম দুই বছরে (২০০৬ থেকে ২০০৮) তাই VM-এর সাথে ছিল শুধু instance store. ডেটা রাখতে চাইলে নিজেকে replicate করতে হতো, বা S3-তে কপি পাঠাতে হতো। এই চাপ থেকেই একটি ধারণা জন্ম নেয়, যা আজ cloud-এর ভিত্তি: কম্পিউটিং আর storage আলাদা করে দেওয়া। EBS সেটিই করল। VM ফেলে দেওয়া যায়, ডেটা থাকে। Autoscaling আর “pets vs cattle”-এর চিন্তাও এই আলাদা করার ওপর দাঁড়িয়ে।
মূল উপলব্ধি: একটি সিস্টেম কতটা বড় হতে পারে, তা অনেকটাই ঠিক করে সে কত কম প্রতিশ্রুতি দেয়। ছোট প্রতিশ্রুতি বড় মাপ কেনে। প্রতিটি storage বাছাই আসলে একটি প্রতিশ্রুতি বাছাই।
প্র ০২এপ্রিল ২০১১-র EBS বিভ্রাট থেকে network disk-এর ঝুঁকি নিয়ে কী শেখার আছে? তাহলে কি লোকাল disk-এই ফিরে যাওয়া উচিত?
AWS-এর প্রকাশিত postmortem অনুযায়ী, ২০১১ সালের এপ্রিলে US East region-এর একটি zone-এ network পরিবর্তনের একটি ভুলে EBS node-গুলোর অনেকটি হঠাৎ নিজেদের কপি হারানোর মতো অবস্থায় পড়ে। প্রতিটি node নিজের ডেটা বাঁচাতে নতুন কপি বানাতে চাইল। এত node একসাথে একই কাজ করায় ফাঁকা জায়গা ফুরিয়ে গেল, আর “re-mirroring storm” তৈরি হলো। Volume আটকে গেল, তার ওপরের অনেক সেবা আটকে গেল, পুনরুদ্ধারে কয়েক দিন লাগল। Postmortem জানায়, ওই zone-এর খুব ছোট একটি অংশের volume আর ফেরানো যায়নি।
শিক্ষা তিনটি।
- নিরাপত্তা-ব্যবস্থাই ঝড় বানাতে পারে: প্রতিটি node ঠিক কাজ করেছে, একসাথে করাতেই বিপদ। এটি thundering herd-এর আরেক রূপ, যাকে পরে “metastable failure” নামেও আলোচনা করা হয়েছে।
- VM আর disk আলাদা মানে নতুন নির্ভরতা: VM সুস্থ, কিন্তু I/O আটকে থাকলে অ্যাপও আটকে। এই অবস্থা crash-এর চেয়েও খারাপ, কারণ health check অনেক সময় ধরতে পারে না।
- Zone কেন আছে: যাঁদের অ্যাপ অন্য zone-এও চলত, তাঁরা অনেক কম ভুগেছেন (পর্ব ৫)।
লোকাল disk-এ ফেরা উত্তর নয়। লোকাল NVMe-তে host-ই ব্যর্থতার একক, আর replication আপনার দায়িত্ব। একটি network volume-এ provider কপি রাখেন, কিন্তু তাঁর ভুল আপনার সব volume-এ একসাথে পড়তে পারে। লোকাল disk-এ ব্যর্থতা ছোট আর স্বাধীন, কিন্তু প্রতিটি মেরামত আপনার সফটওয়্যারকে করতে হয়। সঠিক প্রশ্ন: ব্যর্থতার সময় কে কপি দেবে, আর কতক্ষণে? দুই ধরনেই ঝুঁকি আছে, শুধু জায়গা আলাদা।
মূল উপলব্ধি: “Managed” মানে ব্যর্থতা নেই, এমন নয়। ব্যর্থতা নিয়ন্ত্রণের দায়িত্ব অন্য হাতে গেছে। আপনার নকশা যেন একটি zone-এর storage হারালেও চলে।
প্র ০৩ফেব্রুয়ারি ২০১৭-র S3 ঘটনায় status পাতাও ঠিকমতো কাজ করেনি। একটি storage সেবার বিভ্রাট এত দূর ছড়ায় কেন?
AWS-এর প্রকাশিত বিবরণ অনুযায়ী, একটি debugging কাজের সময় একজন কর্মী প্রতিষ্ঠিত playbook মেনে কমান্ড দেন, কিন্তু ভুল ইনপুটে প্রয়োজনের চেয়ে বেশি server সরে যায়। সেই server-গুলো S3-র গুরুত্বপূর্ণ subsystem চালাত। সেগুলো পুনরায় চালু করতে হলো, আর বহু বছরে অনেক বড় হওয়ায় চালু হতে প্রত্যাশার চেয়ে বেশি সময় নিল। AWS আরও জানায়, তার Service Health Dashboard-এর আপডেটও S3-র ওপর নির্ভরশীল ছিল, তাই শুরুতে ঘটনাটি সেখানে দেখানো যায়নি।
ছড়ানোর কারণ: object storage শুধু “ফাইল রাখার জায়গা” নয়। এটি ভিতের পাথর। Machine image, container layer, static website, log, deploy artifact, config, অনেক কিছুই এখানে থাকে। অন্য cloud সেবাও ভেতরে এর ওপর নির্ভর করে। তাই ক্ষতি সরাসরি গ্রাহকের চেয়ে অনেক দূর যায়।
এই ঘটনা থেকে তিনটি চর্চা শেখা যায়:
- গোপন নির্ভরতা খুঁজে বের করা: আপনার deploy কি একটি নির্দিষ্ট region-এর bucket থেকে script নামায়? সেই bucket বন্ধ থাকলে কি নতুন VM উঠবে (পর্ব ১৭)? ঠিক যখন autoscaling দরকার, তখনই আটকে যেতে পারে।
- ভুল কমান্ডের ক্ষতি সীমিত করা: AWS জানায়, তারা টুলটি বদলে ক্ষমতা ধীরে সরানো আর ন্যূনতম সীমার সুরক্ষা যোগ করেছিল। Blast radius কমানো মানুষের ওপর দোষ চাপানোর চেয়ে ভালো।
- Status পাতা আলাদা ভিতে: যা দিয়ে আপনি বিভ্রাট জানাবেন, তা যেন ওই বিভ্রাটে না পড়ে।
আর পুরো সময়ে durability ঠিক ছিল: ডেটা ছিল, শুধু পাওয়া যাচ্ছিল না। ব্যবসার কাছে অবশ্য দুটোই ব্যথা দেয়।
মূল উপলব্ধি: নকশা করার সময় জিজ্ঞেস করুন “এই সেবা এক ঘণ্টা না পেলে কী ভাঙবে?” যে উত্তরটি আপনাকে অবাক করবে, সেটিই আপনার গোপন single point of failure.
প্র ০৪Bucket-কে ফোল্ডারের মতো mount করার টুল তো আছে। তাহলে object storage-কে file system বানিয়ে নিলে সমস্যা কী?
Mount করা বাস্তবে সম্ভব। s3fs-এর মতো পুরোনো টুল আছে, আর AWS-এর Mountpoint for Amazon S3-র মতো নতুন টুলও আছে। Mountpoint নিজেই জানিয়ে দেয়, সব POSIX আচরণ তার লক্ষ্য নয়। সমস্যাটি টুলে নয়, মডেলের অমিলে।
- Rename: Filesystem-এ একটি ছোট metadata বদল। Object-এ সাধারণত কপি করে আগেরটি মোছা। ফোল্ডার rename মানে তার সব object-এর জন্য তা-ই, এতে সময়ও লাগে, আর মাঝপথে থামলে অর্ধেক অবস্থা থেকে যায়।
- অংশবিশেষ লেখা: ১ GB ফাইলের শেষে এক লাইন যোগ করা মানে পুরো object আবার লেখা। একটি log ফাইল এভাবে লিখলে কী হবে, ভেবে দেখুন।
- Metadata:
ls -lপ্রতিটি ফাইলের জন্য আলাদা অনুরোধ করতে পারে। আগের হিসাব মনে আছে? এখানে প্রতিটি অনুরোধের দাম আছে। - Lock:
flockবা atomic rename-এর ওপর ভরসা করা সফটওয়্যার ভুল আচরণ করতে পারে, অথবা নিঃশব্দে ডেটা নষ্ট করতে পারে।
তবে পড়ার কাজে এই টুলগুলো সত্যিই উপকারী। যেমন ML training-এ dataset পড়া, বা লম্বা sequential পড়া। এখানে মডেলের অমিল প্রায় নেই।
উল্টো দিকে একটি আকর্ষণীয় ধারা আছে। Apache Iceberg বা Delta Lake-এর মতো table format অপরিবর্তনীয় ফাইলের ওপরেই ডেটাবেসের মতো আচরণ বানায়: বদলানোর বদলে নতুন ফাইল লেখে, আর একটি metadata ফাইল বদলে পুরো পরিবর্তনটি একসাথে দৃশ্যমান করে। এরা object storage-কে file system ভান করায় না, বরং এর আসল বৈশিষ্ট্য ব্যবহার করে।
মূল উপলব্ধি: একটি মডেলের ওপর অন্য মডেল বসালে বাইরের নকশাটি পাওয়া যায়, ভেতরের খরচ যায় না। সিস্টেমের সাথে লড়াই না করে তার স্বভাব অনুযায়ী নকশা করুন।
প্র ০৫এগারো nine থাকলে আলাদা backup-এর দরকার কী? আর এই সংখ্যা কেউ কি মেপে প্রমাণ করতে পারেন?
প্রথমে মাপার প্রশ্ন। প্রতি object-বছরে ১০−১১ ক্ষতি সরাসরি মাপতে হলে ১০১১-এর অনেক গুণ object-বছর পর্যবেক্ষণ করতে হবে, আর তার সাথে প্রতিটি ক্ষতি গুনতে হবে। একটি provider-এর পক্ষে কিছু মাপা সম্ভব, কিন্তু বাইরের কেউ তা পারেন না। তাই সংখ্যাটি আসলে একটি মডেলের ফল: disk ব্যর্থতার হার, কপির সংখ্যা, মেরামতের গতি। বিস্তারিত হিসাব System Design-এর Object storage পর্বে আছে।
আর backup-এর দরকার, কারণ durability শুধু একটি ধরনের ঝুঁকির উত্তর দেয়।
- নিজের ভুল: একটি ভুল
DELETEসব কপিতে নিখুঁতভাবে কার্যকর হয়। ২০১৭ সালে GitLab-এর প্রকাশিত postmortem-এ একজন প্রকৌশলীর ভুল ডিরেক্টরি মোছা, আর বেশ কয়েকটি backup ব্যবস্থা কাজ না করার কথা আছে। Storage ত্রুটিহীন ছিল, ক্ষতি হয়েছিল মানুষের কাজে। - চুরি যাওয়া চাবি বা ransomware: আক্রমণকারী আপনার অনুমতি নিয়ে সব বদলে দেন। Store এটিকে বৈধ কাজ মনে করে।
- অ্যাকাউন্ট-স্তরের ঘটনা: বিল না দেওয়া, ভুল বন্ধ হওয়া, অথবা একই account-এর সব ডেটা একসাথে যাওয়া।
- পুরো জায়গা হারানো: মার্চ ২০২১-এ OVHcloud-এর Strasbourg data center-এ আগুনে প্রকাশ্য খবর অনুযায়ী কিছু গ্রাহক ডেটা হারান, বিশেষ করে যাঁদের backup একই জায়গায় ছিল। পুরো একটি ভবন হারানো তাই কল্পনার ঝুঁকি নয়, আর “কপি পাশেই রাখা” কতটা বিপজ্জনক, ঘটনাটি তা দেখায়।
তাই backup-এর লক্ষ্য কপি বাড়ানো নয়, স্বাধীনতা বাড়ানো: আলাদা account, আলাদা region, আর versioning বা মুছতে না-দেওয়া lock. আর পুরোনো 3-2-1 নিয়মটি এখনো কাজের: ৩টি কপি, ২ রকম মাধ্যম, ১টি অন্য জায়গায়।
মূল উপলব্ধি: Durability বলে যন্ত্র আপনার ডেটা হারাবে না। সে বলে না আপনি হারাবেন না। পর্ব ২৪-এ এই হিসাবই RPO আর RTO হয়ে আসবে।
অনুশীলন
প্রথমে নিজে হিসাব করুন বা ভাবুন, তারপর উত্তর মেলান। কোনো cloud account লাগবে না।
-
কোন সীমা (numerical): একটি volume দেয় ৬,০০০ IOPS আর ২৫০ MB/s, আর VM-এর storage সীমা ২০০ MB/s. (ক) ৮ KB I/O-তে সর্বোচ্চ কত MB/s, সীমা কোনটি? (খ) ১২৮ KB-তে কত MB/s আর কত IOPS? (গ) ১ TB ডেটা কপি করতে (খ)-এর গতিতে কত সময়? ধরে নিন queue depth সীমা নয়।
(ক) ৬,০০০ × ৮ KB = ৪৮ MB/s. এটি ২৫০ আর ২০০-র নিচে, তাই সীমা volume-এর IOPS.
(খ) IOPS-এর হিসাবে ৬,০০০ × ১২৮ KB = ৭৬৮ MB/s. Volume-এ ২৫০, VM-এ ২০০. সবচেয়ে ছোটটি ২০০ MB/s, তাই সীমা VM. IOPS = ২০০,০০০ ÷ ১২৮ ≈ ১,৫৬২.
(গ) ১,০০০,০০০ MB ÷ ২০০ MB/s = ৫,০০০ সেকেন্ড, অর্থাৎ ৮৩ মিনিট ২০ সেকেন্ড। Volume বদলালে এটি কমবে না, VM বদলাতে হবে।
-
ফলাফল আন্দাজ করুন: Versioning বন্ধ একটি ফাঁকা bucket-এ পরপর চলল: (১)
PUT logs/a.txtলেখা “one” (২)PUT logs/a.txtলেখা “two” (৩)DELETE logs/(৪)GET logs/a.txt(৫)LIST prefix=logs/. ধাপ ৪ আর ৫-এ কী আসবে?ধাপ ৪-এ আসবে “two”: দ্বিতীয় PUT পুরো জিনিসটি প্রতিস্থাপন করেছে, আর “one” চলে গেছে। ধাপ ৫-এ তালিকায় আসবে একটি key:
logs/a.txt.ধাপ ৩ কিছুই মোছেনি।
logs/কোনো ফোল্ডার নয়, আর ওই নামে কোনো key নেই। S3-ধাঁচের API-তে না-থাকা key মুছলেও সাধারণত সফল উত্তর আসে, এটাই চমক। পুরো “ফোল্ডার” মুছতে হলে প্রতিটি key-এর জন্য DELETE লাগে, যা CLI-র--recursiveআপনার হয়ে করে। ভুল prefix দিলে তাই সেটি বিপজ্জনক। -
নকশার সমালোচনা: একটি কাল্পনিক অনলাইন বাজার অ্যাপ load balancer-এর পেছনে দুটি VM-এ চলে। ব্যবহারকারীর আপলোড করা ছবি প্রতিটি VM-এর নিজের block volume-এর
/var/www/uploads-এ যায়। অভিযোগ: “ছবি কখনো দেখা যায়, কখনো 404”, আর autoscaling চালু করতে ভয় লাগে। কী সমস্যা, কী নকশা দেবেন?কারণ: ছবিটি শুধু যে VM নিয়েছে তার disk-এ আছে। Load balancer পরের অনুরোধ অন্য VM-এ পাঠালেই 404. Autoscaling নতুন VM আনলে তার disk ফাঁকা, আর scale-in-এ VM গেলে ছবিও যেতে পারে। সার্ভারগুলো এখন stateful.
ভালো নকশা: ছবি object storage-এ, সামনে CDN. অ্যাপ শুধু key মনে রাখে, database-এ। আপলোড হয় presigned URL দিয়ে সরাসরি browser থেকে (পর্ব ২১), অথবা VM হয়ে।
তাড়াহুড়োর বিকল্প: অ্যাপ বদলানো না গেলে দুই VM-এ file share mount করুন। এতে কোড না বদলেই সমস্যা মিটবে, তবে প্রতি GB দাম বেশি আর ফোল্ডারে লক্ষ ফাইল হলে ধীর। Sticky session দিয়ে লুকানো সমাধান নয়। প্রথমে পুরোনো ছবি কপি করে যাচাই, তারপর VM-এর disk থেকে সরানো।
-
মাপের ফল পড়ুন: ৩,০০০ IOPS-এর একটি volume-এ
fio --rw=randread --bs=16k --iodepth=32চালানোর নমুনা আউটপুট (বানানো, আসল রান নয়):read: IOPS=3000, BW=46.9MiB/s (49.2MB/s), আর গড় latency10.67 ms. অথচ এই volume-এর স্বাভাবিক latency প্রায় ১ ms. কোন সীমায় ঠেকেছে? Latency এত বেশি কেন?--iodepth=64করলে কী হবে?IOPS ঠিক ৩,০০০, তাই সীমা volume-এর IOPS.
fio-তে16kমানে ১৬ KiB, তাই ৩,০০০ × ১৬ KiB = ৪৬.৯ MiB/s, যা ৪৯.২ MB/s-এর সমান।Latency আসে Little's law থেকে: ৩২ ÷ ৩,০০০ = ১০.৬৭ ms. ৩২টি কাজ একসাথে চলছে, কিন্তু সেকেন্ডে ৩,০০০টির বেশি বের হতে পারে না। তাই প্রতিটি I/O-র বেশিরভাগ সময় সারিতে যায়।
--iodepth=64-এ IOPS প্রায় ৩,০০০-ই থাকবে, আর latency প্রায় ৬৪ ÷ ৩,০০০ ≈ ২১.৩ ms হবে। এটিই saturation-এর চিহ্ন। সমাধান: বেশি IOPS কেনা, অথবা database-এ cache আর query ঠিক করে I/O কমানো।
নিজেকে যাচাই করুন
ভুল হলে কারণসহ ব্যাখ্যা পাবেন, আবার চেষ্টাও করতে পারবেন।
ক্রমNetwork block volume-এ database-এর একটি COMMIT-এর ধাপগুলো সঠিক ক্রমে সাজান (▲▼ চেপে সরান)
- Database WAL record বানায়
write()দিয়ে record OS-এর page cache-এ যায়fsync()থেকে volume-এ command যায়- Storage server-এ কপিগুলো লেখা হয়
- Ack ফেরে,
fsync()শেষ হয় - অ্যাপ COMMIT সফল উত্তর পায়
দুটি Linux VM-এর একই ফোল্ডার path-এ ফাইল পড়া ও লেখা দরকার, আর সফটওয়্যারটি বদলানো যাবে না। কোনটি সবচেয়ে উপযুক্ত?
- একটি সাধারণ block volume দুই VM-এ লাগানো
- NFS file share
- Object storage
- Instance store
একটি volume-এর সীমা ৩,০০০ IOPS আর ১২৫ MB/s. প্রতিটি I/O ৬৪ KB হলে সর্বোচ্চ throughput কত? (1 MB = 1,000 KB, অন্য কোনো সীমা নেই)
- ১২ MB/s
- ১৯২ MB/s
- ১২৫ MB/s
- ৩১৭ MB/s
একটি database একটির পর একটি লেখা fsync করে (queue depth ১)। প্রতিটি লেখায় ২ ms লাগলে সেকেন্ডে সর্বোচ্চ কতটি লেখা হবে, volume ১৬,০০০ IOPS দিলেও?
- ৫০০
- ৫০
- ১৬,০০০
- ২০,০০০
একটি storage-এর durability লক্ষ্য বছরে এগারো nine (প্রতি object-এ ক্ষতির সম্ভাবনা 10−11). ১০০ কোটি (109) object রাখলে প্রত্যাশিত ক্ষতি কত?
- বছরে ১টি
- বছরে ০.০১টি, গড়ে ১০০ বছরে একটি
- গড়ে ১০,০০০ বছরে একটি
- কখনো একটিও হারাবে না
Object storage-এ রাখা ৫ MB-র একটি ফাইলের এক লাইন বদলাতে হবে। সাধারণ API-তে কী করতে হবে?
- শুধু সেই লাইনের বাইটগুলো PATCH করা
- Range header দিয়ে সেই অংশে PUT করা
- ফাইলটি জায়গায় রেখেই খুলে সম্পাদনা করা
- পুরো ফাইল আনা, বদলানো, আবার পুরোটা PUT করা
ধরে নেওয়া দাম: object storage $০.০২/GB-মাস, GET প্রতি মিলিয়নে $০.৫০, internet-এ egress $০.১০/GB. ১ TB (১,০০০ GB) ডেটা, মাসে ১০ কোটি GET আর ১০০ GB egress-এ মাসিক বিল কত?
- $২০
- $৭০
- $৮০
- $৫৩০
শব্দকোষ
লেখার মধ্যে ডটেড দাগ দেওয়া শব্দে মাউস রাখুন বা চাপুন, অর্থ দেখাবে। এই পর্বের সব নতুন শব্দ এখানে একসাথে:
মনে রাখুন
- Block: এক VM-এর disk, ঠিকানা block নম্বর। File: অনেক VM-এর ফোল্ডার, ঠিকানা path. Object: HTTP-তে পুরো জিনিস, ঠিকানা key.
- Throughput = IOPS × block size; সবচেয়ে ছোট সীমাই আসল সীমা, আর VM ও queue depth-ও সীমা।
- Durability মানে ডেটা টিকে থাকা, availability মানে এখন পাওয়া। এগারো nine নকশার লক্ষ্য, ভুল মোছার বিমা নয়।
- বিল = জায়গা + অনুরোধ ও গতি + data transfer. ছোট, ঘনঘন object-এ অনুরোধের দাম জায়গাকে ছাড়িয়ে যায়।
- Access pattern দিয়ে বাছুন, আর AI-এর পরামর্শে bucket private, হিসাব নিজে, মোছার আগে dry-run.
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- পর্ব ২১ · Object storage চালানো — bucket, versioning, lifecycle, storage class আর presigned URLপরবর্তী পর্বBucket-এর দৈনন্দিন কাজ আর খরচ কমানো।
- ক্লাউড কম্পিউটিং ও DevOps · কোর্স হোম৮১টি পর্বপুরো কোর্সের রোডম্যাপ।
- System Design · Object storageগভীরে যানMetadata, placement, erasure coding আর durability-র হিসাব।
- Operating Systems · RAIDপাশের ট্র্যাকএকাধিক disk-এ ডেটা ছড়ানো আর কপির মূল ধারণা।
- DBMS ও SQL · Recoveryপাশের ট্র্যাকWAL আর crash থেকে database ফেরানোর নিয়ম।