กลับไปที่บล็อก
31 สิงหาคม 2569Sergei Solod18 นาทีในการอ่าน

VPS ของผมยังออนไลน์อยู่ แต่ Linux เริ่มรอการอ่านดิสก์นานถึง 18 วินาที

กรณี debugging Linux บน production ที่ VPS ยังออนไลน์อยู่ แต่แทบไม่มีงานที่มีประโยชน์เดินหน้าต่อ: I/O pressure เข้าใกล้ 100%, read latency สูงถึง 18.7 วินาที, EXT4 และ Nginx ถูก block ขณะที่ backend ยังตอบได้ในราว 3 ms

LinuxDevOpsVPSประสิทธิภาพการดีบัก

ก่อนเข้าเรื่อง debugging ผมอยากชี้แจงอย่างหนึ่งก่อน: โดยรวมแล้วผมไม่ได้มีความรู้สึกเชิงลบต่อ FDCServers นี่ไม่ใช่รีวิวที่บอกให้คนหลีกเลี่ยงผู้ให้บริการรายนี้ และไม่ใช่การตัดสินคุณภาพของ infrastructure ทั้งหมด ผมมี VPS อยู่หนึ่งเครื่อง ในช่วงเวลาหนึ่ง และมันเจอปัญหาที่ยากและผิดปกติอย่างมาก

เป็นเวลานาน VPS เครื่องนั้นทำงานตามปกติและรองรับ production traffic จริงได้ดี จากนั้นบางอย่างก็เปลี่ยนไป Request ธรรมดาเริ่มใช้เวลานานผิดปกติ หน้าเว็บเปิดช้าลง และบางครั้งก็เปิดไม่ได้เลย ในบางช่วงเครื่องกลับมาดูปกติก่อนที่ผมจะตรวจสอบ failure ได้อย่างละเอียดเสียอีก

ในช่วงที่อาการหนักที่สุด ผมบันทึกได้ว่า:

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 นั้นน่าหงุดหงิด แต่ตัวกระบวนการ debugging กลับสนุกมาก นี่คือสิ่งหนึ่งที่ผมชอบใน Linux: เครื่องอาจดูเหมือนยังมีชีวิตจากภายนอก แต่ interface หลายตัวของ kernel ที่เป็นอิสระต่อกันสามารถบอกได้ว่าความคืบหน้าที่แท้จริงหยุดอยู่ตรงไหน บทความนี้เล่าการตามรอยสัญญาณเหล่านั้น ไม่ได้มีเป้าหมายจะตัดสินว่า FDCServers เป็น provider ที่ดีหรือแย่

active (running) แทบไม่ได้บอกอะไรเลย

ผมเริ่มจากการตรวจสอบพื้นฐาน:

top
free -h
df -h
systemctl status nginx

ในช่วงที่ระบบปกติ ค่าจะประมาณนี้:

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

ถ้าผมเข้ามาดูเฉพาะช่วงนี้ ผมคงสรุปง่าย ๆ ว่า VPS ปกติดี แต่เมื่อ normal traffic กลับมา สถานะก็สามารถเปลี่ยนได้ทั้งหมด Snapshot ที่ดู healthy ของระบบที่มีปัญหาแบบ intermittent แทบไม่ได้บอกอะไรเกี่ยวกับช่วงที่มันเสียจริง ๆ ผมต้องเก็บ evidence ขณะ failure กำลังเกิดขึ้น

ตัวอย่าง iostat ที่เปลี่ยนทิศทางการสืบสวน

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

Read ที่เสร็จใช้เวลาประมาณ 18.7 วินาที ส่วน flush ใช้ประมาณ 53.6 วินาที ค่า queue เฉลี่ยสูงกว่า 128 แต่ throughput การอ่านที่เป็นประโยชน์มีเพียง 88 KB/s

นี่ไม่เหมือน storage ที่ยุ่งเพราะกำลังประมวลผล workload หนักอย่างมีประสิทธิภาพ Virtual block path แทบอิ่มตัว แต่กลับทำงานเสร็จน้อยมาก Utilization สูงอย่างเดียวไม่ใช่ failure แต่เมื่อรวมกับ latency มหาศาล queue ยาว task ค้าง throughput ต่ำมาก และ request ล้มเหลว ภาพจะต่างไปโดยสิ้นเชิง

ผมหยุดใช้ iowait เป็น diagnosis โดยลำพัง

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

เรามักอยากสรุปว่า CPU ใช้เวลา 100% รอดิสก์ ซึ่งช่วยให้เข้าใจแบบคร่าว ๆ ได้ แต่ accounting ของ Linux ซับซ้อนกว่านั้น และ iowait ไม่ใช่การวัดตัวดิสก์โดยตรง ผมจึงมองมันเป็นเพียง symptom หนึ่งแล้วหาหลักฐานอิสระอื่น ๆ มาประกอบ

PSI แสดงว่า I/O กำลังหยุดงานที่มีประโยชน์

cat /proc/pressure/io

ในช่วงรุนแรงครั้งหนึ่ง:

some avg10=99.14
full avg10=95.55

ในการ reproduce ครั้งหลัง full เข้าใกล้ 98% สำหรับ I/O pressure ค่า some คือเวลาที่อย่างน้อยบางส่วนของ non-idle work stalled เพราะ I/O ส่วน full คือเวลาที่ non-idle task ทั้งหมด stalled บน I/O พร้อมกัน ค่าใกล้ 100% จึงมีความหมายมากกว่าแค่ “ดิสก์ยุ่ง” — workload แทบไม่มีโอกาสเดินหน้าต่อ

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 workers, Nginx cache processes และ filesystem activity อื่น ๆ ถูก block ในเวลาเดียวกัน

ถ้ามีแต่ backend ค้าง ผมจะตรวจ backend ถ้ามีแต่ Nginx ค้าง ผมจะตรวจ Nginx แต่เมื่อ Nginx, system journal และ EXT4 journal thread หยุด progress พร้อมกัน dependency ร่วมของพวกมันจะน่าสนใจกว่าตัว process ใดตัวหนึ่ง ในกรณีนี้คือ filesystem และ storage path ที่อยู่ข้างใต้

Kernel stack พาไปยัง layer ถัดไป

EXT4 journal thread ปรากฏใน path เช่น:

wait_on_buffer
jbd2_log_wait_commit
jbd2_journal_commit_transaction

Nginx workers อยู่ใน path การอ่าน filesystem ปกติ:

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 ยังอยู่ แต่ task ของ Nginx ใช้เวลามากกว่าสองนาทีโดยไม่สามารถทำงานที่มีประโยชน์ให้เสร็จได้ Process ที่ running กับ service ที่ healthy ไม่ใช่สิ่งเดียวกัน

การทดลองที่ชัดที่สุดใช้เวลาประมาณสามมิลลิวินาที

Request ผ่าน Nginx ล้มเหลว:

HTTP=000
SSL connection timeout

จากนั้นผมข้าม Nginx แล้วเรียก local backend โดยตรง:

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

ประมาณ 3 ms สถานะ HTTP ที่แน่นอนไม่สำคัญสำหรับการทดสอบนี้ Backend รับ connection, execute request และส่ง response กลับแทบจะทันที ในเวลาใกล้เคียงกัน Nginx workers ปรากฏอยู่ใน EXT4 read path

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

ยิ่งตรวจลึก คำอธิบายว่าเป็นปัญหาระดับ application ก็ยิ่งไม่น่าเชื่อ

VPS เครื่องเดิมสามารถพังได้ในประมาณ 30 วินาที

ก่อนการ reproduce ครั้งหนึ่ง:

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

ราวครึ่งนาทีต่อมา:

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

เมื่อเอา workload ออก การเปลี่ยนกลับก็เกิดเร็วได้:

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

นี่คือเหตุผลที่ intermittent infrastructure failure วินิจฉัยยากมาก สิบนาทีต่อมาใครบางคนอาจวัด latency ต่ำกว่า 1 ms บน VM เดิมและพูดถูก เขาไม่ได้ผิด เพียงกำลังดูคนละ state

Latency เท่ากับศูนย์อาจไม่มีประโยชน์อย่างที่คิด

ผมเคยเห็นช่วง iostat ที่ r_await = 0 ทั้งที่ระบบผิดปกติชัดเจน: iowait สูง, มี process ใน D-state, มี outstanding I/O, แทบไม่มี read ที่เสร็จ และ throughput แทบเป็นศูนย์

Average ที่คำนวณจาก operation ที่เสร็จจะให้ข้อมูลน้อยลง เมื่อแทบไม่มีอะไรเสร็จใน sampling interval ค่า 0 ไม่ได้พิสูจน์ว่า read จบในทันที อาจมี completion น้อยเกินกว่าจะสะท้อน operation ที่ยังติดอยู่

หลัง incident นี้ ผมดู latency, IOPS, throughput, queue depth, in-flight I/O, D-state, PSI และ request completion จริงร่วมกัน

Incident หนึ่งกลายเป็นการสืบสวนกับ support ที่ยาวกว่ามาก

เหตุการณ์รุนแรงครั้งแรกทับกับ scheduled backup บน infrastructure เดิม และ FDCServers ยืนยันว่า backup กำลังทำงาน นั่นเป็นคำอธิบายที่สมเหตุสมผลในตอนแรก แต่ภายหลังผม reproduce storage stall แบบเดียวกันได้หลัง backup จบแล้วและอยู่นอกช่วง backup เดิม

ปัญหากลับมาในหลายวัน ใน incident หนึ่ง VPS ใช้งานไม่ได้เป็นเวลา 4 ชั่วโมง 41 นาที 15 วินาที ตาม service log ของผม ผมพิสูจน์ไม่ได้ว่า storage stall เป็นสาเหตุที่ทำให้ VM เข้าสู่ state นั้น เพราะต้องใช้ข้อมูล host-side ที่ผมไม่มี

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

หลังเครื่องหมายคำถามอาจมี virtualization, host queues, storage networking, distributed storage, physical media, schedulers และระบบอื่นที่ guest มองไม่เห็น ผมมองเห็นจุดที่ failure แสดงออก แต่ไม่เห็น physical root cause

FDCServers escalate ปัญหาภายใน และสุดท้าย migrate VPS ไปยัง node อื่น หลัง migration ผมยังจับ storage stall รุนแรงจากฝั่ง guest ได้อีก นั่นไม่ได้พิสูจน์ว่า node ทุกตัวของ FDCServers มี storage problem มันพิสูจน์เพียงว่า จากมุมมองของผม ปัญหาที่กระทบ VPS ของผมยังไม่ได้ถูกกำจัด

ทำไมผมยังไม่มองว่านี่เป็นเรื่องลบของ FDCServers

Infrastructure incident เปลี่ยนเป็นคำตัดสินต่อ provider ทั้งรายได้ง่ายมาก ผมไม่ต้องการทำแบบนั้น

ผมแยก service ที่ normal operating model ไม่เข้ากับ workload ของผมตั้งแต่พื้นฐาน ออกจาก infrastructure problem แบบ intermittent ที่ reproduce ยากและใช้เวลานานในการ isolate ประสบการณ์ของผมกับ FDCServers ดูเหมือนกรณีหลังมากกว่า

ก่อน incident VPS เคยทำงานปกติและรองรับ production traffic จริง Support ตรวจสอบและพยายามแก้ปัญหา สุดท้ายผมมี evidence มากพอที่จะตัดสินใจว่าไม่ต้องการให้ production พึ่งพา VPS เครื่องนั้นอีก

ผมขอ cancel service และ refund แล้ว FDCServers คืนเงินให้ผม เรื่องนี้มีผลต่อความรู้สึกโดยรวมของผม

ผมไม่ได้ทดสอบ infrastructure ปัจจุบันของพวกเขาอีกครั้ง จึงไม่สามารถบอกได้ว่า VPS ของ FDCServers วันนี้ทำงานอย่างไร ผมก็ไม่มีหลักฐานว่าปัญหาที่เกิดกับ instance ของผมเป็นตัวแทนของ fleet ทั้งหมด Infrastructure เปลี่ยนตลอดเวลา ผมจะไม่เปลี่ยน incident ยาก ๆ บน VPS เครื่องเดียวให้เป็นคำตัดสินถาวรต่อ provider ทั้งราย และผมก็ไม่ได้กำลังแนะนำ FDCServers เช่นกัน ผมเพียงเล่าสิ่งที่เกิดกับตัวเอง

ส่วนที่ผมสนุกที่สุดคือ Linux เอง

Downtime น่าหงุดหงิด แต่ investigation สนุก ผมสนุกจริง ๆ กับการหาขอบเขตของปัญหา

ผมไม่มี visibility มากพอจะระบุ physical root cause คำตอบที่ผมต้องการง่ายกว่านั้น: งานที่มีประโยชน์หยุดเสร็จที่ layer ไหน?

Backend ตอบในราวสามมิลลิวินาที Nginx บอกว่า active แต่ kernel stack แสดงว่ามันกำลังรออยู่ใน EXT4 read vmstat แสดง blocked process และ I/O wait รุนแรง PSI แสดงว่า I/O stall กินเกือบทั้ง workload iostat แสดง latency และ queueing มหาศาล D-state แสดง process ที่ไม่เกี่ยวข้องกันรอพร้อมกัน และ kernel ยังรายงาน task ของ Nginx ที่ถูก block นานเกิน 122 วินาที

ไม่มี metric ตัวเดียวที่แก้ incident นี้ได้ สิ่งที่ช่วยคือหลาย signal สอดคล้องกัน นี่เป็นหนึ่งในเหตุผลที่ผมชอบ Linux: เริ่มจากอาการกว้าง ๆ อย่าง “เว็บไซต์บางครั้งเปิดไม่ได้” แล้วค่อย ๆ ลดขอบเขตจนบอกได้อย่างแม่นยำว่า useful work หยุดที่ layer ไหน

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 แยกกัน:

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

ตอนนี้ผมไม่ถามแค่ว่า “ทำไม server ช้า?” ผมถามว่า: งานที่มีประโยชน์หยุดเสร็จที่ layer ไหน? คำถามนี้นำไปสู่ experiment ที่ดีกว่ามาก

กฎสุดท้าย: เก็บ evidence ก่อน reboot

Reboot อาจเป็นสิ่งที่ production ต้องการพอดี แต่ก็อาจลบ 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

เมื่อ availability และ business impact อนุญาต ผมจะเก็บ UTC timestamp, PSI, vmstat, iostat, D-state, wchan, kernel messages, socket queues และ request timings ก่อน แล้วค่อยกู้เครื่อง

Server ยังทำงาน แต่ workload ไม่ได้ทำงาน

ผมไม่เคยรู้ว่า host-side component ตัวใดเป็นสาเหตุสุดท้ายของ incident ผมบอกไม่ได้ว่า SSD ตัวหนึ่งเสีย ระบุ storage node ใดเป็นพิเศษไม่ได้ และพิสูจน์ไม่ได้ว่าเกิดอะไรขึ้นหลัง virtual block device

แต่สิ่งที่ยืนยันได้จากภายใน Linux ก็เพียงพอแล้ว:

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 ออกจาก layer ที่มีปัญหาและใช้ตัดสินใจเชิงปฏิบัติการ FDCServers คืนเงิน VPS ให้ผม ผมย้ายต่อ และผมไม่ได้ใช้ infrastructure incident ยาก ๆ ครั้งเดียวมาตัดสิน provider ทั้งราย

สิ่งที่ติดตัวผมมามีประโยชน์กว่า: process อาจ running, service อาจ active, VM อาจ online, ping อาจใช้ได้ แต่เครื่องก็ยังแทบไม่ได้ทำ useful work เลย

Linux มี evidence มากพอให้เห็นความแตกต่าง เพียงต้องถามคำถามที่ถูกต้องในขณะที่ failure ยังอยู่