การเขียนข้ามหลายภูมิภาค: commit ลงเอยที่ใดจริง ๆ
การกำหนดเส้นทางพาคำขอไปยังภูมิภาคหนึ่ง มีเพียงขอบเขตของทรานแซกชันที่ทำให้การเขียนเป็นอะตอม ตั้งชื่อค่าคงที่ เลือกเจ้าของ แล้วออกแบบการลองใหม่รอบ ๆ สิ่งนั้น
เซิร์ฟเวอร์แอปพลิเคชันสองเครื่องในสองภูมิภาค ไคลเอนต์หนึ่งรายที่เขียนผ่าน VPN และคำถามที่ไม่มีใครจดไว้: องค์ประกอบใดตัดสินว่าการเขียนเกิดขึ้นแล้ว การกำหนดเส้นทางพาคำขอไปถึงโปรเซส ส่วนขอบเขตของทรานแซกชันตัดสินว่าเมื่อใดการเปลี่ยนแปลงจึงจะคงทนและมองเห็นได้ สิ่งเหล่านี้คืองานต่างกันที่ระบบต่างกันทำ และช่องว่างระหว่างสองสิ่งนี้คือที่อยู่ของบั๊กการเขียนข้ามภูมิภาคส่วนใหญ่
เริ่มจากกฎทางธุรกิจ ไม่ใช่แผนที่
เริ่มด้วยประโยคเกี่ยวกับกฎทางธุรกิจ ไม่ใช่ภูมิศาสตร์: การอ่านและการเขียนใดต้องสำเร็จไปด้วยกัน และการเปลี่ยนแปลงพร้อมกันใดต้องเป็นไปไม่ได้ในระหว่างนั้น สำหรับการจองสินค้าคงคลัง นั่นหมายความว่าการตรวจสอบสต็อกและการจองต้องมีผลทั้งคู่หรือไม่มีเลย และคำสั่งซื้อที่สองต้องใช้หน่วยเดียวกันนั้นไม่ได้ในระหว่างนั้น
| Requirement | What satisfies it | What does not |
|---|---|---|
| All-or-nothing application | A transaction inside one owning system | A VPN path between regions |
| No double spend | Isolation strong enough to exclude the conflict | Atomicity alone |
| Survive a region loss | Replication the database itself documents | Two independent databases behind one client |
แถวกลางนั้นเองที่ทีมมักข้ามไป ความเป็นอะตอมโดยไม่มีการแยกที่เพียงพอทำให้ทรานแซกชันสองรายยืนยันถูกต้องได้ทั้งคู่และยังสร้างสภาวะที่ธุรกิจถือว่าเป็นไปไม่ได้ และตรรกะการลองใหม่ไม่ว่าจะมากเพียงใดก็ซ่อมไม่ได้ในภายหลัง
ขอบเขตอำนาจหนึ่งขอบเขตชนะเซิร์ฟเวอร์ภูมิภาคสองเครื่อง
เซิร์ฟเวอร์แอปพลิเคชันระดับภูมิภาคอยู่ที่เดิมได้ ตราบใดที่ส่งปฏิบัติการไปยังบริการที่ทำภายในขอบเขตทรานแซกชันที่รองรับเพียงหนึ่งเดียว ชั้นแอปพลิเคชันกลายเป็นตัวกำหนดเส้นทางของเจตนา ชั้นข้อมูลเป็นเจ้าของความจริง
ทำให้ขอบเขตนั้นสั้นและใกล้กับข้อมูลที่มันแตะ เมื่อมนุษย์กำลังตอบพรอมป์ต์ หรือเมื่อการเรียกข้ามสองภูมิภาค ทรานแซกชันที่เปิดค้างไว้จะใช้เวลาไปกับการถือล็อกและเพิ่มโอกาสที่สิ่งอื่นจะหมดเวลาตามหลัง ความล้มเหลวนั้นดูเหมือนปัญหาฐานข้อมูล แต่จริง ๆ แล้วเป็นปัญหาการออกแบบที่แต่งตัวเป็นเช่นนั้น การย้ายการตัดสินใจลงไปที่ชั้นข้อมูลมักขจัดมันได้ทั้งหมด
BEGIN;
UPDATE inventory SET reserved = reserved + 1
WHERE sku = 'A-100' AND available >= 1;
INSERT INTO reservation (sku, order_id) VALUES ('A-100', 'ord-9f');
COMMIT;
อ่านภาพร่างนั้นเป็นขอบเขต ไม่ใช่คำแนะนำด้านประสิทธิภาพ ประเด็นคือการตรวจสอบและการแทรกใช้ commit เดียวกัน คำสั่งซื้อที่มาพร้อมกันจึงเห็นสต็อกถูกใช้ไปหรือไม่เห็นเลย
ฐานข้อมูลที่จำลองให้อะไรและไม่ให้อะไร
ฐานข้อมูลที่จำลองสามารถให้ขอบเขตที่กว้างขึ้นเมื่อแบบจำลองทรานแซกชันของมันเองรองรับ Spanner จัดทำเอกสารทรานแซกชันอ่าน-เขียนแบบอะตอมภายในฐานข้อมูลเดียวข้ามตาราง พร้อมการแยกและพฤติกรรมการลองใหม่ที่กำหนดไว้ นั่นคือการรับประกันที่คุณอ่าน ทดสอบ และพึ่งพาอย่างตั้งใจ
ยังเป็นการรับประกันที่มาจากผลิตภัณฑ์ ไม่ใช่จากเส้นทาง VPN ระหว่างภูมิภาคเปลี่ยนวิธีที่แพ็กเก็ตเดินทางและวิธีที่ความล้มเหลวปรากฏ มันไม่ได้ขยายขอบเขตทรานแซกชันแม้แต่แถวเดียว ไม่ว่าอุโมงค์จะดูแข็งแรงเพียงใด การสับสนระหว่างสองสิ่งนี้ก่อให้เกิดสถาปัตยกรรมที่ทุกองค์ประกอบผ่านการตรวจสอบของตัวเองแต่ข้อมูลยังไม่ตรงกัน
ฐานข้อมูลสองตัวไม่กลายเป็นระบบเดียว
ฐานข้อมูลสองตัวที่บริหารแยกกันไม่ได้รับตัวจัดการทรานแซกชันร่วมกันเพียงเพราะไคลเอนต์เข้าถึงได้ทั้งคู่ หากธุรกิจต้องการความมุ่งมั่นแบบอะตอมข้ามคู่นี้จริง ๆ กลไกการประสาน ผู้เข้าร่วม และกระบวนการกู้คืนทั้งหมดต้องถูกเลือกและผ่านการรับรอง ไม่ใช่สันนิษฐาน
ลองคิดถึงช่วงเวลาที่ผู้เข้าร่วมหรือลิงก์หายไปหลังงานถูกเตรียมไว้ การยืนยันแบบกระจายที่รองรับอาจทิ้งสภาวะที่ไม่แน่นอนซึ่งต้องใช้กระบวนการกู้คืนและการตัดสินใจของมนุษย์ และมันไม่ได้มาพร้อมสัญญาว่าทุกภูมิภาคจะยังเขียนได้ผ่านทุกการแบ่งแยก
หากการประสานแบบอะซิงโครนัสยอมรับได้แทน ให้บอกอย่างชัดเจนและจดสภาวะธุรกิจระหว่างกลางพร้อมกฎการกระทบยอด ห่วงโซ่ของขั้นตอนที่ยืนยันภายในเครื่องพร้อมการชดเชยเป็นการออกแบบที่ชอบด้วยเหตุผล มันเพียงไม่ใช่ทรานแซกชันอะตอมเดียวในชื่ออื่น
ออกแบบการลองใหม่ก่อนความล้มเหลวครั้งแรก
ไคลเอนต์อาจสูญเสียการตอบกลับหลังปฏิบัติการถูกยืนยันแล้ว ผู้เรียกจึงถือว่าการหมดเวลาเป็นความล้มเหลวไม่ได้ เก็บรักษาเอกลักษณ์คำขอที่คงทนและใช้ผลลัพธ์ของบริการหรือกลไกการไม่ทำซ้ำก่อนลองใหม่การเปลี่ยนแปลง มิฉะนั้นการลองใหม่จะกลายเป็นการเขียนครั้งที่สอง
คอลแบ็กทรานแซกชันอัตโนมัติยังทำงานได้มากกว่าหนึ่งครั้งหลังการยกเลิกที่ลองใหม่ได้ ซึ่งทำให้มันเป็นที่อยู่ที่ไม่ดีสำหรับผลข้างเคียงภายนอกที่ย้อนกลับไม่ได้ เก็บสิ่งเหล่านั้นไว้นอกคอลแบ็กเว้นแต่เวิร์กโฟลว์กำหนดโปรโตคอลที่ปลอดภัยชัดเจนสำหรับมัน คำเตือนเดียวกันใช้กับทุกสิ่งที่มีค่าใช้จ่ายหรือส่งข้อความ การเรียกเก็บเงินซ้ำเป็นการสนทนาที่ยากกว่าบรรทัดล็อกซ้ำมาก
การยอมรับควรเล่นซ้ำสี่สถานการณ์: ไคลเอนต์สองรายแย่งแถวเดียวกัน การยกเลิกที่บริการบอกว่าลองใหม่ได้ commit ที่คำตอบไม่เคยมาถึง และการสูญเสียภูมิภาคหรือลิงก์ระหว่างกัน บันทึกผลลัพธ์ทางธุรกิจที่ยืนยันแล้วและสภาวะที่ยังไม่คลี่คลายไว้ข้างการออกแบบเส้นทาง เพื่อไม่ให้ใครเข้าใจผิดว่าเครือข่ายเป็นองค์ประกอบที่ให้การรับประกัน