เนื้อหาขั้นต่อจาก Computer Networks / Network Computing ว่าด้วยการทำให้หลาย process หลายเครื่อง และหลายบริการร่วมกันเป็นระบบเดียว พร้อมปรับแนวคิดคลาสสิกให้เชื่อมกับ cloud, container, microservices และระบบข้อมูลกระจายในปัจจุบัน
ผมเคยสอนเนื้อหาชุดนี้ในช่วงปี 2017–2018 ตอนนั้นคำว่า cloud เริ่มกลายเป็นเรื่องปกติมากขึ้น container กำลังเปลี่ยนวิธีติดตั้งระบบ และ microservices ถูกพูดถึงราวกับเป็นคำตอบของทุกปัญหา เวลาผ่านมาไม่กี่ปี ชื่อเครื่องมือหลายตัวเปลี่ยนไป บาง framework หายจากกระแส บางเทคโนโลยีกลายเป็นของพื้นฐาน และบางสิ่งที่เคยดูเหมือนของใหม่ก็เริ่มแสดงต้นทุนที่ซ่อนอยู่ชัดขึ้น
แต่เมื่อกลับมาเปิดเนื้อหา Distributed Systems อีกครั้ง สิ่งที่น่าสนใจคือคำถามหลักแทบไม่ได้เก่าไปตามเครื่องมือเลย เรายังต้องถามเหมือนเดิมว่า ถ้าไม่มีนาฬิกากลางจะเรียงเหตุการณ์อย่างไร ถ้าได้รับคำขอซ้ำจะรู้ได้อย่างไรว่าควรทำซ้ำหรือคืนผลเดิม ถ้าเครื่องหนึ่งเงียบไป เราจะแยกได้อย่างไรว่ามันล่ม เครือข่ายขาด หรือเพียงตอบช้า และถ้าข้อมูลมีสำเนาหลายชุด เราจะยอมให้แต่ละชุดต่างกันได้นานเท่าใด
นี่คือเหตุผลที่ผมนำเนื้อหาชุดเดิมกลับมาปรับปรุง ไม่ใช่เพื่อเปลี่ยนชื่อ CORBA เป็น gRPC แล้วเรียกว่าทันสมัย แต่เพื่อรักษาโครงความคิดเดิมที่ยังใช้ได้ พร้อมเปลี่ยนตัวอย่างให้ผู้เรียนเห็นว่าปัญหาเดียวกันปรากฏอยู่ในระบบปัจจุบันตรงไหนบ้าง จาก remote object มาสู่ service API จาก group communication มาสู่ message broker จาก distributed transaction มาสู่ Saga และ Transactional Outbox และจากแนวคิด replication ในตำรามาสู่ distributed database ที่เราเรียกใช้ผ่าน cloud console ได้ภายในไม่กี่นาที
เอกสารชุดนี้จึงไม่ตั้งใจเป็นพิพิธภัณฑ์ของเทคโนโลยี และไม่ตั้งใจเป็นคู่มือใช้ผลิตภัณฑ์ใดผลิตภัณฑ์หนึ่ง เป้าหมายคือให้ผู้เรียนอ่านระบบใหม่แล้วมองเห็นปัญหาเก่าในรูปแบบใหม่ เมื่อพบคำว่า service discovery ควรเชื่อมกลับไปหา naming เมื่อพบ distributed tracing ควรเชื่อมกลับไปหา ordering และ causality เมื่อพบ eventual consistency ควรถามต่อว่าความไม่ตรงกันชั่วคราวนั้นมีขอบเขตและผลกระทบต่อผู้ใช้อย่างไร
วิชานี้เป็นเนื้อหาขั้นสูงที่ต่อจาก Computer Networks / Network Computing โดยตรง ในวิชา Networks เราศึกษาว่าข้อมูลออกจาก application ผ่าน transport และ network ไปถึงปลายทางได้อย่างไร เราพูดถึง address, routing, TCP, UDP, HTTP, socket, timeout และเครื่องมือวินิจฉัย แต่เมื่อโปรแกรมสองตัวเริ่มคุยกันได้ คำถามชุดใหม่จะเกิดขึ้นทันที เพราะ “ส่งข้อความถึงกันได้” ยังไม่เท่ากับ “ร่วมกันทำงานได้อย่างถูกต้อง”
Distributed Systems เริ่มตรงรอยต่อนั้น เราไม่ได้มอง packet เป็นหน่วยหลักเพียงอย่างเดียวอีกต่อไป แต่เริ่มมอง request, object, transaction, replica, event และ process ที่มีสถานะของตนเอง ปัญหาไม่ใช่เพียงข้อความจะไปถึงหรือไม่ แต่รวมถึงข้อความมาถึงซ้ำ มาถึงช้า มาถึงคนละลำดับ หรือมาถึงหลังจากอีกฝ่ายเปลี่ยนสถานะไปแล้ว เครือข่ายจึงไม่ได้หายไปจากภาพ มันเปลี่ยนจากหัวข้อที่ศึกษาโดยตรงมาเป็นเงื่อนไขที่ทำให้การคำนวณไม่แน่นอน
ในอีกด้านหนึ่ง เนื้อหาชุดนี้ทำหน้าที่เป็นพื้นฐานของวิชา Scalable Computing ซึ่งใช้ชื่อเดิมว่า Parallel and Distributed Systems วิชา Scalable Computing จะขยับจากคำถามว่า “ระบบกระจายทำงานถูกต้องอย่างไร” ไปสู่คำถามว่า “ระบบจะเติบโตได้ไกลเพียงใด และข้อจำกัดอยู่ตรงไหน” ผู้เรียนจะต้องวิเคราะห์ work/span, decomposition, communication cost, memory, placement, ordering, failure และ adaptation ความเข้าใจเรื่อง message passing, consistency, replication, coordination และ failure model จากวิชานี้จะช่วยให้เนื้อหาเหล่านั้นไม่กลายเป็นสูตรหรือชื่อ pattern ที่ลอยอยู่โดยไม่มีแบบจำลองรองรับ
ควรผ่านหรือมีความเข้าใจใน Computer Networks / Network Computing ก่อน ไม่จำเป็นต้องจำรายละเอียด header ทุก bit แต่ควรมีแบบจำลองในหัวว่าการสื่อสารข้ามเครื่องมีต้นทุน มีความล่าช้า และล้มเหลวได้หลายแบบ ถ้ายังมอง remote call ว่าเหมือนเรียก function ในเครื่องเดียว เพียงเขียน URL เพิ่มเข้ามา เนื้อหาเรื่อง timeout, retry, idempotency และ partial failure จะดูเหมือนข้อควรระวังย่อย ๆ ทั้งที่จริงแล้วเป็นแกนของวิชา
ถ้ายังไม่มั่นใจ ให้กลับไปอ่านชุด Computer Networks / Network Computing โดยเน้น Communication & Reliability, Protocol & Layering, Performance, Socket API, Network Programming, Network Services และ Failure/Deployment เนื้อหาเหล่านี้เป็นพื้น ไม่ใช่เพราะวิชานี้ต้องการตั้งกำแพง prerequisite แต่เพราะ distributed algorithm ทุกตัวทำงานอยู่บนเครือข่ายจริง ซึ่งไม่ได้ส่งข้อความทันที ไม่ได้รับประกันว่าทุกคนจะเห็นเหตุการณ์เดียวกัน และไม่ส่ง exception ที่อธิบายความจริงทั้งหมดกลับมาให้เราอย่างสุภาพ
เนื้อหาจัดเรียงเป็นลำดับต่อเนื่อง — แต่ละบทอ้างอิงกลับไปยังบทก่อนหน้าและเชื่อมโยงไปข้างหน้า แนะนำให้ไล่ตามลำดับ 1 → 11 ในการเรียนครั้งแรก
นิยามระบบกระจาย ความท้าทายพื้นฐาน และกลไกสื่อสารที่ทุกบทถัดไปใช้ต่อ
ความถูกต้องของข้อมูลเมื่อมีการเข้าถึงพร้อมกัน ทั้งบนเครื่องเดียวและข้ามเครื่อง รวมถึงการจัดการชื่อและเวลาที่ไม่มีนาฬิกากลาง
การเก็บและกระจายข้อมูลให้ทนต่อความล้มเหลวและสเกลได้ พร้อม trade-off ระหว่าง consistency และ availability
การตกลงร่วมกันของกลุ่ม process ในสภาพแวดล้อมที่ล้มเหลวได้ทุกเมื่อ ไปจนถึงระบบที่ไม่มีศูนย์กลางเลย
บททั้ง 11 บทไม่ได้เรียงเพราะหัวข้อหนึ่งเก่ากว่าอีกหัวข้อหนึ่ง แต่เรียงตามสิ่งที่ระบบต้องเพิ่มเข้ามาทีละชั้น เริ่มจากนิยามว่าเรากำลังเรียกอะไรว่า distributed system จากนั้นสร้างการสื่อสารข้าม process ทำให้การเรียกดูคล้าย local call แล้วจึงพบว่าความสะดวกนั้นซ่อน failure ไว้ เมื่อระบบเริ่มแก้ข้อมูลพร้อมกัน เราต้องนิยาม transaction และ concurrency เมื่อ transaction ข้ามเครื่อง ปัญหาก็เปลี่ยนจาก lock ในฐานข้อมูลเดียวไปสู่การตกลงระหว่างผู้เข้าร่วมที่อาจหายไปกลางทาง
| ช่วง | คำถามหลัก | สิ่งที่ไม่ควรเข้าใจผิด | ตัวอย่างปัจจุบันที่เชื่อมได้ |
|---|---|---|---|
| บท 1: System Models | ส่วนประกอบอยู่ที่ไหน สื่อสารแบบใด และล้มเหลวได้อย่างไร | แผนภาพกล่องกับลูกศรยังไม่ใช่ system model ถ้าไม่บอกเวลาและ failure assumption | cloud region, container, edge, serverless |
| บท 2: IPC | process ส่งข้อมูลและสร้าง request–reply อย่างไร | ส่งสำเร็จไม่เท่ากับประมวลผลสำเร็จ และ multicast ไม่เท่ากับ broadcast ทุกกรณี | HTTP, messaging, broker, event streaming |
| บท 3: Remote Invocation | จะซ่อนรายละเอียดเครือข่ายได้แค่ไหน | remote call ไม่มีวันเหมือน local call จริง เพราะ latency และ failure semantics ต่างกัน | gRPC, Protocol Buffers, service client |
| บท 4–5: Transactions | หลายงานเปลี่ยนข้อมูลพร้อมกันและข้ามเครื่องอย่างไร | ACID ในฐานข้อมูลเดียวไม่ย้ายไปครอบหลาย service โดยอัตโนมัติ | MVCC, 2PC, Saga, Outbox |
| บท 6: Naming | ชื่อหนึ่งชื่อถูกแปลไปหาทรัพยากรที่เปลี่ยนตำแหน่งได้อย่างไร | ชื่อ, address, identifier และ location ไม่ใช่คำเดียวกัน | DNS, service discovery, registry |
| บท 7: Time & State | เมื่อไม่มีนาฬิกากลาง จะรู้ได้อย่างไรว่าอะไรเกิดก่อนและระบบอยู่ในสถานะใด | timestamp จากนาฬิกาจริงไม่ได้รับประกัน causal order | Lamport clock, vector clock, tracing |
| บท 8–9: Storage & Replication | จะเก็บสำเนาเพื่อความเร็วและความทนทานโดยไม่ทำลายความหมายอย่างไร | สำเนามากขึ้นไม่ได้ให้ทั้ง performance, availability และ consistency ฟรี | object storage, CDN, distributed DB |
| บท 10: Agreement | สมาชิกที่เห็นข้อมูลไม่พร้อมกันจะตัดสินใจร่วมกันได้อย่างไร | consensus ไม่ได้ทำให้เครือข่ายเชื่อถือได้ มันกำหนดวิธีเดินหน้าภายใต้ failure model | Raft, leader election, quorum |
| บท 11: P2P & Ubiquitous | ระบบที่ไม่มีศูนย์กลางและมีสมาชิกเปลี่ยนตลอดจะจัดโครงสร้างอย่างไร | decentralized ไม่ได้แปลว่าไม่มีการประสานงานหรือไม่มีจุดอ่อน | DHT, edge, mobile, IoT |
เมื่ออ่านแบบนี้ CORBA และ Java RMI ไม่ได้เป็นเพียงเทคโนโลยีเก่าที่ควรข้าม แต่เป็นกรณีศึกษาว่าเราพยายามทำให้ remote call โปร่งใสเพียงใด และจุดใดที่ abstraction เริ่มรั่ว ส่วน gRPC ไม่ได้ลบปัญหาเดิม มันปรับ interface definition, serialization และ tooling ให้เหมาะกับระบบยุคใหม่มากขึ้น แต่ปลายทางยังช้า ล่ม ตอบซ้ำ หรือทำงานสำเร็จทั้งที่คำตอบหายได้เหมือนเดิม
ระบบหนึ่งอาจตอบถูกทุกครั้งแต่ช้าจนใช้งานไม่ได้ และอีกระบบอาจรองรับผู้ใช้จำนวนมากแต่คืนข้อมูลผิดเมื่อเกิด race condition การออกแบบระบบจริงต้องถือสองเลนส์พร้อมกัน Distributed Systems มักเริ่มจากความหมายและความถูกต้องภายใต้ concurrency/failure ส่วน Scalable Computing เริ่มจาก work, critical path, resource, communication และขอบเขตที่ระบบขยายได้ ทั้งสองวิชาจึงไม่ได้แข่งขันกันว่าใคร “ขั้นสูงกว่า” แต่ถามคนละด้านของระบบเดียวกัน
| หัวข้อใน Distributed Systems | คำถามที่ควรนำไปถามต่อใน Scalable Computing |
|---|---|
| Message passing / RPC | ข้อความหนึ่งครั้งมี latency และ serialization cost เท่าใด ควรรวมงานให้หยาบขึ้นหรือขนานเพิ่มตรงไหน |
| Concurrency control | lock หรือ contention จำกัด throughput ที่จุดใด เมื่อจำนวน worker เพิ่มแล้ว speedup หยุดเพราะอะไร |
| Distributed transactions | coordination เพิ่ม critical path และ failure surface มากเพียงใด จะลด synchronous dependency ได้หรือไม่ |
| Time and ordering | ข้อกำหนดเรื่องลำดับทำให้ parallelism ลดลงตรงไหน และงานส่วนใดไม่จำเป็นต้องมี total order |
| Replication | replica เพิ่ม read throughput เท่าใด write amplification กับ repair traffic โตอย่างไร |
| Coordination and agreement | จำนวนรอบการสื่อสาร quorum size และ geographic placement กระทบ tail latency อย่างไร |
| P2P / decentralized system | routing hop, data placement, churn และ load balance กำหนด scalability envelope อย่างไร |
วิธีอ่านที่แนะนำคือเลือก concept หนึ่งเรื่อง แล้วเขียนบันทึกสองคอลัมน์ คอลัมน์แรกถามว่า “ต้องรับประกันความหมายอะไร” คอลัมน์ที่สองถามว่า “การรับประกันนี้มีต้นทุนอะไรเมื่อระบบโต” การฝึกเช่นนี้จะช่วยไม่ให้เลือก algorithm จากความเร็วเพียงอย่างเดียว และไม่ออกแบบ correctness โดยลืมว่าระบบต้องตอบผู้ใช้ภายในเวลาจริง
การปรับปรุงเนื้อหาไม่ควรทำด้วยวิธีลบทุกอย่างที่มีอายุมากกว่าห้าปี เพราะแนวคิดจำนวนมากต้องอาศัยกรณีศึกษาทางประวัติศาสตร์เพื่อเห็นว่าปัญหาถูกค้นพบและแก้ไขมาอย่างไร แต่ก็ไม่ควรหยุดที่ชื่อเทคโนโลยีซึ่งผู้เรียนอาจไม่พบในงานจริงแล้ว เอกสารแต่ละบทจึงรักษาแนวคิดแกนกลางไว้ แล้วเพิ่มสะพานไปยังเทคโนโลยีร่วมสมัย
| แกนความรู้ที่ยังจำเป็น | ตัวอย่างเดิมที่ใช้เรียนรู้ | สิ่งที่เชื่อมเพิ่มในฉบับปรับปรุง |
|---|---|---|
| External Data Representation และ marshalling | XDR, object serialization | JSON, Protocol Buffers, schema evolution |
| Remote invocation และ interface contract | CORBA, Java RMI | REST/gRPC, generated client, deadline propagation |
| Atomic commitment | Two-Phase Commit | Saga, compensating action, Transactional Outbox |
| Naming และ location transparency | directory/name service | DNS, container service name, cloud registry |
| Logical time และ global state | Lamport/vector clock, snapshot | event ordering, distributed tracing, stream processing |
| Replication และ quorum | primary/backup, active replication | eventual consistency, Dynamo-style systems, geo-replication |
| Coordination และ agreement | election, Byzantine/general agreement | Raft, etcd/consensus-backed control plane |
| P2P overlay | Chord และ DHT | content addressing, edge collaboration, decentralized services |
บางแนวคิดจะถูกวิจารณ์มากขึ้นด้วย เช่นคำว่า transparency ฟังดูดีเพราะทำให้ของไกลดูเหมือนของใกล้ แต่การซ่อน latency และ failure มากเกินไปทำให้นักพัฒนาเขียน remote call ราวกับ local call จนระบบสร้าง call chain ยาวและล้มเป็นทอด ๆ ความก้าวหน้าจึงไม่ได้แปลว่า abstraction ต้องซ่อนทุกอย่าง บางครั้งระบบสมัยใหม่ที่ดีขึ้นกลับเลือกเปิดเผย deadline, retry policy, consistency level และ failure ให้ผู้ใช้ library ตัดสินใจอย่างชัดเจน
ความเข้าใจทางด้าน Distributed Systems ของผมไม่ได้เริ่มจากการอ่านตำราเพียงลำพัง แต่ได้รับการประสิทธิ์ประสาทและวางรากฐานจากคณาจารย์ภาควิชาวิศวกรรมคอมพิวเตอร์ คณะวิศวกรรมศาสตร์ จุฬาลงกรณ์มหาวิทยาลัย ได้แก่ ผศ.ดร.ณัฐวุฒิ หนูไพโรจน์, ผศ.ดร.วีระ เหมืองสิน, อ.ดร.ยรรยง เต็งอำนวย และ รศ.ดร.ทวิตีย์ เสนีวงศ์ ณ อยุธยา
อาจารย์แต่ละท่านช่วยทำให้ผมเห็นระบบจากคนละมุม ทั้ง parallel/distributed systems, system software, networking, distributed technology และ service-oriented computing สิ่งที่มีค่ากว่าการจำชื่อ algorithm คือวิธีตั้งคำถามว่าแบบจำลองสมมุติอะไร สิ่งใดรับประกันได้จริง และระบบจะมีพฤติกรรมอย่างไรเมื่อข้อสมมุติไม่เป็นจริง
เอกสารชุดนี้เป็นการนำความรู้เหล่านั้นมาจัดระเบียบใหม่ตามประสบการณ์สอนและเทคโนโลยีในปัจจุบัน หากมีส่วนใดที่ช่วยให้ผู้เรียนมองระบบได้ชัดขึ้น เครดิตสำคัญย่อมย้อนกลับไปถึงครูผู้วางรากฐาน ส่วนข้อผิดพลาดหรือการตีความที่คลาดเคลื่อนในเอกสารฉบับนี้เป็นความรับผิดชอบของผู้เรียบเรียงเอง
เนื้อหาทั้ง 11 บทอิงโครงสร้างวิชา Distributed Information System ตามตำรา Coulouris, Dollimore, Kindberg & Blair — Distributed Systems: Concepts and Design (Edition 5) ซึ่งเป็นตำรามาตรฐานของวิชาระบบกระจายระดับปริญญาตรีและโท
ทุกบทมีส่วน "ทันสมัย" ที่เชื่อมโยงทฤษฎีคลาสสิกเข้ากับเทคโนโลยีที่ใช้งานจริงในปัจจุบัน เช่น Saga Pattern แทน 2PC, Raft แทน Paxos แบบดั้งเดิม, gRPC แทน CORBA, และ Consistent Hashing ใน Cassandra/DynamoDB ที่สืบทอดมาจาก Chord DHT — เพื่อให้เห็นว่าปัญหาพื้นฐานของระบบกระจายไม่เคยหายไป เพียงเปลี่ยนรูปแบบการแก้ตามยุคสมัยเท่านั้น
สำหรับการเรียนครั้งแรก แนะนำให้เริ่มบทที่ 1 เพื่อสร้าง vocabulary และ system model ร่วมกัน แล้วอ่านบทที่ 2–3 ให้เห็นว่าการสื่อสารพื้นฐานถูกยกขึ้นมาเป็น abstraction อย่างไร จากนั้นบทที่ 4–7 จะค่อย ๆ เปิดปัญหาเรื่องการเปลี่ยนข้อมูล ชื่อ เวลา และสถานะ ส่วนบทที่ 8–11 นำแนวคิดเหล่านั้นไปใช้กับการเก็บข้อมูล การทำสำเนา การตกลงร่วมกัน และระบบที่ไม่มีศูนย์กลาง
แต่ไม่จำเป็นต้องอ่านแบบไปข้างหน้าอย่างเดียว เมื่อพบ retry ในระบบจริงให้ย้อนกลับไปดู invocation semantics เมื่อพบข้อมูลไม่ตรงกันให้เชื่อม transaction, time และ replication เข้าด้วยกัน และเมื่อพบ performance problem ให้เปิดวิชา Scalable Computing ควบคู่ไปถามว่าต้นทุนเกิดจาก work, communication, contention, placement หรือ ordering วิชาระบบกระจายจะเริ่มมีชีวิตเมื่อบทต่าง ๆ อธิบายเหตุการณ์เดียวกันได้จากหลายมุม
เป้าหมายปลายทางไม่ใช่การท่องว่า 2PC, Raft หรือ vector clock ทำงานเป็นขั้นตอนใดเท่านั้น แต่คือการมองระบบหนึ่งแล้วบอกได้ว่าใครสื่อสารกับใคร สมมุติเรื่องเวลาและ failure อย่างไร ต้องรักษาความหมายอะไร และต้องจ่ายต้นทุนเท่าใด เมื่อทำได้ Distributed Systems จะไม่เป็นเพียงวิชาที่เคยสอนในปี 2017–2018 แต่เป็นพื้นภาษาที่ใช้คิดกับ Scalable Computing และระบบสมัยใหม่แทบทุกชนิดต่อจากนี้