Generated by Answer me with HTML 0.5.2 · 2026-10-19 18:41 · ★ Star on GitHub

ผลวัด load ฐานข้อมูล PROD — ลด M60 → M50 ได้ไหม

v3 · ปริมาณงาน 6–19 ต.ค. 2026 + วัด load สด 2 ช่วง (ช่วงปกติ และช่วง report รัน)

ลง M50 ได้ แต่ต้องแก้ช่วง report ก่อน. ตอน report รัน แม้บน M60 ฐานข้อมูลก็ต้องอ่านจาก disk ราว 70 GB ใน 26 นาที. M40 และ M30 ยังไม่พอ.

A

ข้อสรุป

M50 = ได้แบบมีเงื่อนไข · M40 / M30 = ยังไม่ได้
  • ช่วงปกติ M60 สบาย: อ่านจาก disk แค่ 0.47 MB/s และข้อมูลที่ใช้บ่อยอยู่ใน memory หมด.
  • ช่วง report รัน (ทุก 3 ชั่วโมง) คือคอขวดจริง: อ่านจาก disk เพิ่มเป็น 46.8 MB/s (~100 เท่า). Memory cache ทั้งก้อนถูกแทนที่ ~2.2 รอบใน 26 นาที.
  • Query ที่ report ใช้ช้าลงมาก: การอ่านข้อมูลคนขับเพิ่มจาก 18 ms เป็น 9–11 วินาทีต่อครั้ง.
  • ปริมาณงานเดือนนี้ลดลง 10–15% จากสัปดาห์แรกไปสัปดาห์ที่สอง. load ไม่ได้โต.
  • M50 มี memory ครึ่งเดียว ช่วง report จะหนักกว่านี้. ให้แก้ report และเพิ่ม index ก่อนลด tier.
B

ปริมาณงานต่อวัน (6–19 ต.ค.)

รายการ เฉลี่ย 6–12 ต.ค. เฉลี่ย 13–18 ต.ค. เปลี่ยน วันสูงสุด
Order ใหม่ 5,233 4,538 −13% 5,752 (11 ต.ค.)
รายการสินค้าใน order 22,789 19,253 −16% 24,059 (11 ต.ค.)
งานส่ง (task) 312 299 −4% 318
Log กิจกรรม (ตัวแทนจำนวนการสร้าง/แก้ข้อมูล) 661,000 591,000 −11% 687,000 (12 ต.ค.)
จุด GPS ของคนขับ 73,200 66,100 −10% 77,600
ข้อความ Kafka 40,900 36,300 −11% 42,700
รูป/ไฟล์แนบ 9,960 9,320 −6% 10,500

นับจากเวลาที่สร้างข้อมูล (ไม่นับการแก้ไข). 19 ต.ค. ยังไม่จบวัน จึงไม่รวมในค่าเฉลี่ย.

C

ช่วงเวลาที่หนักที่สุดของวัน

Log กิจกรรม 17:00–18:00 (เฉลี่ย เทียบสูงสุด)70800 / max 86400 ต่อชั่วโมง
Order ใหม่ 17:00–18:00 (เฉลี่ย เทียบสูงสุด)869 / max 1118 ต่อชั่วโมง
GPS คนขับ 11:00–13:00 (เฉลี่ย เทียบสูงสุด)8870 / max 15500 ต่อชั่วโมง
  • งานหนักช่วง 16:00–19:00. ค่าสูงสุดทั้งเดือนคือ 12 ต.ค. 17:00.
  • 01:00–05:00 แทบไม่มีงาน. เหมาะกับการเปลี่ยน tier.
D

Load สด: ช่วงปกติ เทียบช่วง report

ค่า 17:49–17:52 (ช่วงพีค ไม่มี report) 17:52–18:19 (report รอบ 18:00)
Reads 1,342 ops/s 2,446–3,522 ops/s
Writes 217 ops/s 300–480 ops/s
อ่านจาก disk เข้า memory 0.47 MB/s 46.8 MB/s (รวม 70.5 GB ใน 26 นาที)
เวลาอ่านข้อมูลคนขับต่อครั้ง 18 ms 9–11 วินาที
เวลาอ่านข้อมูลงาน/การชำระเงินต่อครั้ง 17–33 ms 17–41 วินาที
Query เล็กอื่นๆ ที่ report ไม่ใช้ ~17 ms ~17 ms (ไม่เปลี่ยน)

Report รันทุก 3 ชั่วโมง (09, 12, 15, 18, 21, 00, 03, 06 น.). Report ดึงข้อมูลงาน การชำระเงิน คนขับ และผู้ใช้. ส่วนนี้ช้าลงเป็นวินาที. ส่วนอื่นของระบบยังปกติ.

E

Spec เทียบ load

M60 (ปัจจุบัน) M50 M40 M30
vCPU 16 8 4 2
RAM 64 GB 32 GB 16 GB 8 GB
Memory cache ของ DB ~31.5 GB ~15.5 GB ~7.5 GB ~3.5 GB
ช่วงปกติ
ช่วง report (ตอนนี้) cache ถูกแทนที่ 2.2 รอบ ~4.5 รอบ
ช่วง report (หลังแก้) ต้องวัดใหม่
Disk 39 GB ต้องขยาย
F

สิ่งที่ยังไม่รู้

  • ใครอ่าน log กิจกรรมทั้งก้อน: log กิจกรรมมี index แค่ _id. ช่วง 17:52–18:17 มีการอ่าน log กิจกรรมจาก disk 32.8 GB. ขนาดนี้เท่ากับอ่านทั้ง collection. Report ไม่ได้ใช้ข้อมูลชุดนี้ ต้องหาต้นทาง.
  • ไม่มีค่า CPU % และ IOPS จากการวัดนี้. ต้องดูกราฟ Atlas ช่วง report.
  • ค่าช่วง report มาจาก 1 รอบ (18:00).
G

Quick wins: แก้ที่ DB / config ไม่ต้องแก้โค้ด

ลำดับ สิ่งที่ทำ ผลที่คาด ความเสี่ยง
1 เพิ่ม index ที่ payments → order report เร็วขึ้น ~58 ms ต่อ order (~70% ของเวลา report) ต่ำ
2 เอา join ข้อมูล COD ออกจาก report (ฟิลด์ที่ join ไม่มีอยู่จริง ผลว่างทุกแถว) เร็วขึ้น ~15 ms ต่อ order ต่ำ ค่าที่ได้ว่างอยู่แล้ว
3 เพิ่ม index ที่ exceptions → order เร็วขึ้น ~8 ms ต่อ order ต่ำ
4 เพิ่ม index ที่ orders.updatedAt report เลิกอ่าน orders ทั้งก้อน (6 GB) ทุกรอบ ต่ำ
5 ลดช่วง report จาก 3 วัน เป็น 12 ชม. แล้วรันทุกชั่วโมง แถวที่ประมวลผลต่อวันลด 56% ข้อมูลสดขึ้น (~1 ชม.) ข้อมูลที่ไม่ bump updatedAt อาจค้าง ต้องมีรอบเต็มวันละครั้ง
6 เพิ่ม index ที่ key ของตาราง report และ purge orphan วันละครั้งแทนทุกรอบ ลด ~30 วินาทีต่อรอบ ต่ำ
7 เพิ่ม index ที่ tasks → loads / orders, loads → orders และ order logs → order งานสร้าง task และ unhold เร็วขึ้น 200–900 ms ต่อครั้ง ต่ำ
8 ตั้ง TTL หรือ archive log กิจกรรม 30 วัน (ตอนนี้ 32.6 GB เพิ่มวันละ ~580k แถว) ลดข้อมูล ~17 GB และลดการอ่าน disk ต้องตกลงระยะเก็บกับทีม audit
9 ตั้ง TTL ให้ log Kafka (8.1 GB), log pipeline (7.4 GB), log Google API (4.2 GB อยู่ใน memory 4.6 GB) คืน memory และ disk ~15–20 GB ต้องตกลงระยะเก็บ
10 ลบ index ที่ซ้ำ (task_id เดี่ยว ซึ่งเป็น prefix ของ index อื่น) write เร็วขึ้นเล็กน้อย ต่ำ

ข้อ 1–4 รวมกันอธิบายได้ ~81 จาก 82 ms ต่อ order ที่ report ใช้. คาดว่ารอบ report จะสั้นลงจาก ~33 นาที เหลือไม่กี่นาที (ค่าประมาณ ต้องวัดซ้ำ). สร้าง index ช่วง 01:00–05:00 แบบ rolling ใน Atlas.

H

แก้ที่โค้ด

ลำดับ สิ่งที่ทำ ผลที่คาด ขนาดงาน
1 Cache ข้อมูล master ในแอป (คนขับ ผู้ใช้ สาขา รถ channel partner สกุลเงิน zone strategy) TTL 30–60 วินาที reads ลด ~650 ops/s (49%) และเวลา DB ช่วงปกติลด ~63% กลาง ต้อง invalidate ตอนแก้ข้อมูล
2 จำกัด populate เฉพาะฟิลด์ที่ใช้ (ตอนนี้ order 1 ใบ populate 94 path) query ต่อ request ลดลงมาก CPU ฝั่ง Node ลดด้วย กลาง
3 แยก route polyline และผล Google ออกจากเอกสาร task (เฉลี่ย 103 KB ต่อใบ) task เล็กลง อ่าน list เร็วขึ้น memory ใช้น้อยลง กลาง
4 เปลี่ยน order ที่ copy ไว้ใน stop point เป็น reference (แผน DO-ref Phase 2) ข้อมูล stop point 13 GB เล็กลง write เบาลง ใหญ่
5 Report เขียนเฉพาะแถวที่เปลี่ยน แทนเขียนทุกแถวทุกรอบ write ช่วง report ลดลงมาก เล็ก
6 เลิกเขียน log กิจกรรมของ pipeline job/log (วัดบน bench = 54% ของ log กิจกรรม) log กิจกรรมเพิ่มช้าลงราวครึ่งหนึ่ง เล็ก
7 ตัด deep clone ทั้ง response และการเรียก refresh search text ทุกครั้งที่เขียน CPU ฝั่งแอปลด จำนวน request ภายในลด กลาง (อยู่ใน lib)
I

ลำดับที่แนะนำ

อ่าน disk ไม่เกิน 5 MB/s และ CPU p95 ไม่เกิน 35%?}00–05:00]: ใช่ไม่ใช่q[ทำ quick wins ข้อ1–7]m[วัด report รอบถัดไป]mc[cache master data ในแอป]ccheck{ช่วง reportcheckm50[ลด M60 → M50 ช่วง01hold[คง M60 แล้วทำข้อH2–H4]m50ttl[ตั้ง TTL log ข้อ8–9]ttlm40{วัดใหม่ load พอสำหรับ M40?}m40down40[พิจารณา M40]
  • ถ้ามีปัญหา scale กลับ M60 ได้ทันที แบบไม่มี downtime.
  • หาต้นทางที่อ่าน log กิจกรรมทั้งก้อนคู่กันไปด้วย.