ব্লগে ফিরে যান
৩১ আগস্ট, ২০২৬Sergei Solod9 মিনিট পড়া

আমার VPS অনলাইন ছিল। তারপর Linux ডিস্ক রিডের জন্য 18 সেকেন্ড অপেক্ষা করতে শুরু করল

Production Linux debugging-এর একটি বাস্তব ঘটনা: VPS online ছিল, কিন্তু কার্যকর কাজ প্রায় থেমে গিয়েছিল। I/O pressure প্রায় 100% ছুঁয়েছিল, read latency 18.7 সেকেন্ড হয়েছিল, EXT4 ও Nginx blocked ছিল, অথচ backend প্রায় 3 ms-এ উত্তর দিচ্ছিল।

লিনাক্সDevOpsVPSপারফরম্যান্সডিবাগিং

ডিবাগিংয়ে যাওয়ার আগে একটি বিষয় পরিষ্কার করা দরকার: FDCServers সম্পর্কে আমার সামগ্রিক ধারণা খারাপ নয়। এটি কাউকে তাদের এড়িয়ে চলতে বলার review নয়, আর তাদের পুরো infrastructure বিচার করার চেষ্টাও নয়। আমার একটি VPS ছিল, একটি নির্দিষ্ট সময়ে, যেখানে একটি অস্বাভাবিক ও কঠিন সমস্যা হয়েছিল।

দীর্ঘ সময় VPS স্বাভাবিকভাবে কাজ করেছে এবং real production traffic সামলেছে। তারপর কিছু বদলে গেল। সাধারণ request অস্বাভাবিক ধীর হতে শুরু করল। Page প্রথমে ধীরে খুলত, পরে কখনও একেবারেই খুলত না। আবার কখনও failure ভালোভাবে inspect করার আগেই machine স্বাভাবিক দেখাতে শুরু করত।

সবচেয়ে খারাপ অবস্থায় আমি পেয়েছিলাম:

CPU iowait:       97–100%
I/O PSI full:     ~95–98%
read latency:     up to 18.7 seconds
flush latency:    up to 53.6 seconds
I/O queue depth:  128+

Nginx চলছিল। Backend চলছিল। VM online ছিল। কিন্তু কার্যকর কাজ প্রায় এগোচ্ছিল না।

Production failure বিরক্তিকর ছিল, কিন্তু debugging আমার সত্যিই ভালো লেগেছে। Linux-এর এই দিকটাই আমি পছন্দ করি: বাইরে থেকে system জীবিত দেখালেও kernel-এর একাধিক স্বাধীন interface বলে দিতে পারে কোথায় useful progress থেমেছে। এই লেখাটি সেই clues অনুসরণ করার গল্প, FDCServers ভালো না খারাপ provider সেটি বিচার করার নয়।

active (running) প্রায় অর্থহীন হয়ে গেল

আমি স্বাভাবিক checks দিয়েই শুরু করেছিলাম:

top
free -h
df -h
systemctl status nginx

Healthy সময়ে roughly এমন দেখতাম:

D-state processes: 0
CPU iowait:        ~0%
disk latency:      ~2–4 ms
I/O PSI some:      0.04
I/O PSI full:      0.04

শুধু তখন connect করলে VPS সম্পূর্ণ healthy মনে হতো। তারপর normal traffic ফিরে এসে state পুরো বদলে দিত। Intermittent failure-এর healthy snapshot তার broken state সম্পর্কে খুব কমই বলে। Failure চলার সময়ই evidence ধরতে হয়েছিল।

যে iostat sample investigation বদলে দিল

r_await = 18744 ms
f_await = 53561 ms
aqu-sz  = 128.54
util    ≈ 100%
read    = 88 KB/s

Completed read প্রায় 18.7 সেকেন্ড, flush প্রায় 53.6 সেকেন্ড, average queue 128-এর বেশি, অথচ useful read throughput মাত্র 88 KB/s

এটি demanding workload efficiently serve করতে থাকা ব্যস্ত storage-এর মতো ছিল না। Virtual block path প্রায় saturated ছিল, কিন্তু খুব কম useful work করছিল। Utilization একা failure প্রমাণ করে না; huge latency, queueing, stalled task, tiny throughput এবং failed request একসঙ্গে সম্পূর্ণ আলাদা signal দেয়।

iowait-কে diagnosis হিসেবে দেখা বন্ধ করলাম

blocked processes: 4–9
CPU iowait:        97–100%
CPU idle:          0%

এটিকে CPU 100% সময় disk-এর জন্য অপেক্ষা করছে বলা সহজ। Intuition হিসেবে এটি কাজে লাগে, কিন্তু Linux accounting আরও জটিল এবং iowait disk-এর সরাসরি measurement নয়। তাই এটিকে একমাত্র প্রমাণ না ধরে একটি symptom হিসেবে দেখেছি এবং independent evidence খুঁজেছি।

PSI দেখাল I/O সত্যিই useful work থামিয়ে দিচ্ছে

cat /proc/pressure/io

একটি severe period-এ:

some avg10=99.14
full avg10=95.55

পরে full প্রায় 98% পর্যন্ত উঠেছিল। I/O pressure-এ some বোঝায় অন্তত কিছু non-idle work I/O-তে stalled, আর full বোঝায় সব non-idle task একই সময়ে stalled। 100%-এর কাছাকাছি value শুধু busy disk নয়; workload-এর progress করার সুযোগ প্রায় নেই।

D-state আমাকে একটি process-কে দোষ দেওয়া থেকে সরিয়ে দিল

ps -eo state,pid,ppid,etime,wchan:50,comm,args | awk 'NR==1 || $1 ~ /^D/'

একটি process অল্প সময় D-state-এ থাকলেই storage problem প্রমাণ হয় না। গুরুত্বপূর্ণ ছিল কোন process-গুলো একসঙ্গে আটকে আছে। আমি jbd2, systemd-journald, Nginx worker, Nginx cache process এবং অন্য filesystem activity-কে একই সময়ে blocked দেখেছি।

Backend একা আটকে থাকলে backend দেখি। Nginx একা আটকে থাকলে Nginx দেখি। কিন্তু Nginx, system journal এবং EXT4 journal thread একসঙ্গে progress করতে না পারলে তাদের shared dependency বেশি গুরুত্বপূর্ণ হয়ে ওঠে। এখানে সেটি ছিল filesystem এবং তার নিচের storage path।

Kernel stack পরবর্তী layer দেখাল

EXT4 journal thread দেখা যাচ্ছিল:

wait_on_buffer
jbd2_log_wait_commit
jbd2_journal_commit_transaction

Nginx worker ছিল normal file-read path-এ:

folio_wait_bit_common
filemap_read
generic_file_read_iter
ext4_file_read_iter
vfs_read
pread64

একসময় kernel লিখেছিল:

INFO: task nginx blocked for more than 122 seconds.

systemctl status nginx তখনও active (running) বলছিল। দুটোই সত্য: process ছিল, কিন্তু Nginx task দুই মিনিটেরও বেশি সময় useful work complete করতে পারেনি। Running process আর healthy service একই জিনিস নয়।

সবচেয়ে পরিষ্কার experiment: প্রায় তিন মিলিসেকেন্ড

Nginx দিয়ে request ব্যর্থ:

HTTP=000
SSL connection timeout

Direct local backend:

connect = 0.000423 s
TTFB    = 0.003063 s
total   = 0.003139 s

প্রায় 3 ms। Exact HTTP status গুরুত্বপূর্ণ ছিল না। Backend connection নিয়েছে, request execute করেছে এবং প্রায় সঙ্গে সঙ্গে response দিয়েছে। একই সময়ে Nginx worker EXT4 read path-এ blocked ছিল।

application execution       → progressing normally
filesystem-backed web path  → not progressing normally

যত গভীরে গেছি, application-level explanation তত কম বিশ্বাসযোগ্য হয়েছে।

একই VPS প্রায় 30 সেকেন্ডে collapse করতে পারত

একটি reproduction-এর আগে:

HTTP:          200
D-state:       0
CPU iowait:    3%
r_await:       ~1.18 ms
I/O PSI full:  ~2.95%

প্রায় 30 সেকেন্ড পরে:

D-state:       4
CPU iowait:    91%
CPU idle:      0%
I/O PSI some:  86.11%
I/O PSI full:  78.02%
r_await:       236.50 ms
HTTP:          000

পরে আরও খারাপ:

CPU iowait:    96–100%
I/O PSI full:  ~98%
HTTPS queue:   512
HTTP:          000

Load সরালে আবার দ্রুত recover করত:

D-state:      0
CPU iowait:   6%
r_await:      ~0.98 ms
queue depth:  ~0.07
HTTP:         200

এই কারণেই intermittent infrastructure failure এত কঠিন। দশ মিনিট পরে কেউ একই VM দেখে sub-millisecond latency পেতে পারে এবং তবু সত্যি কথা বলবে; সে শুধু অন্য state দেখছে।

Zero latency সবসময় ভালো খবর নয়

একবার r_await = 0 পেয়েছিলাম, যদিও system স্পষ্টতই unhealthy: high iowait, D-state, outstanding I/O, প্রায় কোনো completed read নেই এবং throughput প্রায় শূন্য।

Completed operation-এর average তখন কম informative হয়, কারণ sampling interval-এ প্রায় কিছুই complete হচ্ছে না। Zero মানেই read instant ছিল না; stalled operation বোঝানোর মতো useful completion যথেষ্ট নাও থাকতে পারে।

এরপর থেকে latency, IOPS, throughput, queue depth, in-flight I/O, D-state, PSI এবং actual request completion একসঙ্গে দেখি।

একটি incident দীর্ঘ support investigation-এ পরিণত হলো

প্রথম severe incident-এর সময় scheduled backup চলছিল, এবং FDCServers সেটি নিশ্চিত করেছিল। প্রথম ঘটনার জন্য এটি যুক্তিসঙ্গত explanation ছিল। কিন্তু backup শেষ হওয়ার পর এবং original backup window-এর বাইরে একই ধরনের storage stall আবার reproduce করেছি।

সমস্যা একাধিক দিনে ফিরেছে। এক ঘটনায় আমার service log অনুযায়ী VPS 4 ঘণ্টা 41 মিনিট 15 সেকেন্ড unavailable ছিল। Storage stall-ই VM-কে ওই state-এ পাঠিয়েছে তা আমি প্রমাণ করতে পারি না; তার জন্য host-side data দরকার ছিল।

application
    ↓
Linux VFS
    ↓
EXT4
    ↓
virtual block device
    ↓
?

প্রশ্নচিহ্নের পরে virtualization, host queue, storage network, distributed storage, physical media, scheduler এবং guest-এর অদৃশ্য আরও layer থাকতে পারে। Failure কোথায় manifest করছে তা দেখতে পেরেছি, physical root cause নয়।

FDCServers issue escalate করে VPS অন্য node-এ migrate করেছিল। Migration-এর পরও guest-এর ভেতর severe storage stall ধরেছি। এটি সব FDCServers node খারাপ প্রমাণ করে না; শুধু আমার VPS-এর problem আমার দৃষ্টিতে শেষ হয়নি।

তবু আমি এটিকে FDCServers-বিরোধী গল্প মনে করি না

একটি infrastructure incident থেকে পুরো provider সম্পর্কে verdict দেওয়া সহজ। আমি তা করতে চাই না।

একটি service-এর normal operating model যদি আমার workload-এর সঙ্গে fundamentally incompatible হয়, সেটা এক জিনিস। আর intermittent, কঠিনভাবে reproducible, দীর্ঘসময় ধরে isolate করতে হওয়া infrastructure problem অন্য জিনিস। FDCServers-এর সঙ্গে আমার অভিজ্ঞতা দ্বিতীয়টির মতো ছিল।

VPS আগে স্বাভাবিকভাবে কাজ করেছে এবং real production traffic বহন করেছে। Support investigate করেছে ও fix করার চেষ্টা করেছে। শেষে আমার operational evidence যথেষ্ট হয়ে যায় এবং আমি ওই VPS-এর ওপর production আর রাখতে চাইনি।

আমি service cancel ও refund চেয়েছিলাম। FDCServers আমাকে refund করেছে। আমার overall impression-এর জন্য এটি গুরুত্বপূর্ণ।

তাদের বর্তমান infrastructure আমি retest করিনি, তাই আজ কীভাবে কাজ করে বলতে পারি না। আমার এক VPS-এর সমস্যা পুরো fleet-এর representative ছিল—এমন evidence-ও নেই। Infrastructure সবসময় বদলায়। আমি একটি কঠিন incident-কে পুরো provider-এর স্থায়ী verdict বানাতে চাই না। এখানে FDCServers recommend-ও করছি না; শুধু নিজের experience লিখছি।

সবচেয়ে বেশি উপভোগ করেছি Linux-কে

Downtime বিরক্তিকর ছিল, কিন্তু investigation সত্যিই আনন্দের ছিল। Problem-এর boundary খুঁজে বের করতে আমার ভালো লেগেছে।

Physical root cause identify করার মতো visibility আমার ছিল না। আমি যে answer খুঁজছিলাম সেটি ছিল সহজ: কোন layer-এ useful work থামছে?

Backend প্রায় তিন মিলিসেকেন্ডে response দিয়েছে। Nginx active ছিল, কিন্তু kernel stack-এ EXT4 read-এর মধ্যে আটকে ছিল। vmstat blocked process ও extreme I/O wait দেখিয়েছে। PSI প্রায় সম্পূর্ণ I/O stall দেখিয়েছে। iostat huge latency ও queue দেখিয়েছে। D-state unrelated process-কে একই সময়ে অপেক্ষা করতে দেখিয়েছে। Kernel এমনকি Nginx task 122 সেকেন্ডেরও বেশি blocked থাকার কথাও জানিয়েছে।

একটি metric incident সমাধান করেনি; সব metric-এর agreement করেছে। Linux-এর প্রতি আমার মুগ্ধতার একটি কারণ এটাই: “website মাঝে মাঝে খুলছে না” ধরনের অস্পষ্ট সমস্যা থেকে আপনি ধীরে ধীরে এমন নির্দিষ্ট statement-এ পৌঁছাতে পারেন যে ঠিক কোন layer-এ progress থামছে।

এখন যে debugging workflow ব্যবহার করি

top
free -h
df -h

date -u
uptime
cat /proc/pressure/io
cat /proc/pressure/memory
cat /proc/pressure/cpu
vmstat 1 10
iostat -x 1 10
ps -eo state,pid,ppid,etime,wchan:50,comm,args | awk 'NR==1 || $1 ~ /^D/'
ss -lntp
journalctl -k --since "30 min ago" --no-pager

সম্ভব হলে request path-এর প্রতিটি অংশ আলাদাভাবে test করি:

public request
      ↓
reverse proxy
      ↓
direct backend
      ↓
filesystem
      ↓
block device

এখন শুধু “server slow কেন?” জিজ্ঞেস করি না। জিজ্ঞেস করি: কোন layer-এ useful work complete হওয়া বন্ধ করছে? এই প্রশ্ন অনেক ভালো experiment তৈরি করে।

শেষ নিয়ম: reboot-এর আগে evidence সংগ্রহ করুন

Production recover করতে reboot দরকার হতে পারে, কিন্তু সেটিই সবচেয়ে দরকারি diagnostic state মুছে দিতে পারে।

Before reboot:
D-state:     high
I/O PSI:     ~97%
iowait:      ~100%
queues:      large
requests:    failing

After reboot:
D-state:     0
latency:     milliseconds
requests:    healthy

সম্ভব হলে আগে UTC timestamp, PSI, vmstat, iostat, D-state, wchan, kernel message, socket queue ও request timing ধরি; তারপর machine recover করি।

Server চলছিল, workload চলছিল না

Host-side কোন component শেষ পর্যন্ত incident ঘটিয়েছে তা আমি জানি না। নির্দিষ্ট SSD, storage node বা virtual block device-এর পেছনে কী হয়েছিল—এসব প্রমাণ করার visibility আমার ছিল না।

Linux-এর ভেতর থেকে এতটাই establish করতে পেরেছিলাম:

read latency:       up to 18.7 s
flush latency:      up to 53.6 s
I/O PSI full:       almost 100%
iowait:             almost 100%
I/O queue:          128+
Nginx:              blocked in filesystem reads
EXT4/jbd2:          blocked waiting for I/O
direct backend:     ~3 ms
HTTP through Nginx: timing out

Application-কে failing layer থেকে আলাদা করতে এবং operational decision নিতে সেটাই যথেষ্ট ছিল। FDCServers refund করেছে, আমি move করেছি, এবং একটি কঠিন infrastructure incident-কে provider-এর স্থায়ী verdict বানাইনি।

যে lesson থেকে গেছে সেটি বেশি গুরুত্বপূর্ণ: process running হতে পারে, service active হতে পারে, VM online হতে পারে, ping কাজ করতে পারে—তবু machine প্রায় কোনো useful work complete না-ও করতে পারে।

Failure থাকতেই Linux-কে সঠিক প্রশ্ন করলে পার্থক্যটি দেখা যায়।