Infrastructure Proposal · สำหรับทีม ICT Team พิจารณา

gnss.rid.go.th
ข้อเสนอปรับปรุง Infrastructure

ย้ายจาก single-VM ไปเป็นสถาปัตยกรรมแบบหลาย instance ด้านล่างเปรียบเทียบ 3 scenarios ทุก scenario ใช้ขนาดไม่เกิน 2 vCPU ต่อ instance ตามข้อจำกัดที่กำหนด และมีข้อเสนอแนะชัดเจนอยู่ท้ายเอกสาร

Service
gnss.rid.go.th
Stack
Rails · PostgreSQL · Redis · Sidekiq
Expected load
น้อยกว่า 50 concurrent users
Per-instance cap
2 vCPU / 4 GB

สถานะปัจจุบันของ server

เพื่อให้เข้าใจตรงกันก่อนพิจารณาแนวทาง นี่คือ snapshot ของ server ที่ gnss.rid.go.th รันอยู่ ณ ตอนนี้

Hardware / OS
  • CentOS 6.10EOL
  • Kernel 2.6.32
  • Xeon E5-4620 v2 @ 2.60 GHz · 2 cores
  • RAM 4 GB · swap 4 GB
  • Disk 291 GB (ใช้ไป 7%)
  • Uptime ~1,388 วัน (ตั้งแต่ 2022-06-06)
Application stack
  • Nginx → Puma (unix socket) → Rails 5.1
  • Ruby 2.3.1 (ผ่าน RVM)
  • PostgreSQL 11.2 — rid_prod · 26 MB · 11 tables
  • Redis 5.0.3 + Sidekiq (concurrency 10)
  • Monit (process management)
  • Last deploy 2019-04-296+ ปี
Uploads / data
  • ไฟล์อัปโหลดรวม 14 GB
  • ทั้งหมดเป็น attachments ของ control points
  • เก็บใน shared/public/system/control_points/
  • ขนาดเพิ่มขึ้นต่อเนื่องตามการใช้งาน
ประเด็นที่น่ากังวลหลัก: CentOS 6 หมด support ตั้งแต่ปี 2020 — ไม่มี security patch อีกแล้ว · ทุกบริการ (Rails, PostgreSQL, Redis, Sidekiq) แย่ง resource กันบน VM เดียวที่มี RAM 4 GB และ 2 cores · code ไม่ได้ deploy มาเกือบ 7 ปี ความรู้เรื่อง deployment มีความเสี่ยงที่จะสูญหายไปแล้ว · uptime 1,388 วันหมายความว่าไม่เคย reboot เพื่อ patch เลย

ทำไมต้อง upgrade

ปัจจุบันระบบรันอยู่บน VM เดียว ซึ่งทำให้ Rails, PostgreSQL และ background jobs ต้องแย่ง CPU และ RAM กันเอง ไม่สามารถ deploy โดยไม่มี downtime ได้ หาก disk เต็มจากไฟล์ที่อัปโหลดจะทำให้ระบบล่มทั้งหมด และเมื่อเกิดปัญหาก็ไม่มีทางตรวจสอบว่าเกิดอะไรขึ้น การแยกหน้าที่ออกเป็นหลาย VM จึงเป็นแนวทางมาตรฐานที่ควรทำ

3 scenarios ที่เสนอ

แต่ละ scenario เพิ่มจำนวน VM ขึ้นทีละหนึ่ง คำถามคือเราจะตัดสินใจจุดไหนระหว่างต้นทุนและความเสถียรของระบบ

Scenario A

ขั้นต่ำ — 2 VMs

แยก database ออกจากส่วนอื่น ไม่มี monitoring ไม่มีการแยก file storage

VM 1 · App
Rails + Sidekiq + Redis
2 vCPU / 4 GB
Disk 100 GB
Web, jobs, cache, files
VM 2 · Data
PostgreSQL
2 vCPU / 4 GB
Disk 50 GB
Database อย่างเดียว
ข้อเสียที่ต้องรับ: ไม่มี monitoring — เวลามีปัญหาเราจะไม่รู้เลยว่าเกิดอะไรขึ้น และไม่มีข้อมูลไว้วิเคราะห์ย้อนหลัง deploy ทุกครั้งต้องมี downtime ไฟล์ที่ user อัปโหลดจะสะสมอยู่บน disk ของ Rails VM สุดท้ายเต็มและทำให้ระบบล่ม
Scenario B

สมดุล — 3 VMs

เพิ่ม monitoring VM แยกต่างหาก แต่ไฟล์อัปโหลดยังคงอยู่บน Rails VM

VM 1 · App
Rails + Sidekiq
2 vCPU / 4 GB
Disk 100 GB
Web + jobs + files
VM 2 · Data
PostgreSQL + Redis
2 vCPU / 4 GB
Disk 50 GB
DB + cache + queue
VM 3 · Ops
Monitoring
2 vCPU / 4 GB
Disk 50 GB
Prometheus + Grafana
ข้อเสียที่ต้องรับ: มี observability แล้ว — เรามองเห็นปัญหาก่อนที่ user จะแจ้งเข้ามา แต่ไฟล์อัปโหลดยังแชร์ disk กับ Rails VM ซึ่งยังเป็นปัญหาหลักเมื่อไฟล์ GNSS data สะสมมากขึ้นเรื่อยๆ

เปรียบเทียบทั้ง 3 scenarios

สรุปทรัพยากรทั้งหมด ความสามารถ และลักษณะของความเสี่ยงในมุมมองเดียว

เกณฑ์ A · 2 VMs B · 3 VMs C · 4 VMs
Total vCPU 4 6 8
Total RAM 8 GB 12 GB 16 GB
Total disk 150 GB 200 GB 330 GB
แยก database ใช่ ใช่ ใช่
Monitoring & alerting ไม่มี มี มี
แยก file storage ไม่ ไม่ แยก
ผลกระทบเมื่อ disk เต็ม ทั้งระบบ Web tier เฉพาะ files
ข้อเสนอแนะ ขั้นต่ำที่รับได้ ทางเลือกสำรอง แนะนำ
หมายเหตุเรื่องขนาดที่ขอ: ตัวเลขที่เสนอเป็นเพียงจุดเริ่มต้นสำหรับการพูดคุย ทีม ICT คือผู้ที่เข้าใจข้อจำกัดของ infrastructure ได้ดีที่สุด หากพิจารณาแล้วเห็นว่าควรปรับลดตรงไหน เรายินดีปรับตามครับ สำหรับข้อมูลอ้างอิง: v1 ที่ใช้อยู่ตอนนี้มี 2 cores / 4 GB RAM / 291 GB disk (ใช้จริง ~20 GB) ส่วน Scenario C รวมประมาณ 8 vCPU / 16 GB RAM / 330 GB disk กระจายใน 4 VM ซึ่งแต่ละตัวยังอยู่ภายใต้ cap 2 vCPU / 4 GB ที่ทีม ICT ได้กำหนดไว้ จุดประสงค์หลักคือการแยกหน้าที่ของแต่ละ service ออกจากกัน ไม่ได้ต้องการเพิ่ม capacity ของระบบแต่อย่างใด workload จริงยังเบาเท่าเดิม

FAQ

ประเด็นที่เราคาดว่าจะถูกถาม และคำตอบที่เตรียมไว้

ทำไมต้องใช้ VM เยอะขนาดนี้ VM ใหญ่ตัวเดียวไม่ง่ายกว่าเหรอ?

VM เดียวหมายความว่าถ้ามีปัญหาครั้งเดียวระบบล่มทั้งหมด การแยก VM ช่วยจำกัด blast radius ของปัญหาที่อาจเกิดขึ้น แต่ละ VM ขนาดเล็กแค่ 2 vCPU ซึ่ง hypervisor จัดการ scheduling ได้ง่ายกว่า VM ใหญ่ที่ต้องแย่งทรัพยากรแบบต่อเนื่อง

Monitoring ไม่อยู่ใน scope ปกติของเรา

ถ้าไม่มี monitoring เราไม่สามารถการันตี availability หรือทำ root-cause analysis หลังเกิดปัญหาได้ ต้นทุนคือ VM เล็กๆ 1 ตัวขนาด 2 vCPU และเป็นสิ่งที่สำคัญที่สุดรองจากการแยก database ออกมา

ทำไมไม่เก็บไฟล์บน Rails VM เหมือนเดิม?

ระบบนี้มีฟีเจอร์อัปโหลดไฟล์ในหลายจุด (cover photo, document, damage report) จะเพิ่มขึ้นต่อเนื่อง (15GB in v1) เมื่อ disk ของ Rails เต็มระบบจะล่มทั้งหมด การแยก storage VM ทำให้ประเด็นนี้หมดไป และเปิด path ให้ขยายพื้นที่เก็บข้อมูลได้อย่างอิสระในอนาคต

จุดที่อยากขอเพิ่ม

ถ้า vCPU จำกัด แต่ RAM และ disk ยืดหยุ่นได้

Performance ของ PostgreSQL ส่วนใหญ่มาจากการ cache ข้อมูลที่เข้าถึงบ่อยไว้ใน RAM — database VM ที่มี RAM 6–8 GB กับ 2 vCPU จะทำงานได้ดีกว่า VM ที่มี RAM 4 GB กับ 4 vCPU สำหรับงานประเภทนี้

ถ้า IT ยืดหยุ่นด้าน memory ได้ เราอยากขอเพิ่ม RAM ให้ data VM มากกว่าเพิ่ม cores ที่อื่น