Step 12 of 18
High-Level System Design textหลักการออกแบบระบบระดับสูง ครอบคลุม Design for Failure, KISS, Redundancy, Multi-tenancy และ Service Health Check
Study the principles that interviewers look for in system design rounds.
High-Level System Design
Core Principles and Strategies
1. Design For Failure
ระบบย่อมมีความล้มเหลวเกิดขึ้น ไม่ใช่เรื่องของ if แต่เป็นเรื่องของ when ระบบที่ทนทานจะคาดการณ์ความล้มเหลวและได้รับการออกแบบมาให้จัดการกับมันได้อย่างราบรื่น
Embrace Redundancy : มีส่วนประกอบหลายชุด (เซิร์ฟเวอร์, ฐานข้อมูล ฯลฯ) เพื่อให้หากตัวหนึ่งล้มเหลว อีกตัวสามารถทำงานแทนได้
Fault Isolation : แยกส่วนประกอบออกจากกัน เพื่อให้ความล้มเหลวในจุดหนึ่งไม่ลามไปยังจุดอื่น ๆ สามารถทำได้โดยใช้เทคนิคเช่น bulkheads และ circuit breakers
Automated Recovery : ใช้กลไกสำหรับการกู้คืนอัตโนมัติจากความล้มเหลว เช่น auto-scaling และ self-healing
2. Keep Things Simple and Robust (KISS)
ระบบที่ซับซ้อนยากต่อการสร้าง บำรุงรักษา และแก้ไขจุดบกพร่อง พยายามออกแบบให้เรียบง่ายที่สุด
Avoid Over-engineering : อย่าเพิ่มความซับซ้อนสำหรับฟีเจอร์ที่ยังไม่จำเป็นในตอนนี้
Use Proven Technologies : เลือกใช้เทคโนโลยีที่เป็นที่เข้าใจดีและมีประวัติการใช้งานที่พิสูจน์แล้ว
Modularity : แบ่งระบบออกเป็นโมดูลเล็ก ๆ ที่เป็นอิสระต่อกัน ซึ่งเข้าใจและจัดการได้ง่ายกว่า
3. Redundancy and Fault Recovery
ความซ้ำซ้อนคือการมีส่วนประกอบที่ซ้ำกัน ในขณะที่การกู้คืนความเสียหายคือวิธีที่ระบบฟื้นตัวจากความล้มเหลว
Active-Passive vs. Active-Active : ในการตั้งค่าแบบ active-passive ส่วนประกอบหนึ่งจะสแตนด์บายรอ ในขณะที่ active-active ส่วนประกอบทั้งสองจะทำงานและแชร์โหลดกัน
Backup and Restore : สำรองข้อมูลอย่างสม่ำเสมอและมีกระบวนการกู้คืนที่ผ่านการทดสอบแล้ว
Graceful Degradation : หากส่วนประกอบที่ไม่สำคัญล้มเหลว ระบบควรยังคงทำงานต่อไปได้ แต่อาจมีฟังก์ชันการทำงานที่ลดลง
4. Multi-tenancy
Multi-tenancy คือสถาปัตยกรรมที่แอปพลิเคชันซอฟต์แวร์อินสแตนซ์เดียวให้บริการลูกค้าหลายราย ซึ่งเรียกว่าผู้เช่า (tenants)
Data Isolation : ตรวจสอบให้แน่ใจว่าข้อมูลของผู้เช่าแต่ละรายถูกแยกออกจากกันและผู้เช่ารายอื่นไม่สามารถเข้าถึงได้
Resource Pooling : แชร์ทรัพยากรระหว่างผู้เช่าเพื่อลดต้นทุน
Scalability : สถาปัตยกรรมควรสามารถขยายเพื่อรองรับผู้เช่าจำนวนมากได้
5. Service Health Check
การตรวจสอบสุขภาพใช้เพื่อตรวจสอบว่าบริการกำลังทำงานและปกติดีหรือไม่
Liveness Probe : ตรวจสอบว่าแอปพลิเคชันกำลังทำงานอยู่หรือไม่ หาก liveness probe ล้มเหลว แอปพลิเคชันจะถูกรีสตาร์ท
Readiness Probe : ตรวจสอบว่าแอปพลิเคชันพร้อมที่จะรับทราฟฟิกหรือไม่ หาก readiness probe ล้มเหลว แอปพลิเคชันจะไม่ได้รับทราฟฟิกใด ๆ
Deep Health Checks : ตรวจสอบลึกกว่าแค่การ ping ธรรมดา โดยตรวจสอบสุขภาพของบริการปลายทางและสิ่งที่ต้องพึ่งพาด้วย
6. Development Parity with Production
สภาพแวดล้อมการพัฒนาควรเหมือนกับสภาพแวดล้อมการใช้งานจริงมากที่สุดเท่าที่จะเป็นไปได้ เพื่อช่วยจับประเด็นปัญหาได้ตั้งแต่เนิ่น ๆ และลดความเสี่ยงที่จะเกิดเรื่องเซอร์ไพรส์เมื่อ deploy ขึ้น production
Infrastructure as Code : ใช้เครื่องมือเช่น Terraform หรือ CloudFormation เพื่อจัดเตรียมและจัดการโครงสร้างพื้นฐานในรูปแบบที่ทำซ้ำได้
Containerization : ใช้คอนเทนเนอร์ (เช่น Docker) เพื่อแพ็คเกจแอปพลิเคชันและสิ่งที่ต้องใช้รวมกัน เพื่อให้แน่ใจว่ามีความสอดคล้องกันในทุกสภาพแวดล้อม
Continuous Integration/Continuous Deployment (CI/CD) : ทำกระบวนการ build, test และ deploy ให้เป็นอัตโนมัติ
7. Zero Trust Architecture
ในสถาปัตยกรรมแบบ zero-trust จะไม่มีผู้ใช้หรืออุปกรณ์ใดได้รับความไว้วางใจโดยค่าเริ่มต้น ไม่ว่าจะอยู่ภายในหรือภายนอกเครือข่าย
Authenticate and Authorize Everything : ทุกคำขอต้องได้รับการตรวจสอบตัวตนและได้รับอนุญาต
Least Privilege : ให้สิทธิ์ผู้ใช้และบริการเฉพาะเท่าที่จำเป็นสำหรับการทำงานเท่านั้น
Micro-segmentation : แบ่งเครือข่ายออกเป็นส่วนเล็ก ๆ ที่แยกจากกันเพื่อจำกัดวงความเสียหายของการโจมตี
8. Don't Repeat Yourself (DRY)
หลักการ DRY มีเป้าหมายเพื่อลดการทำซ้ำของรูปแบบซอฟต์แวร์ โดยการใช้ abstraction หรือการทำ data normalization แทน
Code Reusability : สร้างไลบรารีและบริการที่สามารถนำกลับมาใช้ใหม่ได้
Single Source of Truth : มีแหล่งข้อมูลความจริงเพียงแหล่งเดียวสำหรับข้อมูลของคุณ
Avoid Copy-Paste : อย่าคัดลอกและวางโค้ด ให้สร้างฟังก์ชันหรือคลาสแทน
9. Independent Workloads/Clusters
แยกเวิร์กโหลดและคลัสเตอร์ออกจากกันเพื่อป้องกันไม่ให้รบกวนซึ่งกันและกัน
Resource Quotas : กำหนดโควตาทรัพยากรเพื่อป้องกันไม่ให้เวิร์กโหลดหนึ่งใช้ทรัพยากรทั้งหมด
Separate Environments : ใช้สภาพแวดล้อมแยกต่างหากสำหรับการพัฒนา การทดสอบ และการใช้งานจริง
Cell-based Architecture : ระบบถูกแบ่งออกเป็นกลุ่มของเซลล์ที่มีทุกอย่างในตัว (self-contained) โดยแต่ละเซลล์มีข้อมูลและบริการของตัวเอง
10. Autonomous with Emergency Human Intervention
ระบบควรสามารถทำงานได้โดยอัตโนมัติ แต่ควรมีวิธีให้มนุษย์เข้ามาจัดการในกรณีฉุกเฉิน
Automated Alerts : ตั้งค่าการแจ้งเตือนเพื่อแจ้งทีมเมื่อมีสิ่งผิดปกติ
Runbooks : มีขั้นตอนการปฏิบัติงานที่กำหนดไว้ชัดเจนสำหรับการจัดการปัญหาที่พบบ่อย
Feature Flags : ใช้ feature flags เพื่อเปิดหรือปิดฟีเจอร์โดยไม่ต้อง deploy โค้ดใหม่
How to Approach a HLD Interview Question
ใช้ Framework นี้เป็นแนวทางในการตอบคำถาม System Design ทุกข้อ:
Step 1 — Clarify Requirements (5 min)
Functional : ระบบต้องทำอะไรได้บ้าง? (features)
Non-functional : Scale เท่าไหร่? Latency? Availability? Consistency?
Out of scope : ระบุสิ่งที่ไม่ต้องออกแบบในครั้งนี้
Step 2 — Estimate Scale (3 min)
DAU / QPS (Queries per second)
Storage ที่ต้องการ
Read vs Write ratio
Step 3 — High-Level Architecture (10 min)
วาด Components หลัก: Client → API → Service → DB
ระบุ Data flow คร่าว ๆ
เลือก SQL vs NoSQL พร้อมเหตุผล
Step 4 — API Design (5 min)
ระบุ Endpoints หลักที่จำเป็น
Request / Response format
Step 5 — Data Model (5 min)
ออกแบบ Schema หรือ Data structure หลัก
ระบุ Indexes ที่จำเป็น
Step 6 — Deep Dive (15 min)
เลือก 1–2 ส่วนที่ท้าทาย แล้วขุดลึก เช่น:
How to handle high read traffic? → Cache strategy
How to scale writes? → Sharding
How to ensure reliability? → Replication, failover
Step 7 — Identify Bottlenecks & Trade-offs
ระบุ Single points of failure
พูดถึง Trade-offs ของการออกแบบที่เลือก
Common High-Level Design Interview Questions
Design a URL shortener (like TinyURL)
Design a social media feed (like Twitter or Facebook)
Design a ride-sharing service (like Uber or Lyft)
Design a video streaming service (like YouTube or Netflix)
Design a distributed key-value store (like Redis or Cassandra)
Design a search engine (like Google)
Design a notification service
Design a distributed message queue (like Kafka or RabbitMQ)