เรียนรู้ว่าทำไมฐานข้อมูลกระจายมักผ่อนปรนความสอดคล้องเพื่อรักษาความพร้อมใช้งานเมื่อเกิดความล้มเหลว, วิธีการทำงานของ CAP และควอรัม, และเมื่อใดควรเลือกแนวทางแต่ละแบบ

เมื่อฐานข้อมูลถูกกระจายไปยังเครื่องหลายเครื่อง (replica) คุณจะได้ความเร็วและความทนทาน—แต่คุณก็เพิ่มช่วงเวลาที่เครื่องเหล่านั้นอาจไม่เห็นด้วยหรือไม่สามารถสื่อสารกันได้อย่างเชื่อถือได้
ความสอดคล้อง หมายถึง: หลังการเขียนที่สำเร็จ ทุกการอ่านจะได้ค่าที่เหมือนกัน หากคุณอัปเดตอีเมลในโปรไฟล์ การอ่านครั้งถัดไป—ไม่ว่าตอบจาก replica ใด—จะคืนค่าอีเมลใหม่
ในทางปฏิบัติ ระบบที่ให้ความสำคัญกับความสอดคล้องอาจ หน่วงหรือปฏิเสธ บางคำขอในช่วงความล้มเหลวเพื่อหลีกเลี่ยงการคืนคำตอบที่ขัดแย้งกัน
ความพร้อมใช้งาน หมายถึง: ระบบตอบคำขอทุกคำขอ แม้บางเซิร์ฟเวอร์จะล้มเหลวหรือตัดการเชื่อมต่อ คุณอาจไม่ได้ข้อมูลล่าสุด แต่คุณได้คำตอบ
ในทางปฏิบัติ ระบบที่เน้นความพร้อมใช้งานอาจยอมรับการเขียนและให้การอ่าน แม้ replica จะแตกต่างกันอยู่ แล้วรวมความต่างภายหลัง
การ แลกเปลี่ยน หมายความว่าคุณไม่สามารถทำให้ทั้งสองเป้าหมายสูงสุดพร้อมกันได้เสมอไป หาก replica ไม่สามารถประสานกัน ฐานข้อมูลต้องเลือกระหว่าง:
สมดุลที่เหมาะสมขึ้นกับความผิดพลาดที่คุณยอมรับได้: การหยุดชั่วคราวหรือช่วงเวลาของข้อมูลผิด/เก่า ระบบจริงส่วนใหญ่เลือกจุดกึ่งกลาง—และทำให้การแลกเปลี่ยนนั้นชัดเจน
ฐานข้อมูลถือว่า “กระจาย” เมื่อเก็บและให้บริการข้อมูลจากเครื่องหลายเครื่อง (โหนด) ที่ประสานงานผ่านเครือข่าย ต่อให้แอปเห็นว่าเป็นฐานข้อมูลเดียว แต่ภายใต้ผิวคำขออาจถูกจัดการโดยโหนดต่างกันในที่ต่างกัน
ฐานข้อมูลกระจายส่วนใหญ่มักทำสำเนาข้อมูล: เรคอร์ดเดียวกันถูกเก็บบนโหนดหลายตัว ทีมทำเพื่อ:
การทำสำเนามีพลัง แต่ก็ยกคำถามทันที: ถ้าโหนดสองตัวมีสำเนาเดียวกัน จะรับประกันว่าพวกมันเห็นด้วยเสมอได้อย่างไร?
บนเซิร์ฟเวอร์เดียว “down” มักชัดเจน: เครื่องขึ้นหรือลง ในระบบกระจาย ความล้มเหลวมักเป็นแบบบางส่วน โหนดหนึ่งอาจยังวิ่งแต่ช้า ลิงก์เครือข่ายอาจทิ้งแพ็กเก็ต แร็คทั้งแร็คอาจสูญเสียการเชื่อมต่อ ทั้งคลัสเตอร์ยังทำงานต่อ
เรื่องนี้สำคัญเพราะโหนดไม่สามารถรู้ได้ทันทีว่าโหนดอื่น “ล้มจริง” หยุดชั่วคราว หรือแค่ช้า ขณะที่พวกมันรอคำตอบ ต้องตัดสินใจว่าจะจัดการการอ่านและการเขียนอย่างไร
บนเซิร์ฟเวอร์เดียว มีแหล่งความจริงเดียว: ทุกการอ่านเห็นการเขียนที่สำเร็จล่าสุด
กับหลายโหนด “ล่าสุด” ขึ้นกับการประสาน หากการเขียนสำเร็จที่โหนด A แต่โหนด B ไม่สามารถเข้าถึงได้ ฐานข้อมูลควรจะ:
แรงตึงนี้—เกิดจริงจากเครือข่ายที่ไม่สมบูรณ์—คือเหตุผลที่การกระจายเปลี่ยนกฎ
การแยกเครือข่าย (network partition) คือการขาดการสื่อสารระหว่างโหนดที่ควรทำงานเป็นฐานข้อมูลเดียว โหนดอาจยังทำงานได้ แต่ไม่สามารถแลกเปลี่ยนข้อความได้อย่างเชื่อถือได้—เพราะสวิตช์เสีย ลิงก์โอเวอร์โหลด การเปลี่ยนเส้นทางผิดพลาด กฎไฟร์วอลล์ไม่ถูกต้อง หรือแม้แต่เพื่อนร่วมงานเสียงดังในเครือข่ายคลาวด์
เมื่อระบบถูกกระจายข้ามหลายเครื่อง (มักข้ามแร็ค โซน หรือภูมิภาค) คุณไม่ได้ควบคุมทุกฮอประหว่างพวกมัน เครือข่ายทิ้งแพ็กเก็ต เพิ่มความหน่วง และบางครั้งแบ่งเป็น "เกาะ" เหตุการณ์เหล่านี้ที่ขนาดเล็กอาจหายาก แต่ที่ขนาดใหญ่จะเกิดบ่อย แม้การขัดจังหวะสั้น ๆ ก็สำคัญ เพราะฐานข้อมูลต้องการการประสานอย่างต่อเนื่องเพื่อเห็นเหตุการณ์ว่าเกิดอะไรขึ้น
ในช่วงพาร์ติชัน ทั้งสองฝั่งยังรับคำขอได้ หากผู้ใช้สามารถเขียนทั้งสองฝั่ง แต่ละฝั่งอาจยอมรับการอัปเดตที่อีกฝั่งไม่เห็น
ตัวอย่าง: โหนด A อัปเดตที่อยู่ผู้ใช้เป็น “New Street” ในขณะที่โหนด B อัปเดตเป็น “Old Street Apt 2” แต่ละฝั่งเชื่อว่าการเขียนของตนเป็นล่าสุด—เพราะไม่มีทางเปรียบเทียบแบบเรียลไทม์
พาร์ติชันไม่ปรากฏเป็นข้อความผิดพลาดชัดเจน แต่แสดงเป็นพฤติกรรมสับสน:
นี่คือจุดกดดันที่บังคับให้ต้องเลือก: เมื่อเครือข่ายไม่รับประกันการสื่อสาร ฐานข้อมูลกระจายต้องตัดสินใจว่าจะให้ความสำคัญกับความสอดคล้องหรือความพร้อมใช้งาน
CAP คือวิธีสรุปสั้น ๆ ว่าเกิดอะไรขึ้นเมื่อฐานข้อมูลกระจายอยู่บนเครื่องหลายเครื่อง
เมื่อ ไม่มีพาร์ติชัน ระบบหลายชนิดสามารถดูทั้งสอดคล้องและพร้อมใช้งานได้
เมื่อ เกิดพาร์ติชัน คุณต้องเลือกว่าจะให้ความสำคัญกับอะไร:
balance = 100 กับ Server A.balance = 80.CAP ไม่ได้หมายความว่า "เลือกได้แค่สองเสมอ" แต่มันหมายความว่า เมื่อเกิดพาร์ติชัน คุณไม่สามารถการันตีได้ทั้งสองอย่างพร้อมกัน นอกพาร์ติชัน ระบบมักจะเข้าใกล้ทั้งสองได้บ่อยครั้ง—จนกว่าเครือข่ายจะมีปัญหา
การเลือก ความสอดคล้อง หมายความว่าฐานข้อมูลให้ความสำคัญกับ "ทุกคนเห็นความจริงเดียวกัน" มากกว่า "ตอบเสมอ" ในทางปฏิบัติ นี้มักชี้ไปที่ ความสอดคล้องแบบเข้มงวด หรือที่อธิบายว่าเป็นพฤติกรรมแบบ linearizable: เมื่อการเขียนได้รับการยืนยัน การอ่านใด ๆ ภายหลัง (จากที่ไหนก็ได้) จะคืนค่านั้นเหมือนมีสำเนาเดียวที่อัปเดต
เมื่อเครือข่ายแยกและ replica สื่อสารกันไม่ได้อย่างเชื่อถือได้ ระบบที่สอดคล้องอย่างหนักจะไม่สามารถยอมรับการอัปเดตอิสระทั้งสองฝั่งได้อย่างปลอดภัย เพื่อปกป้องความถูกต้อง มันมักจะ:
จากมุมมองผู้ใช้ นี่อาจดูเหมือนการหยุดชั่วคราวแม้บางเครื่องจะยังทำงานอยู่
ประโยชน์หลักคือ การคิดง่ายขึ้น โค้ดแอปสามารถทำงานเหมือนกำลังคุยกับฐานข้อมูลเดียว ไม่ใช่ replica หลายตัวที่อาจขัดแย้ง ซึ่งลดช่วงเวลา "แปลก ๆ" เช่น:
คุณยังได้โมเดลทางความคิดที่ชัดเจนสำหรับการตรวจสอบ บิลลิ่ง และงานที่ต้องถูกต้องทันที
ความสอดคล้องมีต้นทุนจริง:
ถ้าผลิตภัณฑ์ของคุณทนต่อคำขอล้มเหลวระหว่างการหยุดชั่วคราวไม่ได้ ความสอดคล้องแบบเข้มงวดอาจรู้สึกแพง—แม้บางครั้งจะเป็นตัวเลือกที่ถูกต้องสำหรับความถูกต้อง
การเลือกความพร้อมใช้งานหมายถึงการมุ่งสัญญาง่าย ๆ: ระบบตอบ แม้บางส่วนของโครงสร้างพื้นฐานจะมีปัญหา ในทางปฏิบัติ "ความพร้อมใช้งานสูง" ไม่ได้แปลว่า "ไม่มีข้อผิดพลาดเลย"—แต่คือคำขอส่วนใหญ่ยังได้คำตอบระหว่างการล้มเหลวของโหนด รีพลิก หรือการเชื่อมต่อเครือข่ายเสีย
เมื่อเครือข่ายแยก replica ไม่สามารถคุยกันได้อย่างเชื่อถือได้ ฐานข้อมูลที่เน้นความพร้อมใช้งานมักจะให้บริการจากฝั่งที่เข้าถึงได้:
สิ่งนี้ทำให้แอปยังดำเนินต่อไป แต่หมายความว่า replica ต่าง ๆ อาจยอมรับ "ความจริง" ที่ต่างกันชั่วคราว
คุณได้ uptime ที่ดีกว่า: ผู้ใช้ยังท่องเว็บ ใส่ของลงตะกร้า โพสต์คอมเมนต์ หรือติดตามเหตุการณ์ได้แม้ภูมิภาคจะโดนแยก
คุณยังได้ประสบการณ์ผู้ใช้ที่ราบเรียบกว่าในช่วงความเครียด แทนที่จะเจอ timeout แอปของคุณอาจแสดงพฤติกรรมที่สมเหตุสมผล ("บันทึกการอัปเดตของคุณแล้ว") แล้วซิงก์ภายหลัง สำหรับงานผู้บริโภคและงานวิเคราะห์หลายอย่าง การแลกเปลี่ยนนี้คุ้มค่า
ราคาที่ต้องจ่ายคือฐานข้อมูลอาจคืน การอ่านล้าสมัย ผู้ใช้อาจอัปเดตโปรไฟล์บน replica หนึ่ง แล้วอ่านจาก replica อีกตัวและยังเห็นค่าดั้งเดิม
คุณยังเสี่ยงกับ ความขัดแย้งของการเขียน ผู้ใช้สองคน (หรือผู้ใช้คนเดียวในสองที่) อาจอัปเดตเรคอร์ดเดียวกันบนฝั่งต่างกันของพาร์ติชัน เมื่อการเชื่อมคืน ระบบต้องรวมประวัติที่ต่างกัน อาจเลือกให้เขียนหนึ่งชนะ ผสานฟิลด์ หรือให้แอปจัดการความขัดแย้ง
การออกแบบแบบเน้นความพร้อมใช้งานคือการยอมรับการไม่เห็นด้วยชั่วคราวเพื่อให้ผลิตภัณฑ์ยังตอบ—แล้วลงทุนในวิธีการตรวจจับและซ่อมแซมความต่างภายหลัง
ควอรัมเป็นเทคนิคการโหวตที่ฐานข้อมูลรีพลิเคตหลายระบบใช้เพื่อลดช่องว่างระหว่างความสอดคล้องและความพร้อมใช้งาน แทนที่จะเชื่อโหนดเดียว ระบบถามโหนด พอประมาณ เพื่อให้เห็นด้วย
มักจะเห็นควอรัมอธิบายด้วยตัวเลขสามตัว:
กฎง่าย ๆ ที่พบบ่อยคือ: ถ้า R + W > N การอ่านทุกครั้งจะทับกับการเขียนที่สำเร็จบน replica อย่างน้อยหนึ่งตัว ซึ่งลดโอกาสการอ่านข้อมูลล้าสมัย
ถ้าคุณมี N=3 replica:
บางระบบตั้ง W=3 (ทุก replica) เพื่อความสอดคล้องสูง แต่จะทำให้การเขียนล้มเหลวง่ายกว่าเมื่อ replica ใดช้าหรือลง
ควอรัมไม่กำจัดปัญหาพาร์ติชัน—แต่มันกำหนด ฝ่ายที่สามารถทำงานต่อได้ หากเครือข่ายแบ่งเป็น 2–1 ฝั่งที่มี 2 replica ยังสามารถพอใจ R=2 และ W=2 ได้ ฝั่งเดียวโดดจะทำไม่ได้ ซึ่งช่วยลดการอัปเดตที่ขัดแย้ง แต่ก็หมายความว่าลูกค้าบางส่วนจะเจอข้อผิดพลาดหรือ timeout
ควอรัมมักหมายถึง ความหน่วงเพิ่มขึ้น (ต้องติดต่อโหนดมากขึ้น), ต้นทุนสูงขึ้น (ทราฟฟิกข้ามโหนดมากขึ้น), และพฤติกรรมการล้มเหลวที่ซับซ้อนกว่า (timeout อาจดูเหมือนไม่พร้อมใช้งาน) แต่ข้อดีคือเป็นทางสายกลางที่ปรับได้: คุณสามารถเลื่อน R และ W ให้เข้ากับการอ่านที่สดขึ้นหรือการยอมรับการเขียนมากขึ้นตามความสำคัญ
ความสอดคล้องในท้ายที่สุดหมายความว่า replica ถูกปล่อยให้ไม่ซิงก์กันชั่วคราว ตราบใดที่พวกมัน รวมเป็นค่าเดียวกัน ในภายหลัง
คิดถึงเครือร้านกาแฟที่อัปเดตป้าย "สินค้าขาด" สำหรับขนมชิ้นหนึ่ง ร้านหนึ่งขึ้นว่า "ขาด" แต่การอัปเดตไปถึงร้านอื่นอีกไม่กี่นาที ในช่วงนั้นร้านอื่นอาจยังแสดงว่า "มี" และขายชิ้นสุดท้าย ไม่มีระบบไหน "เสีย" แค่การอัปเดตกำลังตามกันทัน
เมื่อข้อมูลกำลังแพร่หลาย ลูกค้าอาจเห็นพฤติกรรมที่น่าประหลาดใจ:
ระบบ eventual consistency มักมีกลไกพื้นหลังเพื่อลดช่องว่างความไม่สอดคล้อง:
เหมาะเมื่ความพร้อมใช้งานสำคัญกว่าการมีข้อมูลปัจจุบันสมบูรณ์: ฟีดกิจกรรม ตัวนับวิว คำแนะนำ โปรไฟล์ที่แคช บันทึก/เทเลเมทรี และข้อมูลไม่สำคัญที่ "ถูกต้องในไม่กี่วินาที/นาที" เป็นที่ยอมรับ
เมื่อฐานข้อมูลยอมรับการเขียนบน replica หลายตัว อาจเกิดความขัดแย้ง: อัปเดตสองครั้งขึ้นไปกับไอเท็มเดียวกันที่เกิดขึ้นอิสระบน replica ต่างกันก่อนที่จะซิงก์
ตัวอย่างคลาสสิกคือผู้ใช้เปลี่ยนที่อยู่จัดส่งบนอุปกรณ์หนึ่ง ในขณะที่เปลี่ยนเบอร์โทรบนอีกอุปกรณ์ ถ้าการอัปเดตแต่ละอันไปตกคนละ replica ในช่วงตัดการเชื่อมต่อ ระบบต้องตัดสินว่าสุดท้ายแล้วเรคอร์ดไหนคือ "ของจริง" เมื่อ replica แลกเปลี่ยนข้อมูลกัน
หลายระบบเริ่มจาก last-write-wins: อันไหนมี timestamp ใหม่กว่าจะเขียนทับ
มันน่าสนใจเพราะทำได้ง่ายและเร็ว แต่ข้อเสียคืออาจ ทำให้ข้อมูลหายโดยเงียบ ๆ ถ้า "ใหม่สุด" ชนะ การเปลี่ยนที่สำคัญแต่เก่ากว่าอาจถูกทับ แม้สองการอัปเดตจะกระทบคนละฟิลด์
ยังสมมติว่านาฬิกาเชื่อถือได้ด้วย ความเบี้ยวนาฬิการะหว่างเครื่อง/ไคลเอนต์อาจทำให้การอัปเดตที่ผิดเป็นฝ่ายชนะ
การจัดการความขัดแย้งที่ปลอดภัยมักต้องติดตามประวัติเชิงสาเหตุ
เชิงแนวคิด version vectors (และรูปแบบย่อย) ผูกเมตาดาต้ากับแต่ละเรคอร์ดที่สรุปว่า "โหนดไหนเห็นอัปเดตไหน" เมื่อ replica แลกเวอร์ชัน ฐานข้อมูลสามารถตรวจสอบได้ว่ารุ่นหนึ่งรวมอีกอัน (ไม่มีความขัดแย้ง) หรือแยกออก (ต้องแก้)
บางระบบใช้ตรรกะเวลาหรือ hybrid logical clocks เพื่อลดการพึ่งพานาฬิกาจริงในขณะที่ยังให้เบาะแสการจัดลำดับ
เมื่อพบความขัดแย้ง คุณมีทางเลือก:
วิธีที่ดีที่สุดขึ้นกับความหมายของคำว่า "ถูกต้อง" สำหรับข้อมูลของคุณ—บางครั้งการสูญเสียการเขียนยอมรับได้ บางครั้งนั่นคือบั๊กทางธุรกิจสำคัญ
การเลือกทิศทางความสอดคล้อง/ความพร้อมใช้งานไม่ใช่การโต้วาทีเชิงปรัชญา แต่มันคือการตัดสินใจเชิงผลิตภัณฑ์ เริ่มจากถามว่า: ความเสียหายจากการผิดชั่วคราวคืออะไร และความเสียหายจากการบอกให้ผู้ใช้ "ลองใหม่ที" เป็นอย่างไร?
บางโดเมนต้องคำตอบเดียวที่น่าเชื่อถือทันทีเพราะ "เกือบถูก" ก็ผิดได้:
ถ้าผลกระทบจากความไม่ตรงกันชั่วคราวต่ำหรือย้อนกลับได้ คุณมักจะเลือกความพร้อมใช้งานมากขึ้น
ประสบการณ์ผู้ใช้หลายอย่างโอเคกับการอ่านเก่าสักเล็กน้อย:
ชัดเจนว่าระยะเวลาที่ยอมรับได้คือเท่าไร: วินาที นาที หรือชั่วโมง งบเวลานี้จะกำหนดการตั้งค่าการจำลองและควอรัมของคุณ
เมื่อ replica ไม่สามารถตกลงกัน คุณมักจะได้หนึ่งในสามผลลัพธ์ UX:
เลือกตัวเลือกที่สร้างความเสียหายน้อยที่สุดต่อฟีเจอร์ ไม่ใช่ทั้งระบบ
เชื่อม C (consistency) ถ้า: ผลลัพธ์ผิดสร้างความเสี่ยงทางการเงิน/กฎหมาย ความปลอดภัย หรือการกระทำที่ไม่สามารถย้อนกลับ
เชื่อม A (availability) ถ้า: ผู้ใช้ให้ความสำคัญกับการตอบสนอง ข้อมูลล้าสมัยยอมรับได้ และความขัดแย้งสามารถแก้ได้ภายหลัง
ถ้าสงสัย แยกระบบ: เก็บเรคอร์ดสำคัญให้สอดคล้องอย่างเข้มงวด และปล่อยมุมมองอนุมาน (ฟีด แคช วิเคราะห์) ให้เน้นความพร้อมใช้งาน
คุณไม่จำเป็นต้องเลือกค่าเดียวสำหรับทั้งระบบ ฐานข้อมูลกระจายสมัยใหม่หลายตัวให้คุณเลือกความสอดคล้องต่อการดำเนินการ และแอปที่ฉลาดใช้ประโยชน์จากสิ่งนี้เพื่อรักษาประสบการณ์ผู้ใช้ให้ราบเรียบโดยไม่ปิดบังการแลกเปลี่ยน
ปฏิบัติกับความสอดคล้องเหมือนปุ่มปรับตามสิ่งที่ผู้ใช้กำลังทำ:
วิธีนี้หลีกเลี่ยงการจ่ายต้นทุนความสอดคล้องสูงสุดสำหรับทุกอย่าง แต่ยังปกป้องการดำเนินการที่จำเป็นจริง ๆ
รูปแบบที่พบบ่อยคือ แรงสำหรับเขียน อ่อนสำหรับอ่าน:
ในบางกรณี ทำแบบกลับกัน: เขียนเร็ว (คิว/แบบ eventual) พร้อม อ่านเข้มงวด เมื่อยืนยันผล ("คำสั่งของฉันไปแล้วหรือยัง?")
เมื่อเครือข่ายสั่นคลอน ลูกค้ามักลองใหม่ ทำให้ลองใหม่ปลอดภัยด้วย idempotency keys เพื่อให้การส่งคำสั่งซ้ำ ๆ (เช่น "ส่งคำสั่งซื้อ") จะไม่สร้างคำสั่งซ้ำ เก็บและใช้ผลลัพธ์แรกเมื่อเห็นคีย์เดิมอีกครั้ง
สำหรับการกระทำหลายขั้นข้ามบริการ ให้ใช้ saga: แต่ละขั้นมี การกระทำชดเชย (คืนเงิน ปล่อยการจอง ยกเลิกการจัดส่ง) วิธีนี้ทำให้ระบบกู้คืนได้แม้บางส่วนไม่ตรงกันหรือล้มเหลวชั่วคราว
คุณจะจัดการการแลกเปลี่ยนไม่ได้ถ้าคุณมองไม่เห็น ปัญหาในโปรดักชันมักดูเหมือน "ข้อผิดพลาดสุ่ม" จนกว่าคุณจะเพิ่มการวัดและการทดสอบที่เหมาะสม
เริ่มจากชุดเมตริกเล็ก ๆ ที่เชื่อมตรงกับผลกระทบต่อผู้ใช้:
ถ้าเป็นไปได้ ติด tag เมตริกตาม โหมดความสอดคล้อง (ควอรัม vs ท้องถิ่น) และ ภูมิภาค/โซน เพื่อหาจุดแตกต่างของพฤติกรรม
อย่ารอการล้มจริง ในสเตจ ลอง chaos experiments ที่จำลอง:
ตรวจสอบไม่ใช่แค่ "ระบบยังขึ้น" แต่ให้ดูว่าการรับประกันอะไรยังคงอยู่: การอ่านยังสดไหม การเขียนบล็อกหรือไม่ ลูกค้าได้ข้อผิดพลาดชัดเจนหรือไม่
เพิ่มการแจ้งเตือนสำหรับ:
สุดท้าย ทำให้การรับประกันชัดเจน: เอกสารว่าสัญญาอะไรระหว่างการทำงานปกติและระหว่างพาร์ติชัน และสอนทีมผลิตภัณฑ์และซัพพอร์ตว่าผู้ใช้จะเห็นอะไรและจะตอบอย่างไร
ถ้าคุณกำลังสำรวจการแลกเปลี่ยนเหล่านี้ในผลิตภัณฑ์ใหม่ ควรยืนยันสมมติฐานตั้งแต่ต้น—โดยเฉพาะพฤติกรรมการล้ม ลักษณะการลองใหม่ และรูปร่างของข้อมูลล้าสมัยใน UI
แนวทางปฏิบัติที่ใช้ได้จริงคือทำต้นแบบขนาดเล็กของเวิร์กโฟลว์ (เส้นทางเขียน เส้นทางอ่าน การลองใหม่/ไอดีมพอเทนซี และงานรวมผล) ก่อนตัดสินใจสถาปัตยกรรมเต็มรูปแบบ ด้วย Koder.ai, ทีมสามารถสปินเว็บแอปและแบ็กเอนด์ผ่านเวิร์กโฟลว์ที่ขับเคลื่อนด้วยแชท ทำซ้ำโมเดลข้อมูลและ API ได้รวดเร็ว และทดสอบรูปแบบความสอดคล้องต่าง ๆ (เช่น เขียนเคร่งครัด + อ่านผ่อนปรน) โดยไม่ต้องผ่าน pipeline การสร้างแบบดั้งเดิม เมื่อต้นแบบตรงกับพฤติกรรมที่ต้องการ คุณสามารถส่งออกซอร์สโค้ดและพัฒนาต่อสู่การผลิตได้
ในฐานข้อมูลที่ทำสำเนา ข้อมูล "เดียวกัน" จะอาศัยอยู่บนเครื่องหลายเครื่อง สิ่งนี้ช่วยเพิ่มความทนทานและลดหน่วงเวลา แต่ก็นำปัญหาการประสานมาด้วย: โหนดอาจช้า ไม่สามารถเข้าถึงได้ หรือตกอยู่ในสภาวะแยกของเครือข่าย ทำให้พวกมันไม่สามารถตกลงกันทันทีว่าการเขียนล่าสุดคืออะไร
หมายถึง: หลังการเขียนที่สำเร็จ การอ่านใด ๆ ภายหลังจะต้องคืนค่าที่เหมือนกันไม่ว่าจะอ่านจาก replica ใด ในทางปฏิบัติ ระบบมักบังคับโดยการหน่วงหรือปฏิเสธการอ่าน/การเขียนจนกว่า replica เพียงพอ (หรือ leader) จะยืนยันการอัปเดต
หมายถึงระบบจะตอบกลับด้วยการตอบที่ไม่ใช่ข้อผิดพลาดสำหรับทุกคำขอ แม้บางโหนดจะล้มเหลวหรือไม่สามารถสื่อสารได้ คำตอบนั้นอาจเป็นข้อมูลล้าสมัย เป็นผลลัพธ์บางส่วน หรือมาจากความรู้ในเครื่องท้องถิ่น แต่ระบบหลีกเลี่ยงการบล็อกผู้ใช้ระหว่างความล้มเหลว
คือการตัดการสื่อสารระหว่างโหนดที่ควรทำงานร่วมกัน โหนดยังอาจทำงานได้ปกติ แต่ข้อความไม่สามารถข้ามการแบ่งได้อย่างเชื่อถือได้ ซึ่งบีบให้ฐานข้อมูลต้องเลือกระหว่าง:
ทั้งสองฝั่งอาจรับอัปเดตที่อีกฝั่งยังไม่เห็น ส่งผลให้เกิด:
นี่คือผลกระทบที่ผู้ใช้เห็นเมื่อ replica ไม่สามารถประสานกันได้ชั่วคราว
มันไม่ได้หมายความว่า "เลือกได้แค่สองตลอดไป" แต่หมายความว่า เมื่อเกิดพาร์ติชัน คุณไม่สามารถรับรองทั้ง:
นอกช่วงพาร์ติชัน ระบบส่วนใหญ่สามารถดูเหมือนให้ทั้งสองได้ในเวลาปกติ—จนกว่าเครือข่ายจะเกิดปัญหา
ควอรัมใช้การโหวตข้าม replica:
แนวทางที่พบบ่อยคือ R + W > N เพื่อลดการอ่านล้าสมัย ควอรัมไม่ได้กำจัดพาร์ติชัน แต่กำหนดว่าใครมีสิทธิเพื่อให้ระบบก้าวหน้า (เช่น ฝั่งที่ยังมีเสียงข้างมากจะทำงานต่อได้)
ความสอดคล้องแบบท้ายที่สุดยอมให้ replica ไม่สอดคล้องกันชั่วคราว ตราบใดที่พวกมัน รวมเป็นค่าเดียวกัน ในภายหลัง อาการที่พบได้บ่อยรวมถึง:
ระบบมักลดช่องเวลาความไม่สอดคล้องด้วย , , และการไล่เช็ค/ซิงก์เป็นระยะ (anti-entropy)
ความขัดแย้งเกิดเมื่อ replica ยอมรับการเขียนต่างกันกับรายการเดียวกันในช่วงการตัดการเชื่อมต่อ กลยุทธ์การแก้ไขรวมถึง:
เลือกวิธีตามความหมายของ “ถูกต้อง” สำหรับข้อมูลของคุณ
เริ่มจากถามว่า: ความผิดพลาดชั่วคราวมีค่าเสียหายเท่าไร และการบอกให้ผู้ใช้ "ลองใหม่ที" มีผลอย่างไร
รูปแบบปฏิบัติได้แก่ การตั้งระดับความสอดคล้องต่อการดำเนินการ, ใช้คีย์ idempotency สำหรับการลองใหม่ และใช้ saga พร้อมการชดเชยสำหรับเวิร์กโฟลว์หลายขั้นตอน