บทที่ 3 · Part 1 — Foundation
The 7-Step Frame
CADENCE — ลำดับที่ทำซ้ำได้จาก requirement คลุมเครือไปถึง design, พร้อม clarification script และการประเมิน scale
Engineer ส่วนใหญ่ออกแบบด้วยการเชื่อมโยง: ได้ยินคำว่า "แอปแชท" ก็ตอบ "WebSocket กับ Kafka" ผลลัพธ์คือ design ที่ defend ไม่ได้ เพราะมันไม่ได้ถูก derive มาจากอะไรเลย การมีลำดับขั้นที่ตายตัวแก้ปัญหานี้ — ไม่ใช่ระบบราชการ แต่คือความต่างระหว่าง design ที่อธิบายได้ กับ design ที่คุณแค่ชอบ
จบบทนี้คุณจะ
- ใช้ลำดับ 7 ขั้น (CADENCE) ได้ทั้งในห้องสัมภาษณ์ 45 นาทีและโปรเจกต์จริง 3 สัปดาห์
- มี clarification script ที่ถามได้ครบทุกหมวดโดยไม่ต้องนึกสด
- แปลงคำว่า "เร็ว" "ห้ามล่ม" "real-time" ให้เป็นตัวเลขที่ทดสอบได้
- เชื่อมตัวเลข scale เข้ากับ ขีดจำกัดของ component ได้ ไม่ใช่แค่พูดว่า "300 tps"
ลำดับ 7 ขั้น
ใช้ลำดับเดิมทุกครั้ง ลำดับสำคัญเพราะผลลัพธ์ของขั้นหนึ่งคือ input ของขั้นถัดไป
| # | ขั้น | Artefact ที่ได้ | สัมภาษณ์ 45 นาที | โปรเจกต์จริง |
|---|---|---|---|---|
| 1 | Clarify requirements & scope | functional list + quality attribute + non-goal ที่เขียนชัด | 5–7 นาที | 1–5 วันคุยกับ stakeholder |
| 2 | Assess the scale | QPS, storage, bandwidth, growth, peak factor | 3–5 นาที | ครึ่งวัน + telemetry จริง |
| 3 | Define the contracts | API surface, event, error semantics, idempotency | 3–5 นาที | 2–4 วัน review กับ consumer |
| 4 | Entities & data model | entity, key, access pattern, การเลือก store | 5 นาที | 3–5 วัน — ขั้นที่ให้ leverage สูงสุด |
| 5 | Nail the architecture | diagram 1 ใบ + trace เส้นทาง request | 8–10 นาที | 2–3 วันรวม review |
| 6 | Critical deep dives | 2–3 sub-problem ที่ยากจริง แก้ให้ละเอียด | 10 นาที | 1–2 สัปดาห์ อาจมี spike |
| 7 | Examine failures & evolution | failure table, SLO, rollout plan, ADR | 5 นาที | ต่อเนื่อง และเป็น gate ของ go-live |
ทำไมต้องลำดับนี้ ไม่ใช่ลำดับอื่น
ขั้น 3 กับ 4 มาก่อน diagram โดยเจตนา ถ้าวาดกล่องก่อน คุณจะบิด data model ให้เข้ากับรูปที่วาดไว้ แต่ถ้าตกลง contract กับ data ให้จบก่อน กล่องจะวาดตัวมันเอง — เพราะกล่อง 1 ใบก็แค่ "สิ่งที่เป็นเจ้าของข้อมูลชุดนี้และ serve contract นี้" ทีมที่วาดก่อนเถียงเรื่อง topology กันเป็นสัปดาห์ ทีมที่ทำ model ก่อนเถียง 2 วันแล้วตกลงกันได้
ขั้นที่ 1 — Clarification script
ถามตามลำดับนี้ ห้ามกระโดดไปที่ทางแก้ ในโปรเจกต์จริง คนที่มาสั่งงานมักยังไม่เคยคิดถึงครึ่งหนึ่งของคำถามพวกนี้ และคำถามของคุณคือคุณค่าที่คุณเพิ่มเข้าไป
| หมวด | คำถามที่ต้องถาม | ทำไมมันเปลี่ยน design |
|---|---|---|
| Users & actors | ใครใช้ — ลูกค้า, ops ภายใน, ระบบ partner, regulator? แต่ละกลุ่มกี่คน | เครื่องมือ ops ทน latency 2 วินาทีได้ payment API ทนไม่ได้; ระบบ partner หมายถึงต้องทำ versioning ตลอดไป |
| Core use cases | 3 อย่างที่ต้องทำได้คืออะไร และ อะไรอยู่นอก scope ของ v1 ชัดๆ | non-goal กัน over-engineering ได้ถึง 80% — เขียนลงกระดาษและให้คนเห็นด้วย |
| Read/write shape | read-heavy หรือ write-heavy? อัตราส่วนเท่าไหร่? พีคเป็นก้อนหรือสม่ำเสมอ? | read-heavy → cache + replica; write-heavy → partition, batch, LSM store |
| Latency | p99 ที่ผู้ใช้รู้สึกคือเท่าไหร่? มีส่วนไหนเป็น asynchronous ได้ไหม | "อันนี้ async ได้" คือประโยคที่ทรงพลังที่สุดใน system design — ตามหามันให้เจอ |
| Consistency | ถ้าผู้ใช้เห็นข้อมูลเก่า 2 วินาที อะไรพัง? ถ้า 2 นาที? | นี่คือวิธีขออนุญาตใช้ eventual consistency ด้วยภาษาธุรกิจ |
| Availability | ล่ม 1 ชั่วโมงตอนบ่าย 2 วันธรรมดา เสียหายเท่าไหร่? degraded mode รับได้ไหม | เปลี่ยน "เราต้องการ 99.99%" ให้เป็นตัวเลขที่ธุรกิจตีราคาได้ — ปกติเขาจะยอมรับน้อยกว่านั้น |
| Durability | ยอมเสียข้อมูลได้ 1 record ไหม? RPO เท่าไหร่ | เงินและ audit log: RPO = 0 ซึ่งบังคับให้ต้องมี synchronous replication และ backup จริง |
| Scale & growth | ตัวเลขวันนี้ และแผน 12 เดือน มี launch campaign ไหม | ออกแบบเผื่อ 10 เท่าของวันนี้ ไม่ใช่ 1,000 เท่า เกิน 10 เท่าให้วางเส้นทาง migration ไว้ ไม่ต้อง build วันนี้ |
| Compliance & data | มีข้อมูลส่วนบุคคลไหม? ข้อมูลบัตร? ส่งข้อมูลข้ามประเทศไหม? เก็บนานเท่าไหร่? ต้องมี audit trail แบบไหน | ภายใต้ PDPA และกฎ card scheme (PCI DSS) เรื่องพวกนี้กำหนด encryption, tokenization, logging, residency, การลบ — มันคือสถาปัตยกรรม ไม่ใช่เอกสาร |
| Constraints | ทีมกี่คนทักษะอะไร, งบ, deadline, vendor ที่ถูกกำหนดมา, ระบบเดิมที่แก้ไม่ได้ | พื้นที่ design จริงเล็กกว่าพื้นที่ทฤษฎีมาก — หาขอบของมันให้เจอเร็วๆ |
ห้ามเดาคำตอบเรื่อง compliance
ระยะเวลาเก็บข้อมูล, KYC threshold, การส่งข้อมูลข้ามประเทศที่อนุญาต
และนิยามว่าอะไรคือ "ข้อมูลส่วนบุคคลอ่อนไหว" เป็นการตัดสินทางกฎหมายและนโยบาย
หน้าที่ของ architect คือ ยกคำถามขึ้นมา, บันทึกคำตอบที่ได้รับ, และบันทึกว่าใครให้คำตอบนั้น
เขียนใน design doc ว่า Retention = 10 ปี ตาม [ชื่อเจ้าของเรื่อง] ยืนยันวันที่ [วันที่]
อย่าคิดขึ้นมาเอง — design ที่สร้างบนสมมติฐาน compliance ที่แต่งขึ้นจะไม่ผ่าน audit
และ reviewer จะไม่เชื่ออะไรอีกเลยในเอกสารนั้น (ซึ่งถูกต้อง)
แปลงคำคลุมเครือให้เป็นตัวเลขที่ทดสอบได้
| เขาพูดว่า | คุณเขียนลงไปว่า |
|---|---|
| "ต้องเร็ว" | p99 < 300 ms สำหรับ GET /balance วัดที่ API gateway ไม่รวม network ฝั่ง client |
| "ต้องไม่ล่ม" | availability 99.9% ต่อเดือนสำหรับ payment path (งบล่ม ≈ 43 นาที/เดือน); 99.5% สำหรับ reporting path |
| "ต้อง real-time" | end-to-end < 2 s สำหรับ 95% ของ notification; < 30 s สำหรับ 99.9% (ถามด้วยว่า real-time สำหรับ คน หรือสำหรับ เครื่อง) |
| "ต้อง scale ได้" | รับ 1,000 tps ต่อเนื่อง และขยายถึง 3,000 tps ได้ด้วยการเพิ่ม node โดยไม่แก้โค้ดและไม่แก้ schema |
| "ต้องปลอดภัย" | least privilege ต่อ service identity; PII เข้ารหัสตอน at rest และ mask ใน log; ไม่เก็บ card PAN; มี audit trail ว่าใครอ่านอะไร |
| "ต้อง consistent" | การอ่านยอดเงินเป็น read-your-own-writes สำหรับผู้จ่าย; มุมมองของคนอื่นช้าได้ถึง 5 s |
ประโยคที่ควรใช้ให้ติดปาก
"ถ้าเราวัดที่ … และค่าเกิน … ถือว่าไม่ผ่าน — ตกลงกันแบบนี้ไหม" requirement ที่ผ่านประโยคนี้ได้จะกลายเป็น SLO ในภายหลังโดยไม่ต้องเขียนใหม่
ขั้นที่ 2 — ประเมิน scale
ใช้วิธีจากบทที่ 2 แล้วเพิ่มนิสัย 2 อย่างที่แยกมืออาชีพออกจากมือสมัครเล่น
1 — เขียนสมมติฐานไว้ในบรรทัดนั้นเลย เช่น "สมมติ DAU 20%, สมมติ peak factor 8 เท่า" แล้ว reviewer จะเถียงกับ สมมติฐาน ของคุณ ไม่ใช่ ข้อสรุป ของคุณ ซึ่งเป็นบทสนทนาที่เร็วกว่ามาก
2 — คำนวณขีดจำกัดที่ derive ออกมาแล้วมันสำคัญ ไม่ใช่แค่ "300 tps" แต่เป็น:
300 tps x 5 ledger rows = 1,500 row-inserts/s
เทียบกับตัวเลขวางแผน relational DB (1,000-5,000 writes/s) แล้ว
1,500 inserts/s อยู่เหนือระดับที่สบายสำหรับ schema ปัจจุบัน
(เรามี 6 index บนตาราง ledger_entries)
--> ทางเลือก: (a) batch insert เป็นชุด, (b) ลดจำนวน index,
(c) partition by account_id, (d) แยกตาราง hot/cold
--> ต้องมี load test ยืนยันก่อนเลือก
ตัวเลข scale มีความหมายก็ตอนที่คุณเชื่อมมันเข้ากับขีดจำกัดของ component เท่านั้น
กับดัก "ออกแบบเผื่อ 1,000 เท่า"
การออกแบบเผื่อโหลด 1,000 เท่าตั้งแต่วันแรกทำให้คุณจ่าย complexity วันนี้ เพื่อสถานการณ์ที่อาจไม่มาถึง และมักทำให้ขึ้นระบบช้าจนธุรกิจไม่รอ กฎที่ใช้ได้: build เผื่อ 10 เท่า, วางแผน migration ไว้สำหรับ 100 เท่า, และเขียนไว้ใน design doc ว่า 100 เท่าจะเปลี่ยนอะไร
ขั้นที่ 3–7 อยู่บทถัดไป
3 ขั้นแรกกินเนื้อหามากพอที่จะแยกบท:
- ขั้นที่ 3 (Contracts) อยู่ในบทที่ 4 — API contract, error semantics และ event schema
- ขั้นที่ 4–7 (Data model → Architecture → Deep dives → Failures) อยู่ในบทที่ 5
Lab 3 — รัน CADENCE กับ brief ที่ยังคลุมเครือ
Brief (คลุมเครือโดยเจตนา เพราะ brief จริงก็เป็นแบบนี้):
"เราอยากเพิ่มการจ่ายบิลในแอป wallet ผู้ใช้ควรสแกน barcode ของผู้ออกบิล จ่าย แล้วเห็นใบเสร็จ ทางธุรกิจบอกว่าต้องเชื่อถือได้เพราะเป็นบิลค่าสาธารณูปโภคที่มีวันครบกำหนด"
Deliverable แบบจับเวลา (รวม 90 นาที ทำเป็นคู่):
| เวลา | สิ่งที่ต้องส่ง |
|---|---|
| 15 นาที | ตาราง requirement พร้อม quality attribute + non-goal 5 ข้อ |
| 10 นาที | บล็อก estimation ที่เขียนสมมติฐานไว้ในบรรทัด รวมพีคของ วันสุดท้ายของเดือน |
| 15 นาที | API contract ของ create-payment และ get-status พร้อมตาราง error ครบและกฎ idempotency |
| 15 นาที | Access pattern table (อย่างน้อย 6 pattern) และ data model ที่ serve มันได้ |
| 15 นาที | Architecture diagram 1 ใบ + happy-path trace แบบเขียน + failure trace 2 เส้น |
| 10 นาที | Failure table อย่างน้อย 6 แถว |
| 10 นาที | นำเสนอให้อีกคู่ฟัง เขาต้องพยายามทำให้มันพัง จดทุกรูที่เขาหาเจอ — ลิสต์นั้นคือคะแนนจริงของคุณ |
เกณฑ์ให้คะแนน
+2 ต่อสมมติฐานที่เขียนออกมาชัด · +3 ต่อ failure mode ที่มี สัญญาณตรวจจับ ระบุไว้ · +5 ต่อการระบุ trade-off ที่คุณ เลือกยอมรับอย่างรู้ตัว · −5 ต่อทุก component ในไดอะแกรมที่ไม่มี requirement ข้อไหนต้องการ
[!NOTE] สรุปบทนี้ ลำดับเดิมทุกครั้ง — clarify, scale, contract, data, diagram, deep dive, failure · contract และ data model มาก่อนกล่อง · แปลงคำคลุมเครือเป็นตัวเลขที่วัดได้ · เขียนสมมติฐานไว้ให้คนแย้ง · และเชื่อตัวเลขเข้ากับขีดจำกัดของ component เสมอ