Distributed Systems · บทที่ 7 จาก 11

Time & Global States

ย้อนกลับไปบทที่ 1: ระบบกระจายไม่มีนาฬิกากลาง — แล้วจะรู้ได้อย่างไรว่าเหตุการณ์ A เกิดก่อนเหตุการณ์ B? บทนี้ตอบคำถามนี้ด้วยแนวคิดที่เปลี่ยนมุมมองต่อ "เวลา" ไปตลอดกาลสำหรับวิศวกรระบบกระจาย

📚
อิงเนื้อหาจาก Coulouris บทที่ 11 (Time and Global States) — Lamport Clock และ Vector Clock ในบทนี้คือรากฐานทางทฤษฎีของ Correlation ID และ Distributed Tracing ที่สอนในวิชา Network Computing หัวข้อที่ 3 และ 4

1Physical Clock: ทำไมนาฬิกาเครื่องจริงเชื่อถือไม่ได้เต็มร้อย

Clock Drift และ Clock Skew
นาฬิกาฮาร์ดแวร์ (quartz crystal) ในแต่ละเครื่องเดินเร็ว/ช้ากว่าเวลาจริงเล็กน้อยและไม่เท่ากัน เรียกอัตราความคลาดเคลื่อนนี้ว่า clock drift rate — ผลสะสมทำให้นาฬิกาสองเครื่อง ณ เวลาเดียวกันมีค่าต่างกัน เรียกว่า clock skew
วิธี Synchronizeแนวคิด
Cristian's AlgorithmClient ขอเวลาจาก time server ที่เชื่อถือได้ (เช่นอ้างอิง atomic clock) แล้วปรับตามค่าประมาณ round-trip time — ใช้ได้ในเครือข่ายที่ latency ค่อนข้างสมมาตรและคาดเดาได้
Berkeley Algorithmไม่มี time server ที่ "ถูกต้องแน่นอน" — master รวบรวมเวลาจากทุกเครื่องในกลุ่ม เฉลี่ยแล้วบอกทุกเครื่องให้ปรับเข้าหาค่าเฉลี่ยนั้น เหมาะกับกลุ่มเครื่องที่ไม่มีการเชื่อมต่อไปยัง external time source
NTP (Network Time Protocol)โครงสร้างลำดับชั้น (stratum) ตั้งแต่นาฬิกาอะตอมมิก/GPS (stratum 0) ลงมาจนถึงเครื่องผู้ใช้ทั่วไป ใช้กันอย่างแพร่หลายในอินเทอร์เน็ตจริง
ข้อจำกัดที่แก้ไม่ได้เต็มร้อย
ไม่ว่า sync ดีแค่ไหน นาฬิกาสองเครื่องจะไม่มีทาง "ตรงกันเป๊ะ" ตลอดเวลาได้ — จึงต้องมีวิธีอื่นเรียงลำดับเหตุการณ์ที่ไม่พึ่งพา physical clock โดยตรง

2Logical Time: Lamport Clock

แนวคิดของ Leslie Lamport
แทนที่จะถามว่า "เหตุการณ์เกิดเวลาอะไร" (ตามนาฬิกาจริง) ให้ถามแค่ว่า "เหตุการณ์ไหนอาจเป็นสาเหตุของอีกเหตุการณ์" — เรียกความสัมพันธ์นี้ว่า happened-before relation (เขียนแทนด้วย →)
กรณีสรุปว่า → เป็นจริง
เหตุการณ์ในกระบวนการ (process) เดียวกันถ้า a เกิดก่อน b ในลำดับการทำงานของ process เดียวกัน a → b
การส่งและรับข้อความถ้า a คือการส่งข้อความ และ b คือการรับข้อความเดียวกันนั้น a → b เสมอ
Transitivityถ้า a → b และ b → c แล้ว a → c
กติกาการนับ Lamport Timestamp
ทุก process มีตัวนับ (counter) ของตัวเอง
LC1: ก่อนแต่ละ event ในเครื่องตัวเอง — เพิ่มค่า counter ขึ้น 1 LC2: เมื่อส่งข้อความ — แนบค่า counter ปัจจุบันไปกับข้อความ LC3: เมื่อรับข้อความ — ตั้งค่า counter เป็น max(counter ตัวเอง, ค่าที่แนบมา) + 1
ข้อจำกัดสำคัญ
ถ้า Lamport(a) < Lamport(b) ไม่ได้แปลว่า a → b เสมอไป — Lamport clock ให้แค่ partial ordering ที่ถูกต้องในทิศทางเดียว (a → b ⇒ Lamport(a) < Lamport(b)) แต่ไม่ใช่ทิศทางกลับ เหตุการณ์ที่เกิดขึ้น "พร้อมกัน" (concurrent, ไม่มีความสัมพันธ์เชิงสาเหตุ) อาจได้ Lamport timestamp ต่างกันโดยบังเอิญ ทำให้ดูเหมือนเรียงลำดับได้ทั้งที่จริง ๆ ไม่มีความสัมพันธ์เชิงเหตุ-ผลกันเลย

เพื่อให้ได้ total ordering (ทุกเหตุการณ์เทียบกันได้หมดแม้ concurrent) มักเสริมด้วยการเทียบ process ID เป็น tie-breaker เมื่อค่า Lamport timestamp เท่ากัน

3Vector Clock: แก้ข้อจำกัดของ Lamport Clock

แนวคิด
แทนที่จะใช้ตัวเลขเดียว แต่ละ process เก็บ เวกเตอร์ของ counter ขนาด N (N = จำนวน process ทั้งหมดในระบบ) — ทำให้เปรียบเทียบเวกเตอร์สองตัวแล้วรู้ได้ทันทีว่าเหตุการณ์หนึ่ง "เป็นสาเหตุ" ของอีกเหตุการณ์จริงหรือไม่ หรือเป็นแค่ concurrent
กติกาของ Vector Clock
VC1: ก่อน event ในเครื่องตัวเอง — เพิ่มค่าตำแหน่งของตัวเองในเวกเตอร์ขึ้น 1 VC2: เมื่อส่งข้อความ — แนบเวกเตอร์ทั้งชุดไปด้วย VC3: เมื่อรับข้อความ — ตั้งค่าแต่ละตำแหน่งเป็น max ของสองเวกเตอร์ แล้วเพิ่มตำแหน่งตัวเองอีก 1

เหตุการณ์ a → b (จริง ๆ) ก็ต่อเมื่อทุกตำแหน่งของเวกเตอร์ a ≤ เวกเตอร์ b และมีอย่างน้อยหนึ่งตำแหน่งที่น้อยกว่าจริง — ถ้าเทียบกันแล้วไม่มีทิศทางไหนน้อยกว่าล้วน ๆ แปลว่าสอง event นั้น concurrent จริง ๆ (ไม่ใช่แค่ดูเหมือน concurrent แบบที่ Lamport clock บอกไม่ได้)

ราคาที่ต้องจ่าย
Vector clock แม่นยำกว่า Lamport clock มาก แต่ขนาดข้อมูลที่ต้องแนบไปกับทุกข้อความโตเป็นสัดส่วนกับจำนวน process ในระบบ (O(N)) — ในระบบที่มี node เป็นพัน ๆ ตัว การแนบ vector เต็มไปกับทุกข้อความไม่ practical จึงมักใช้เฉพาะในขอบเขตที่จำกัด (เช่น ระหว่าง replica กลุ่มเล็ก ๆ)

4Global State และ Snapshot Algorithm

ปัญหา Global State
ระบบกระจายไม่มีใครมองเห็น "สถานะรวม" ของทุกเครื่องพร้อมกัน ณ ขณะใดขณะหนึ่งได้โดยตรง เพราะไม่มีนาฬิกากลางที่บอกว่า "เดี๋ยวนี้" ตรงกันทุกเครื่อง — แต่บาง algorithm (เช่น deadlock detection ในบทที่ 5, garbage collection แบบกระจาย) จำเป็นต้องรู้ global state ที่ สอดคล้องกัน (consistent)
Consistent Global State (Consistent Cut)
State รวมที่ถ่ายภาพมาจากแต่ละ process ณ เวลาต่างกันได้ แต่ต้องไม่ขัดแย้งกันเชิงเหตุ-ผล — ถ้า snapshot บันทึกว่า process B ได้รับข้อความจาก A แล้ว snapshot ของ A ก็ต้องแสดงว่าได้ส่งข้อความนั้นไปแล้วเช่นกัน (ห้ามมี "ผลที่ไม่มีเหตุ")

Chandy-Lamport Snapshot Algorithm

1. Process ใดก็ได้เริ่มต้น: บันทึก state ของตัวเอง แล้วส่ง marker message
   ออกไปยังทุก outgoing channel

2. เมื่อ process อื่นได้รับ marker เป็นครั้งแรก:
   - บันทึก state ของตัวเองทันที
   - บันทึกว่า channel ที่ marker มาถึงนั้น "ว่างเปล่า" (ไม่มี message ค้าง)
   - ส่ง marker ต่อไปยังทุก outgoing channel ของตัวเอง

3. เมื่อได้รับ marker ซ้ำ (จาก channel อื่น) หลังจากบันทึก state แล้ว:
   - บันทึก message ทั้งหมดที่มาถึงบน channel นั้นก่อน marker มาถึง
     (คือ message ที่ "ค้างอยู่ระหว่างทาง" ตอนที่ snapshot เริ่ม)

4. เมื่อทุก process บันทึก state และทุก channel บันทึก message ค้างครบแล้ว
   -> รวมกันได้ global snapshot ที่ consistent
ทำไม Algorithm นี้ถึงสง่างาม
Chandy-Lamport ไม่ต้องหยุดระบบ (non-blocking) ไม่ต้องพึ่ง global clock เลย และรับประกันว่า snapshot ที่ได้จะ consistent เสมอ — ใช้แค่กติกาการส่ง/รับ marker message ซึ่งเป็นการประยุกต์ใช้แนวคิด happened-before โดยตรง

5ทันสมัย: จาก Vector Clock สู่ Distributed Tracing และ Hybrid Logical Clock

เทคโนโลยีความสัมพันธ์กับทฤษฎีในบทนี้
Correlation ID (Network Computing หัวข้อที่ 3)เป็นรูปแบบที่เรียบง่ายกว่า Lamport/Vector Clock มาก — ใส่ ID เดียวกันตลอดสายของ request แทนที่จะพยายามเรียงลำดับ event ทั้งระบบ พอเพียงสำหรับการ "ค้นหา log ที่เกี่ยวข้องกัน" แต่ไม่ได้บอก causality ที่ละเอียดเท่า vector clock
Distributed Tracing (Network Computing หัวข้อที่ 4)เก็บ parent-child relationship ระหว่าง span (แต่ละ span คือหนึ่ง operation ในหนึ่ง service) ซึ่งจริง ๆ คือการสร้าง happened-before graph บางส่วนโดยตรง — เพียงแต่ใช้เพื่อ debug/monitor แทนการพิสูจน์ทฤษฎี
Hybrid Logical Clock (HLC)ผสม physical clock (สำหรับให้ค่าใกล้เคียงเวลาจริงที่มนุษย์เข้าใจได้) เข้ากับ logical clock (สำหรับรับประกัน causality ที่ถูกต้อง) — ใช้จริงในฐานข้อมูลกระจายอย่าง CockroachDB และ MongoDB
Google Spanner TrueTimeแนวทางที่ต่างออกไป — ลงทุนฮาร์ดแวร์ (GPS + atomic clock) ในทุก datacenter เพื่อให้ physical clock มีขอบเขตความคลาดเคลื่อนที่รู้แน่ชัด (bounded uncertainty) แทนที่จะหลีกเลี่ยงการพึ่งพา physical clock ไปเลยแบบ Lamport — เป็นการแก้ปัญหาเดิมจากอีกมุมหนึ่งโดยสิ้นเชิง
ข้อสังเกตสำคัญ
ไม่มีระบบยุคปัจจุบันไหน "แก้" ปัญหาการไม่มีนาฬิกากลางได้จริง — ทุกเทคโนโลยีข้างต้นเป็นแค่การเลือก trade-off ที่ต่างกันระหว่างความแม่นยำเชิง causality, ต้นทุนของข้อมูลที่ต้องแนบไปกับทุกข้อความ (overhead), และความใกล้เคียงกับเวลาจริงที่มนุษย์เข้าใจได้ — Lamport เขียนงานนี้ไว้ตั้งแต่ปี 1978 แต่ trade-off พื้นฐานที่เขาชี้ให้เห็นยังคงเป็นแกนกลางของการออกแบบระบบกระจายทุกระบบจนถึงทุกวันนี้
คำถามซ้อมสอบ
  1. อธิบาย happened-before relation พร้อมยกตัวอย่างสถานการณ์ของตัวเองที่แสดง 3 กรณี (process เดียวกัน, ส่ง-รับข้อความ, transitivity)
  2. อธิบายว่าทำไม Lamport(a) < Lamport(b) จึงไม่ได้แปลว่า a happened-before b เสมอไป และ vector clock แก้ข้อจำกัดนี้อย่างไร
  3. อธิบายขั้นตอนของ Chandy-Lamport snapshot algorithm และเหตุผลที่มันรับประกัน consistent global state ได้โดยไม่ต้องหยุดระบบ
  4. เปรียบเทียบแนวทางของ Vector Clock กับ Google Spanner TrueTime ว่าแก้ปัญหา "ไม่มีนาฬิกากลาง" จากคนละมุมกันอย่างไร
  5. อธิบายว่า Correlation ID ที่ใช้ใน microservices จริงเป็นรูปแบบที่ "เรียบง่ายกว่า" Vector Clock อย่างไร และยอมสูญเสียความสามารถอะไรไปเพื่อแลกกับความเรียบง่ายนั้น

6เวลาในระบบกระจายมีอย่างน้อยสามความหมาย

คำว่าเวลาในโปรแกรมมักถูกใช้รวมกัน ทั้งเวลาบนปฏิทิน ลำดับเหตุการณ์ และระยะเวลาที่ใช้ ทั้งสามเกี่ยวข้องกันแต่แทนกันไม่ได้ Wall-clock time ใช้ตอบว่าเกิดเมื่อวันใด Monotonic time ใช้วัดระยะเวลาโดยไม่ควรถอยหลังเมื่อปรับนาฬิกา ส่วน Logical time ใช้อธิบายลำดับ/เหตุและผลโดยไม่พยายามบอกเวลาโลกจริง

ชนิดตอบคำถามตัวอย่าง API/แนวคิดข้อควรระวัง
Wall clockเหตุการณ์เกิดเวลาใดตามปฏิทินUTC timestamp, NTPกระโดด/ถอยได้จาก clock correction
Monotonic clockผ่านไปนานเท่าใดในเครื่องเดียวmonotonic timerเทียบข้ามเครื่องโดยตรงไม่ได้
Logical clockเหตุการณ์ใดอาจมีเหตุเป็นผลต่อกันLamport, vector clockไม่บอกวินาทีจริง
Hybrid clockเก็บความใกล้ physical time พร้อม causal orderHLCยังต้องกำหนด skew/error bound
Metaphor: วันเวลา เลขคิว และเวลาจับการแข่งขัน
วันที่บนเอกสารคือ wall clock เลขคิวบอกลำดับแต่ไม่บอกว่าห่างกันกี่นาที และนาฬิกาจับเวลาบอกระยะเวลาโดยไม่สนใจวันนี้วันที่เท่าใด การใช้ timestamp ตัวเดียวทำหน้าที่ทั้งสามอย่างทำให้ bug แปลก ๆ เช่น timeout ยืดหรือหดเมื่อระบบปรับนาฬิกา

ทำไมควรใช้ UTC แต่ UTC ก็ยังไม่พอ

UTC ลดความสับสน timezone และ daylight saving แต่ไม่ได้ทำให้นาฬิกาทุกเครื่องตรงกัน NTP/PTP ลด offset ภายใต้ข้อจำกัด แต่มี error bound และช่วงปรับเวลา การเก็บ timestamp ควรระบุ timezone/precision และงานด้าน ordering ต้องไม่สมมุติว่า timestamp ต่าง 1 ms แปลว่าเหตุการณ์เกิดตามลำดับนั้นแน่นอน

Leap Second และ Clock Adjustment

นาฬิกาอาจ step กระโดดทันทีหรือ slew ปรับอัตราทีละน้อย ระบบบางแห่งใช้ leap smear กระจายวินาทีเพิ่ม ถ้าเอา wall clock คำนวณ duration อาจได้ค่าติดลบหรือยาวผิด ควรใช้ monotonic clock สำหรับ timeout/latency และ wall clock สำหรับ audit/display พร้อมเก็บ uncertainty เมื่อจำเป็น

7Clock Synchronization: ตรงแค่ไหนจึงเรียกว่าตรง

นาฬิกา hardware มี drift เพราะ oscillator ต่างกัน ถ้าไม่ sync offset จะโตตามเวลา Protocol แลก timestamp เพื่อประมาณ offset แต่ network delay ไป/กลับไม่เท่ากัน ทำให้แยกไม่ได้สมบูรณ์ว่าเวลาต่างเพราะนาฬิกาหรือข้อความช้า

แนวคิด NTP อย่างง่าย
round-trip delay ≈ (t4 − t1) − (t3 − t2)
offset ≈ ((t2 − t1) + (t3 − t4)) / 2
สูตรสมมุติความหน่วงไปและกลับใกล้กัน ความไม่สมมาตรสร้าง error
วิธีบริบทระดับโดยคร่าวข้อจำกัด
NTPเครือข่ายทั่วไป/อินเทอร์เน็ตms ขึ้นกับ networkasymmetric delay และ server hierarchy
PTPLAN/อุตสาหกรรมพร้อม hardware supportµs หรือต่ำกว่าต้องควบคุม network/hardware
GPS/atomic sourceระบบเฉพาะทางแม่นสูงราคา สัญญาณ และ trust/spoofing

External กับ Internal Synchronization

External synchronization ถามว่านาฬิกาแต่ละเครื่องใกล้แหล่ง UTC เท่าใด Internal synchronization ถามว่านาฬิกาในกลุ่มต่างกันเองเท่าใด ระบบบางงานไม่สนใจเวลาจริงแต่ต้องให้สมาชิกใกล้กัน ขณะที่ audit ทางกฎหมายอาจต้อง external accuracy ด้วย

TrueTime และ Interval Time

แทนที่จะอ้างเวลาจุดเดียว ระบบอย่าง Spanner ใช้ช่วง [earliest, latest] ที่มั่นใจว่าเวลาจริงอยู่ภายใน แล้วรอ uncertainty ผ่านก่อนประกาศ commit order บทเรียนไม่ใช่ทุกระบบควรสร้าง atomic clock แต่คือความซื่อสัตย์ต่อ uncertainty: ถ้ารู้เวลาได้เพียงช่วง ควร model เป็นช่วง ไม่แกล้งใช้เลขจุดเดียวแล้วรับประกันเกินหลักฐาน

8Happened-Before: ลำดับที่มาจากข้อมูลไหล

Lamport นิยาม a → b ถ้า a และ b อยู่ process เดียวและ a มาก่อน b, หรือ a เป็น send และ b เป็น receive ของข้อความเดียวกัน, หรือเชื่อมต่อแบบ transitive หากไม่มี a→b หรือ b→a เหตุการณ์ concurrent กัน หมายถึงไม่มี causal evidence ระหว่างกัน ไม่ได้แปลว่าเกิดเวลาเดียวกัน

P1:  a ---- send(m) ---------------- c
                   \
P2:                 receive(m) ---- d

a → send(m) → receive(m) → d

Causality มาจากความเป็นไปได้ที่ข้อมูลจากเหตุการณ์หนึ่งมีอิทธิพลต่ออีกเหตุการณ์ ถ้าสอง process ไม่แลกข้อความ ไม่มีทางที่เหตุการณ์ล่าสุดของฝ่ายหนึ่งจะรู้เหตุการณ์อีกฝ่ายในขณะนั้น ต่อให้ wall timestamp ใกล้กันก็ไม่สร้าง causal relation

Causality ไม่เท่ากับ Business Causation

Happened-before บอก potential information flow ไม่ได้พิสูจน์สาเหตุทางธุรกิจ ถ้า request A มาก่อน B ใน process เดียว เราได้ order แต่ไม่ได้แปลว่า A ทำให้ B เกิด ในทางกลับกัน business relation อาจถูกส่งผ่านช่องทางที่ tracing ไม่เห็น ต้องระวังใช้คำ causal เกินความหมายทางเทคนิค

9Lamport Clock แบบทำทีละเหตุการณ์

  1. แต่ละ process มี counter เริ่ม 0
  2. ก่อน local/send event เพิ่ม counter
  3. แนบ counter กับ message
  4. เมื่อรับ timestamp T ตั้ง clock = max(local,T)+1

กฎทำให้ถ้า a→b แล้ว L(a)<L(b) แต่ทิศกลับไม่จริง: L(a)<L(b) ไม่พิสูจน์ a→b เหตุการณ์ concurrent อาจได้เลขเรียงกันเพราะ counter คนละ process การใช้ Lamport timestamp ร่วม process ID สร้าง total order ได้เพื่อ deterministic tie-break แต่ total order ที่สร้างเพิ่มไม่ใช่ causal fact ทั้งหมด

สิ่งที่ Lamport clock ให้สิ่งที่ไม่ให้
รักษา happened-before directionตรวจ concurrency จากเลขสองตัวไม่ได้
สร้าง consistent total order เมื่อ tie-breakไม่บอกเวลาจริงหรือระยะเวลา
ใช้ mutual exclusion/event orderingไม่รู้ว่ามี process ใดเห็น event แล้วบ้าง

Lamport Mutual Exclusion

Process multicast request พร้อม timestamp ทุกคนจัด queue ตาม (timestamp, process ID) และตอบ acknowledgment ผู้ขอเข้า critical section เมื่อ request ตนอยู่หัว queue และได้รับ reply ครบ วิธีนี้แสดงว่า logical order ใช้สร้าง mutual exclusion ได้ แต่มี message cost และสมาชิกใดล้มอาจ block หากไม่มี membership/failure handling

10Vector Clock: เก็บว่าแต่ละ Process รู้ถึงไหน

Vector clock มีหนึ่ง component ต่อ process Local event เพิ่มช่องตน Send แนบ vector Receive ทำ component-wise max แล้วเพิ่มช่องตน ถ้า V(a)<V(b) ทุก component ≤ และอย่างน้อยหนึ่ง < จึงสรุป a→b หาก vector เปรียบเทียบไม่ได้ เหตุการณ์ concurrent

P1 vector [2,0,0] ส่ง m
P2 ก่อนรับ [0,3,0]
P2 รับ: max([0,3,0],[2,0,0]) = [2,3,0], แล้วเพิ่ม → [2,4,0]
ความสัมพันธ์เงื่อนไขความหมาย
V(a) < V(b)ทุกช่องไม่เกิน และมีช่องน้อยกว่าa happened-before b
V(a) || V(b)บางช่องมาก บางช่องน้อยconcurrent
เท่ากันทุก component เท่ากันknowledge frontier เดียวกันใน model

ต้นทุนเมื่อ Membership ใหญ่/เปลี่ยน

Vector ยาวตามจำนวน process ถ้าสมาชิกนับล้านหรือ churn สูง metadata แพง จึงมี version vector ต่อ replica, dotted version vector, interval tree clock หรือ tracking เฉพาะ actor สำคัญ ระบบจริงอาจยอม causal information บางส่วนเพื่อขนาดเล็กลง

Conflict ใน Dynamo-style Store

ถ้า version vector สองค่า concurrent ระบบรู้ว่าไม่มีอันใดสืบทอดอีกอัน จึงเก็บ siblings แล้ว merge ด้วย application เช่น shopping cart union การใช้ last-write-wins จาก wall clock ง่ายกว่าแต่เสี่ยงทิ้ง update จาก clock skew ส่วน CRDT ออกแบบ operation/state ให้ merge ตามคณิตศาสตร์โดยไม่ต้องเลือกผู้ชนะ แต่จำกัดชนิด semantics

11Total Order, Causal Order และ Delivery Order

ระบบอาจต้องการ ordering ต่างระดับ Chat comment/reply ต้องให้ reply ไม่มาก่อนต้นเหตุ (causal) แต่ comment อิสระสองรายการไม่จำเป็นต้องเรียงเหมือนกันทั่วโลก Replicated state machine ต้อง total order ของ command เพื่อ replica ให้ state เหมือนกัน การใช้ guarantee เข้มเกินงานเพิ่ม coordination โดยไม่จำเป็น

Orderรับประกันต้นทุน/ข้อใช้
Per-sender FIFOข้อความจากผู้ส่งเดียวไม่สลับง่ายแต่หลาย sender ยังต่างกัน
Causalเหตุและผลถึงตามลำดับmetadata/dependency tracking
Totalทุกสมาชิกเห็นลำดับเดียวsequencer/consensus และ latency
Real-time/linearizableoperation หลังอีกอันจบต้องอยู่หลังต้อง coordination/clock assumption เพิ่ม

12Global State: ภาพรวมที่ถ่ายพร้อมกันไม่ได้

Global state ประกอบด้วย local state ของทุก process และ state ของ channel (ข้อความที่ส่งแล้วแต่ยังไม่รับ) การอ่านทุก process ทีละตัวอาจได้ inconsistent cut เช่นบันทึกฝั่งรับหลังได้เงิน แต่บันทึกฝั่งส่งก่อนหักเงิน ทำให้ยอดรวมเหมือนเงินเกิดขึ้น หรือกลับกันหายไป

Metaphor: ถ่ายภาพขบวนรถจากกล้องหลายตัว
ถ้ากล้องแต่ละจุดถ่ายคนละเวลา นำภาพมาต่อกันอาจเห็นรถคันเดียวอยู่สองที่หรือหายไป ไม่มีปุ่มหยุดถนนทั้งสาย Distributed snapshot สร้างชุดภาพที่สอดคล้องกับการเคลื่อนผ่านของรถ โดยบันทึกรถที่ออกจากกล้องหนึ่งแต่ยังไม่ถึงอีกกล้องเป็น “state ในช่องทาง”

Consistent Cut

Cut สอดคล้องถ้ารวม event e แล้วต้องรวม causal predecessor ของ e ทั้งหมด ห้ามมี receive โดยไม่มี send อยู่ในอดีตของ snapshot แต่มี send ที่ receive ยังไม่เกิดได้ ซึ่งข้อความนั้นอยู่ใน channel state

13Chandy–Lamport Snapshot แบบเข้าใจ Marker

สมมุติ reliable FIFO channel Process เริ่ม snapshot โดยบันทึก local state แล้วส่ง marker ทุก outgoing channel เมื่อ process ได้ marker แรก บันทึก local state ส่ง marker ต่อ และถือข้อความที่มาถึง channel อื่นตั้งแต่บันทึก stateจนพบ marker ของ channel นั้นเป็น channel state

  1. Initiator บันทึก local state
  2. ส่ง marker ก่อนข้อความปกติถัดไปทุก outgoing channel
  3. ผู้รับ marker แรกบันทึก local state และ channel ที่ marker มาถึงเป็นว่าง
  4. บันทึกข้อความบน channel อื่นจน marker ของ channel นั้นมาถึง
  5. รวม local + channel state เป็น snapshot

FIFO สำคัญเพราะ marker แยกข้อความก่อน/หลัง snapshot บน channel หาก channel ไม่ FIFO ต้องเพิ่ม sequence/color หรือ algorithm อื่น Snapshot ไม่หยุด application และไม่ได้เป็น state ณ wall-clock เดียว แต่มันเป็น consistent global state ที่อาจเกิดขึ้นได้ตาม execution

Snapshot ใช้ทำอะไร

งานสิ่งที่ snapshot ช่วย
Checkpointrestart จาก state ที่สอดคล้อง ไม่สร้าง orphan message
Deadlock detectionดู wait-for relation ระดับระบบ
Termination detectionทุก process idle และไม่มี message in transit
Invariant/debugตรวจ property ของ global state
Stream processingconsistent checkpoint ของ operator/channel

14Distributed Tracing: เวลาเพื่ออธิบาย Request หนึ่งสาย

Tracing สร้าง trace ID และ span ID ต่อ operation บันทึก parent/child, start/end, attribute และ status ทำให้ตาม request ข้าม service ได้ มันตอบว่าเส้นทางและ latency อยู่ที่ไหน แต่ timestamp skew ทำให้ span จากคนละเครื่องดูซ้อนหรือกลับลำดับ จึงควรใช้ causal parent relation และ monotonic duration ร่วม ไม่ดู timeline ด้วยตาอย่างเดียว

ข้อมูลตอบอะไรข้อจำกัด
Trace/span IDsoperation ใดเป็นเรื่องเดียวกันcontext อาจขาดที่ queue/async boundary
Parent/linkcausal/fan-out relationbatch มีหลาย parent ต้องใช้ links
Timestamp/durationใช้เวลาที่จุดใดclock skew และ sampling
Attributes/eventsendpoint, retry, state สำคัญprivacy/cardinality และ overhead

Async Messaging กับ Trace Context

Producer span จบก่อน consumer เริ่มนานมาก การใช้ parent-child อาจทำให้ trace ยาวและ ownership สับสน OpenTelemetry ใช้ span links เชื่อม event จาก producer กับ consumer โดยไม่แกล้งว่าเป็น call stack เดียว Message ต้องส่ง trace context แต่ต้องกำหนด policy เมื่อ replay event เก่าหรือ fan-in หลาย message

15Hybrid Logical Clock และฐานข้อมูลกระจาย

HLC เก็บ physical component ร่วม logical counter หาก wall time เดินหน้าใช้ค่าใหม่ หากรับ timestamp มากกว่าหรือเวลาไม่เดิน counter ช่วยรักษา causality จึงมี timestamp ใกล้เวลาโลกจริงและไม่ถอยตาม causal order เหมาะกับ version/order ใน distributed database บางชนิด

HLC ไม่ทำ clock sync หายไป Physical component ยังมี skew และงานที่ต้อง external time accuracy ต้องใช้กลไกอื่น แต่ช่วยลด metadata เทียบ vector clock และให้ sort/debug ใกล้เวลาจริงกว่า Lamport ล้วน แลกกับตรวจ concurrency ไม่สมบูรณ์แบบ vector

16เวลาที่เกี่ยวกับ Lease, Lock และ Expiry

Lease ให้สิทธิ์ช่วงเวลาจำกัด ใช้ leader, cache validity หรือ resource ownership แต่ถ้าผู้ถือกับผู้ให้เช่าเข้าใจเวลาต่างกัน อาจมีผู้ถือสองคน ต้องมี clock bound หรือ fencing token ที่เพิ่มทุก lease ผู้รับ resource ปฏิเสธ token เก่าแม้ process เก่ายังคิดว่า lease ไม่หมด

Lease #41 → fencing token 41
Lease #42 → fencing token 42
Storage accepts write only if token >= last_seen

TTL expiry ก็ไม่ควรใช้ลบ business fact โดยไม่คิด เช่น session หมดอายุใช้ได้ แต่ order ไม่ควรหายเพราะนาฬิกากระโดด งาน scheduler ต้องออกแบบ duplicate/missed execution เมื่อ leader failover และ clock skew

17ข้อผิดพลาดเรื่องเวลาที่พบในระบบจริง

18Workshop: สร้าง Timeline ที่โกหก แล้วแก้ด้วย Causality

  1. รัน process สามตัว แต่ละตัวมี clock offset ต่างกันและแลก message
  2. เก็บ wall timestamp แล้วเรียง log แสดงลำดับที่ผิด causal relation
  3. เพิ่ม Lamport clock ตรวจว่า send<receive เสมอ
  4. เพิ่ม vector clock สร้างเหตุการณ์ concurrent แล้วพิสูจน์ว่าเปรียบเทียบไม่ได้
  5. จำลอง request fan-out/fan-in สร้าง trace spans และ links
  6. ทำ snapshot algorithm บน channel FIFO บันทึก message in transit
  7. เปลี่ยน channel ให้ reorder แล้วอธิบาย assumption ที่พัง
  8. ใช้ monotonic กับ wall clock วัด duration เปรียบเทียบเมื่อปรับเวลา
รายงานต้องแยก
physical timestamp, logical order, causal relation และ duration ออกจากกัน พร้อมระบุว่าแต่ละข้อสรุปมาจากหลักฐานใด ห้ามใช้คำว่า “เกิดก่อน” โดยไม่บอกว่าหมายถึง wall time, happened-before หรือ total order ที่ระบบกำหนด

19ทบทวนแกนสำคัญก่อนกรณีศึกษา

ไม่มีนาฬิกากลางไม่ได้หมายความว่าเราใช้เวลาไม่ได้ แต่ต้องเลือกเวลาให้ตรงคำถาม Wall clock ใช้ปฏิทิน Monotonic ใช้วัดระยะ Logical clock ใช้ ordering/causality และ hybrid clock ประนีประนอมบางด้าน การ sync ลด error แต่ไม่ทำให้ timestamp เป็นความจริงสมบูรณ์

Lamport clock รักษาทิศ happened-before แต่ตรวจ concurrency ไม่ได้ Vector clock ตรวจ causality ได้ละเอียดขึ้นแต่ metadata โต Global snapshot ไม่หยุดเวลาทั้งระบบ แต่สร้าง consistent cut ที่รวม message in transit ขณะที่ tracing เป็นการประยุกต์ context/causal structureเพื่อ debug request จริง

ขั้นตอนถัดไปคือ Distributed File Systems ซึ่งต้องใช้ naming, caching, replication และเวลา/version ร่วมกัน เมื่อ client หลายเครื่องเปิดชื่อไฟล์เดียว เราต้องกำหนดว่าเห็นข้อมูลเมื่อใด cache เก่าได้นานเท่าใด และ server fail/restart แล้ว file handle กับ write จะมีความหมายอย่างไร

20กรณีศึกษา: เรียง Log ของเหตุขัดข้องข้าม Service

สมมุติ Gateway เวลาเร็วจริง 800 ms, Order ตรง และ Payment ช้า 500 ms ผู้ใช้ส่ง request ผ่าน Gateway→Order→Payment แล้ว Payment timeout การเรียง log ตาม timestamp อาจแสดง Payment เริ่มก่อน Gateway รับ ทั้งที่เป็นไปไม่ได้จาก message flow หากทีมเชื่อ timestamp อย่างเดียวจะสร้าง root cause timeline ผิด

หลักฐานใช้จัดลำดับอย่างไรความเชื่อมั่น
Trace parent/childchild context มาจาก parent จึงมี causal relationสูงเมื่อ context ไม่ขาด
Send/receive log + request IDsend เกิดก่อน receive ของ messageสูงถ้า ID จับคู่ถูก
Local monotonic sequenceevent ใน process เดียวตามลำดับสูงภายใน process incarnation
Wall timestampประมาณเวลาโลกจริงขึ้นกับ sync/uncertainty
User reportขอบเขตโดยคร่าวมี delay/ความจำ

Incident timeline ควรแยก observed timestamp, causal order และ inference เช่น “Payment span เป็นลูก Order จึงเกิดหลัง Order ส่ง call; timestamp ที่ดูย้อนเป็น clock offset” ไม่ควรแก้ timestamp ใน log ให้สวยโดยไม่เก็บ raw value และ correction method

Clock Offset Estimation จาก Trace

เราประมาณ offset บางส่วนจาก constraint ว่า client send ≤ server receive ≤ server send ≤ client receive แต่ network delay ไม่รู้แน่ จึงได้ช่วงความเป็นไปได้มากกว่าค่าจุดเดียว Tool อาจปรับ visualization แต่ไม่ควรใช้ผลประมาณเป็นหลักฐานทางบัญชีโดยไม่มี clock service ที่รับประกัน

21กรณีศึกษา: Shopping Cart ที่แก้แบบ Offline

โทรศัพท์ A และ B แก้ cart เดียวกันขณะ offline A เพิ่มหนังสือ B เพิ่มปากกา เมื่อ sync ทั้งสอง update มี vector clock concurrent ถ้าใช้ last-write-wins จะทิ้งรายการหนึ่งตาม timestamp หาก cart semantics เป็น set/multiset เรา merge การเพิ่มได้ แต่ remove กับ add item เดียวกันต้องกำหนด policy เช่น observed-remove set

Conflictนโยบายที่เป็นไปได้ผลทางธุรกิจ
Add คนละ itemunionรักษาทั้งสองเจตนา
Add กับ remove item เดียวadd-wins/remove-wins ตาม typeต้องเลือกว่าพลาดซื้อหรือพลาดลบอันตรายกว่า
เปลี่ยน quantity พร้อมกันcounter CRDT หรือ manual ruleค่าบวก/ตั้งค่าใหม่ semantics ต่าง
Checkout กับ editstate/version boundaryห้าม merge เข้า order ที่ commit แล้วเงียบ ๆ

Vector clock ตรวจว่า update concurrent แต่ไม่ได้บอกวิธี merge การแก้ conflict เป็น business semantics CRDT ช่วยเมื่อ operation มี algebra ที่ merge ได้ แต่ payment/order invariant ยังต้อง coordination บางจุด

22กรณีศึกษา: Leader Lease และ Process ที่ฟื้นจาก Pause

Leader A ได้ lease ถึงเวลา T แล้วถูก GC pause ขณะเดียวกัน lease หมดและ B ได้ lease ใหม่ A กลับมาทำงานโดย local clock/ความเชื่อเดิมและเขียน storage หาก storageรับทั้งคู่เกิด split-brain Fencing token แก้โดย B ได้ token 42 หลัง A token 41 Storage ปฏิเสธ write 41 แม้ A ยังมีชีวิต

บทเรียนคือการหมดเวลาเปลี่ยนสิทธิ์ในระบบหนึ่ง แต่ไม่ได้หยุด process เก่าทางกายภาพ ต้องมี downstream enforcement ไม่ใช่หวังว่า old leaderจะรับ cancellation ทัน เวลาและ ordering จึงเชื่อมกับ authorization ต่อ resource

23Snapshot ใน Stream Processing

Pipeline มี source, operator state และ channel records ถ้า checkpoint operator แต่ไม่ประสาน offset/message in transit หลัง restart อาจทำข้อมูลหายหรือซ้ำ Barrier snapshot คล้าย marker ไหลตาม stream Operator บันทึก state เมื่อ barrier ครบ input และจัดการ record ระหว่าง barrier ตาม aligned/unaligned checkpoint

แบบพฤติกรรมข้อแลกเปลี่ยน
Alignedหยุด input ที่ barrier ถึง รอ input อื่นstate เล็กกว่าแต่ backpressure ทำ checkpoint ช้า
Unalignedรวม in-flight buffer ใน checkpointcheckpoint เร็วช่วง backpressureแต่ใหญ่

Exactly-once state ใน engine ยังไม่แปลว่า external sink effect exactly-once ถ้าเขียน database/API ต้องใช้ transactional sink, idempotency หรือ 2PC/outbox ตามขอบเขต นี่เชื่อมบท Time/Global State กลับ Distributed Transactions โดยตรง

24เวลาใน Database: MVCC, Commit Timestamp และ Snapshot

MVCC ใช้ transaction ID/timestamp เลือก version ที่มองเห็น Snapshot timestamp ไม่จำเป็นต้องเป็น wall time และ commit order อาจต่างจาก start order ฐานข้อมูลกระจายต้องกำหนด timestamp oracle, HLC หรือ consensus order เพื่อให้ replica/shard ตีความเหมือนกัน

Guaranteeความสัมพันธ์เวลา
Snapshot Isolationอ่านภาพ ณ logical snapshot; concurrent write conflict บางชนิด
Serializabilityมี serial order ที่ผลเทียบเท่า
Strict Serializabilityserial order เคารพ real-time completion
External Consistencycommit timestamp/order สอดคล้อง observation ภายนอกตาม contract

คำว่า “ล่าสุด” ต้องถามว่าล่าสุดตาม replica, commit order, wall time หรือ session ของ client Read-your-writes อาจพอสำหรับ user profile แม้ไม่ linearizable ทั่วโลก การรับประกันให้เข้มสุดทุก read เพิ่ม latency/availability cost

25Bounded Staleness และเวลาใน Consistency Model

ระบบอาจรับประกัน replica ตามหลังไม่เกิน K version หรือ Δ เวลา แต่ guarantee ต้องมี mechanism วัด/บังคับ ถ้า clock uncertaintyสูง “ไม่เกิน 5 วินาที” ต้องนิยามจาก commit timestamp/replication watermark ไม่ใช่เวลาเครื่องอ่านอย่างเดียว

Client ที่ต้องข้อมูลสดอาจรอ safe time/watermark ส่วนงาน analytics ยอม stale เพื่ออ่าน replica ใกล้ การเปิด consistency เป็น option ให้ clientช่วย trade-off แต่ API ต้องอธิบายผล ไม่ใช่ใช้ชื่อ eventual/strong กว้าง ๆ

26Time-based ID: สะดวกแต่มีสมมติฐาน

Snowflake-style ID รวม timestamp, worker ID และ sequence เพื่อ sortable/unique โดยไม่ใช้ coordinatorทุกครั้ง แต่ต้องจัด worker ID, รับมือ clock rollback และ sequence overflow หากนาฬิกาถอย generator อาจรอ ใช้ logical bump หรือ fail ไม่ควรสร้าง ID ซ้ำ

คุณสมบัติประโยชน์ข้อควรระวัง
Time sortableindex locality/ประมาณเวลาไม่ใช่ causal/commit order สมบูรณ์
Decentralizedสร้างที่หลาย workerworker ID uniqueness และ lifecycle
Timestamp embeddeddebug/partitionprivacy และ clock rollback

27แบบฝึกคำนวณ Logical Clock

กำหนด P1, P2, P3 มีเหตุการณ์ local และ message ต่อไปนี้ ให้นักศึกษาคำนวณ Lamport/vector clock ทุกจุด แล้วตอบว่าเหตุการณ์คู่ใด concurrent

P1: a --send m1---------------- d --recv m3
           \                         /
P2:         recv m1--b--send m2----/ 
                         \
P3:        c-------------recv m2--send m3
  1. เริ่ม vector [0,0,0] เพิ่มช่องตนทุก event
  2. คำนวณ timestamp ของ a,b,c,d และ send/receive
  3. ตรวจ a กับ c, b กับ c, d กับ receive m2
  4. สร้าง Lamport total order ด้วย process ID แล้วระบุคู่ที่ order นี้สร้างเพิ่ม
  5. ถ้า m2 มาถึงช้าหลัง local event เพิ่มหนึ่งจุด vector เปลี่ยนอย่างไร

28Checklist การใช้เวลาในระบบจริง

29คำถามทบทวนเชิงเหตุผล

  1. เหตุใด clock ที่ตรงระดับ millisecond ยังพิสูจน์ causal order ของ event ห่าง 2 ms ไม่ได้เสมอ
  2. Lamport clock ให้ implication ทิศใด และเหตุใด converse ไม่จริง
  3. Vector clock บอก conflict ได้ แต่เหตุใดแก้ conflict แทน business logic ไม่ได้
  4. Snapshot ที่ไม่ได้ถ่าย wall time เดียวกันยังถือว่าสอดคล้องได้อย่างไร
  5. Marker ใน Chandy–Lamport ใช้ FIFO assumption ตรงไหน
  6. Tracing timeline ผิดจาก skew ได้ แต่ parent relation ยังช่วยอะไร
  7. Lease หมดแล้วเหตุใด process เก่ายังอันตราย และ fencing แก้อย่างไร
  8. HLC แลกข้อดี/ข้อจำกัดอะไรเทียบ vector clock
  9. event time กับ processing time ต่างกันอย่างไรเมื่อข้อมูลมาช้า
  10. strict serializability เพิ่มเงื่อนไขใดเหนือ serializability

30Event Time, Processing Time และ Watermark

ใน stream system เหตุการณ์อาจเกิดที่อุปกรณ์เวลา 10:00 เดินทางออฟไลน์แล้วถึงระบบ 10:30 Event time คือเวลาที่เหตุการณ์เกิดตาม domain Ingestion time คือเวลาเข้าระบบ และ Processing time คือเวลาที่ operator ประมวลผล ถ้า aggregate หน้าต่างตาม processing time ข้อมูลช้าจะไปอยู่คนละช่วงกับเหตุการณ์จริง

Watermark เป็นข้อสันนิษฐานว่าระบบไม่น่าจะได้รับ event time ต่ำกว่าค่านี้อีก ช่วยปิด window แต่ไม่ใช่ความจริงสมบูรณ์ Late event ยังมาได้ ต้องมี allowed lateness และ policy: update result, ส่ง correction, side output หรือทิ้งพร้อม metric

แนวคิดใช้ตอบความเสี่ยง
Event timeโลกธุรกิจเกิดเมื่อใดsource clock ผิด/ไม่น่าเชื่อถือ
Processing timeระบบเห็น/ทำงานเมื่อใดผลเปลี่ยนตาม load/replay
Watermarkปิด window เมื่อใดเร็วเกินทำ late มาก ช้าเกิน result latency สูง
Allowed latenessแก้ผลย้อนหลังนานเท่าใดstate retention/correction complexity

31Causal Consistency ใน Application

ผู้ใช้โพสต์ข้อความแล้วเปิดหน้าใหม่ควรเห็นโพสต์ตน (read-your-writes) ผู้ใช้อ่านโพสต์แล้วตอบ reply คนอื่นควรไม่เห็น reply ก่อนต้นเรื่อง (writes-follow-reads/causal) Guarantee แบบ session/causal อาจให้ประสบการณ์สมเหตุผลโดยไม่ต้อง linearizable ทุก operation ทั่วโลก

Session guaranteeความหมาย
Read-your-writesหลังเขียน session เดิมไม่ย้อนเห็นรุ่นก่อน
Monotonic readsการอ่านถัดไปไม่ถอยไป version เก่ากว่าที่เคยเห็น
Monotonic writeswrite จาก session ถูกนำไปใช้ตามลำดับ
Writes-follow-readswrite ที่เกิดหลังอ่านถูกวางหลัง version ที่อ่าน

ระบบทำได้ด้วย session token/version vector/sticky region หรือรอ replica catch up การ route ไป replica ใกล้ที่สุดอย่างเดียวอาจละเมิด monotonic read หาก replica ใหม่ตามหลัง

32Global Predicate และ Stable Property

บาง property เป็น stable: เมื่อจริงแล้วจะจริงต่อ เช่น computation terminated ใน model ที่ไม่มีงานใหม่ บาง property transient เช่น token อยู่ที่ process ใด Snapshot/detection algorithm ต้องรู้ชนิด property เพราะ snapshot หนึ่งไม่พบ transient state ไม่ได้พิสูจน์ว่าไม่เคยเกิด

Distributed deadlock detection ต้องรวม wait relation และ message in transit หาก snapshot ไม่ consistent อาจเห็นวงจรปลอมหรือพลาดวงจรจริง การตรวจ invariant ระดับระบบจึงพึ่ง global state construction ไม่ใช่ query dashboard ณ timestamp ใกล้กันอย่างเดียว

33คำศัพท์และประโยคที่ควรใช้ให้แม่น

คำความหมาย
Concurrent eventsไม่มี happened-before ทั้งสองทิศ ไม่ได้แปลว่า timestamp เท่ากัน
Clock skewความต่างของนาฬิกาสองเรือน ณ เวลาใด
Clock driftอัตราที่นาฬิกาเดินต่างจาก reference/กันเอง
Consistent cutถ้ารวม event ต้องรวม causal past ของมัน
Channel statemessage ส่งแล้วแต่ยังไม่รับ ณ snapshot
Total orderทุกคู่เปรียบเทียบได้ อาจเป็น order ที่สร้างเพิ่ม ไม่ใช่ causality
Uncertainty intervalช่วงที่เวลาแท้จริงน่าจะอยู่ แทนความมั่นใจเกินจริงของเลขจุดเดียว

สถานการณ์สรุป

ระบบขายบัตรมี event Reserve, Pay และ Confirm ข้ามสาม service ถ้า Confirm มี wall timestamp ก่อน Pay เพราะ skew แต่ trace แสดง Confirm ได้ context หลัง Pay เราควรรักษา causal order ไม่แก้ business stateตาม timestamp หากสอง Reserve ของที่นั่งเดียว concurrent vector clock ช่วยบอก conflict แต่การเลือกผู้ได้ที่นั่งยังต้อง serializable/consensus policy ไม่ใช่ clock merge อย่างเดียว

นี่คือขอบเขตสำคัญของบท: เวลาและ causality ช่วยอธิบาย/จัดลำดับข้อมูล แต่ไม่ได้แทน concurrency control หรือ agreement เมื่อ invariant ต้องมีผู้ชนะเพียงคนเดียว

34Design Review: ทุกครั้งที่เห็น Timestamp ให้ถามหน้าที่ของมัน

Timestamp field หนึ่งอาจถูกใช้แสดงเวลา เรียงข้อมูล หมดอายุ เลือกผู้ชนะ และสร้าง ID พร้อมกัน ซึ่งแต่ละหน้าที่มี requirement ต่างกัน Review ควรทำ inventory ว่า field มาจาก clock ใคร เชื่อถือได้แค่ไหน ถอยได้หรือไม่ และอะไรเกิดเมื่อสองค่าเท่ากัน

ใช้เพื่อสิ่งที่ควรใช้/กำหนดกับดัก
แสดงผู้ใช้UTC storage + timezone presentationDST/local ambiguity
วัด latencymonotonic duration ต่อ process/spanลบ wall clock ข้ามเครื่อง
เรียง causal eventlogical/trace relationwall clock skew
หมดอายุ tokentrusted time + skew allowanceclient clock เป็น authority
เลือก versioncommit/logical order ตาม consistencylast-write-wins ทำ update หาย
สร้าง unique IDworker+sequence+rollback policytimestamp ล้วนชน/ถอย

ระบบต้องมี behavior เมื่อ time service เสื่อม เช่นหยุดออก lease ใหม่ ลด guarantee หรือใช้ logical counterต่อ ไม่ควรปล่อยให้นาฬิกาผิดแล้วสร้างผลเงียบ ๆ Alert clock offset เป็นเพียงจุดเริ่ม ต้องรู้ว่า component ใดพึ่ง bound และผลกระทบต่อ safety หรือเพียงความสวยของ log

สำหรับ snapshot/tracing ให้เก็บ causal metadata เป็น first-class ไม่หวังแก้ทุกอย่างภายหลังด้วยการ sync clock ที่แม่นขึ้น เพราะแม้นาฬิกาตรง การเห็น event A ก่อน B ทางเวลาก็ยังไม่พิสูจน์ว่า A ส่งผลต่อ B หากไม่มีช่องข้อมูลเชื่อมกัน

เกณฑ์ว่าการใช้เวลาปลอดภัยหรือยัง

ต้องทดสอบ clock ถอย กระโดด และ skew เกิน bound พร้อมตรวจ component ที่ใช้ lease, token expiry, scheduler, ID และ ordering แยกกัน การแก้ log ให้เรียงสวยไม่เท่ากับแก้ algorithm ที่พึ่งเวลาผิด ต้องมี fallback เมื่อ time source unhealthy และ alert ที่บอกผลกระทบต่อ guarantee

Trace/query tooling ควรค้นด้วย ID และ causal relationได้แม้ timestamp คลาด ถ้าการสืบ incident ทำได้เพียงเรียงข้อความทั้งหมดตาม wall time ระบบยังขาดข้อมูลสำคัญ Message/event ต้องพา context ข้าม asynchronous boundary และบันทึก process incarnation เพื่อไม่ให้ sequence หลัง restartปนกับก่อน restart

เมื่อออกแบบ global snapshot ให้เขียน channel assumption, membership และสิ่งที่เกิดกับ message ระหว่าง checkpoint ชัด หากเปลี่ยนจาก FIFO เป็น broker partition/retry semantics ต้องทบทวน algorithm ไม่ถือว่าชื่อ queue เหมือนกันแล้ว assumption เหมือนเดิม

ท้ายที่สุด ความแม่นของนาฬิกาไม่ควรถูกใช้แทนความชัดของ semantics หากงานต้องมีผู้ชนะหนึ่งคนให้ใช้ coordination หากต้องรักษาเหตุและผลให้ส่ง causal metadata และหากเพียงวัดเวลาให้ใช้ monotonic clock เครื่องมือแต่ละชนิดตอบคำถามต่างกัน การเลือกให้ตรงคำถามช่วยลดทั้ง bug และการรับประกันเกินจริง

ในรายงานการทดลองควรระบุ clock source, offset ที่สังเกต, logical timestamp และ message relation แยกกัน เมื่อค่าขัดแย้งให้ถือ causal evidence สำหรับ ordering ที่เกี่ยวกับ execution และเก็บ wall timeไว้เป็นข้อมูลประมาณโลกจริง วิธีนี้ไม่ทำให้เวลาสมบูรณ์ แต่ทำให้ข้อสรุปซื่อสัตย์ต่อสิ่งที่ระบบรู้ได้

35สรุปและขั้นตอนถัดไป

เวลาในระบบกระจายต้องแยก wall clock, monotonic duration และ logical order ออกจากกัน Clock synchronization ลด offset แต่ไม่ลบ uncertainty Lamport clock รักษาทิศ happened-before ส่วน vector clock ตรวจ concurrency ได้ด้วยต้นทุน metadata ที่สูงขึ้น

Global snapshot ไม่ได้หยุดทุกเครื่องในขณะเดียวกัน แต่เลือก consistent cut ที่รวม causal past และ message in transit Distributed tracing นำแนวคิด context/causalityมาใช้ติดตาม request จริง ขณะที่ lease, fencing และ database timestamp แสดงว่าเวลาเชื่อมกับสิทธิ์และ consistency โดยตรง

ขั้นตอนถัดไปคือ Distributed File Systems ซึ่งต้องใช้ naming เพื่อหาไฟล์ ใช้เวลา/version เพื่อจัดการ cache และใช้ snapshot/replication เพื่อกู้ข้อมูล เมื่อหลาย client อ่านเขียน object เดียวกัน คำถามสำคัญจะเปลี่ยนจาก “เหตุการณ์ใดเกิดก่อน” เป็น “write ใดมองเห็นและ durable เมื่อใด”