เหตุใดคุณจึงต้องใช้การจำลองแบบกึ่งซิงโครนัส

สวัสดีทุกคน. วลาดิสลาฟ โรดิน ติดต่อมา ปัจจุบันฉันสอนหลักสูตรเกี่ยวกับสถาปัตยกรรมซอฟต์แวร์และสถาปัตยกรรมซอฟต์แวร์ความเครียดสูงที่ OTUS ในความคาดหมายของการเริ่มสตรีมหลักสูตรใหม่ “สถาปนิกรับภาระหนัก” ฉันตัดสินใจเขียนเนื้อหาต้นฉบับเรื่องสั้นที่ฉันต้องการแบ่งปันกับคุณ

เหตุใดคุณจึงต้องใช้การจำลองแบบกึ่งซิงโครนัส

การแนะนำ

เนื่องจาก HDD สามารถทำงานได้ประมาณ 400-700 การดำเนินการต่อวินาทีเท่านั้น (ซึ่งเทียบไม่ได้กับ rps ทั่วไปบนระบบที่มีโหลดสูง) ฐานข้อมูลดิสก์แบบคลาสสิกจึงเป็นคอขวดของสถาปัตยกรรม ดังนั้นจึงจำเป็นต้องให้ความสนใจเป็นพิเศษกับรูปแบบการปรับขนาดของการจัดเก็บข้อมูลนี้

ปัจจุบันมีรูปแบบการปรับขนาดฐานข้อมูลอยู่ 2 รูปแบบ: การจำลองแบบและการแบ่งส่วน Sharding ช่วยให้คุณสามารถปรับขนาดการดำเนินการเขียน และลด rps ต่อการเขียนต่อเซิร์ฟเวอร์ในคลัสเตอร์ของคุณ การจำลองแบบช่วยให้คุณทำสิ่งเดียวกันได้ แต่ด้วยการดำเนินการอ่าน บทความนี้เน้นรูปแบบนี้

การจำลองแบบ

หากคุณดูการจำลองแบบในระดับที่สูงมาก มันเป็นเรื่องง่าย: คุณมีเซิร์ฟเวอร์เดียว มีข้อมูลอยู่บนนั้น และเซิร์ฟเวอร์นี้ก็ไม่สามารถรับมือกับภาระในการอ่านข้อมูลนี้ได้อีกต่อไป คุณเพิ่มเซิร์ฟเวอร์อีกสองสามเซิร์ฟเวอร์ ซิงโครไนซ์ข้อมูลระหว่างเซิร์ฟเวอร์ทั้งหมด และผู้ใช้สามารถอ่านจากเซิร์ฟเวอร์ใดก็ได้ในคลัสเตอร์ของคุณ

แม้จะมีความเรียบง่ายที่ชัดเจน แต่ก็มีหลายตัวเลือกในการจำแนกการใช้งานต่างๆ ของโครงร่างนี้:

  • ตามบทบาทในคลัสเตอร์ (master-master หรือ master-slave)
  • ตามวัตถุที่ส่ง (ตามแถว ตามคำสั่ง หรือผสม)
  • ตามกลไกการซิงโครไนซ์โหนด

วันนี้เราจะมาพูดถึงประเด็นที่ 3

การทำธุรกรรมเกิดขึ้นได้อย่างไร?

หัวข้อนี้ไม่เกี่ยวข้องโดยตรงกับการจำลองแบบ สามารถเขียนบทความแยกต่างหากได้ แต่เนื่องจากการอ่านเพิ่มเติมไม่มีประโยชน์หากไม่เข้าใจกลไกการทำธุรกรรม ฉันขอเตือนคุณถึงสิ่งพื้นฐานที่สุด การทำธุรกรรมจะเกิดขึ้นใน 3 ขั้นตอน:

  1. การบันทึกธุรกรรมลงในบันทึกฐานข้อมูล
  2. การใช้ธุรกรรมในกลไกฐานข้อมูล
  3. ส่งคืนคำยืนยันให้กับลูกค้าว่าธุรกรรมได้นำไปใช้สำเร็จแล้ว

ในฐานข้อมูลที่แตกต่างกัน อัลกอริธึมนี้อาจมีความแตกต่าง: ตัวอย่างเช่น ในกลไก InnoDB ของฐานข้อมูล MySQL จะมีบันทึก 2 รายการ: รายการหนึ่งสำหรับการจำลอง (บันทึกไบนารี) และอีกรายการหนึ่งสำหรับการรักษา ACID (บันทึกเลิกทำ/ทำซ้ำ) ในขณะที่อยู่ใน PostgreSQL มีหนึ่งบันทึกที่ทำหน้าที่ทั้งสองฟังก์ชัน (บันทึกล่วงหน้า = WAL) แต่สิ่งที่นำเสนอข้างต้นนั้นเป็นแนวคิดทั่วไปอย่างแม่นยำซึ่งช่วยให้ไม่ต้องคำนึงถึงความแตกต่างดังกล่าว

การจำลองแบบซิงโครนัส (ซิงค์)

มาเพิ่มตรรกะเพื่อจำลองการเปลี่ยนแปลงที่ได้รับไปยังอัลกอริทึมการส่งธุรกรรม:

  1. การบันทึกธุรกรรมลงในบันทึกฐานข้อมูล
  2. การใช้ธุรกรรมในกลไกฐานข้อมูล
  3. การส่งข้อมูลไปยังแบบจำลองทั้งหมด
  4. ได้รับการยืนยันจากแบบจำลองทั้งหมดว่าธุรกรรมเสร็จสมบูรณ์แล้ว
  5. ส่งคืนคำยืนยันให้กับลูกค้าว่าธุรกรรมได้นำไปใช้สำเร็จแล้ว

ด้วยวิธีนี้เราได้รับข้อเสียหลายประการ:

  • ไคลเอนต์รอการเปลี่ยนแปลงที่จะนำไปใช้กับแบบจำลองทั้งหมด
  • เมื่อจำนวนโหนดในคลัสเตอร์เพิ่มขึ้น เราจะลดโอกาสที่การดำเนินการเขียนจะสำเร็จ

หากทุกอย่างชัดเจนมากหรือน้อยในประเด็นที่ 1 สาเหตุของประเด็นที่ 2 ก็คุ้มค่าที่จะอธิบาย หากในระหว่างการจำลองแบบซิงโครนัส เราไม่ได้รับการตอบกลับจากโหนดอย่างน้อยหนึ่งโหนด เราจะย้อนกลับธุรกรรม ดังนั้น โดยการเพิ่มจำนวนโหนดในคลัสเตอร์ คุณจะเพิ่มโอกาสที่การดำเนินการเขียนจะล้มเหลว

เราสามารถรอการยืนยันจากโหนดเพียงไม่กี่เปอร์เซ็นต์ เช่น จาก 51% (องค์ประชุม) ได้หรือไม่ ใช่ เราทำได้ แต่ในเวอร์ชันคลาสสิก จำเป็นต้องมีการยืนยันจากโหนดทั้งหมด เนื่องจากนี่คือวิธีที่เราสามารถรับประกันความสอดคล้องของข้อมูลที่สมบูรณ์ในคลัสเตอร์ ซึ่งเป็นข้อได้เปรียบที่ไม่ต้องสงสัยของการจำลองประเภทนี้

การจำลองแบบอะซิงโครนัส (async)

มาแก้ไขอัลกอริธึมก่อนหน้ากัน เราจะส่งข้อมูลไปยังแบบจำลอง "ในภายหลัง" และ "ในภายหลัง" การเปลี่ยนแปลงจะมีผลกับแบบจำลอง:

  1. การบันทึกธุรกรรมลงในบันทึกฐานข้อมูล
  2. การใช้ธุรกรรมในกลไกฐานข้อมูล
  3. ส่งคืนคำยืนยันให้กับลูกค้าว่าธุรกรรมได้นำไปใช้สำเร็จแล้ว
  4. การส่งข้อมูลไปยังเรพลิกาและนำการเปลี่ยนแปลงไปใช้กับเรพลิกา

แนวทางนี้นำไปสู่ความจริงที่ว่าคลัสเตอร์ทำงานได้อย่างรวดเร็ว เนื่องจากเราไม่ปล่อยให้ไคลเอ็นต์รอให้ข้อมูลเข้าถึงแบบจำลองและแม้แต่ถูกคอมมิตด้วยซ้ำ

แต่เงื่อนไขของการดัมพ์ข้อมูลลงบนเรพลิกา “ในภายหลัง” อาจนำไปสู่การสูญเสียธุรกรรม และการสูญเสียธุรกรรมที่ได้รับการยืนยันจากผู้ใช้ เพราะหากข้อมูลไม่มีเวลาสำหรับการจำลอง การยืนยันกับลูกค้า เกี่ยวกับความสำเร็จของการดำเนินการที่ถูกส่งไปและโหนดที่การเปลี่ยนแปลงมาถึงนั้นทำให้ HDD เสียหาย เราสูญเสียธุรกรรมซึ่งอาจนำไปสู่ผลลัพธ์ที่ไม่พึงประสงค์อย่างมาก

การจำลองแบบกึ่งซิงค์

ในที่สุดเราก็มาถึงการจำลองแบบกึ่งซิงโครนัส การจำลองแบบประเภทนี้ไม่เป็นที่รู้จักมากนักหรือแพร่หลายมากนัก แต่เป็นที่สนใจอย่างมาก เนื่องจากสามารถรวมข้อดีของการจำลองแบบซิงโครนัสและอะซิงโครนัสเข้าด้วยกันได้

ลองรวม 2 วิธีก่อนหน้านี้เข้าด้วยกัน เราจะไม่รักษาลูกค้าไว้นาน แต่เราจำเป็นต้องจำลองข้อมูล:

  1. การบันทึกธุรกรรมลงในบันทึกฐานข้อมูล
  2. การใช้ธุรกรรมในกลไกฐานข้อมูล
  3. การส่งข้อมูลไปยังแบบจำลอง
  4. ได้รับการยืนยันจากแบบจำลองว่าได้รับการเปลี่ยนแปลงแล้ว (จะมีการนำไปใช้ "ในภายหลัง")
  5. ส่งคืนคำยืนยันให้กับลูกค้าว่าธุรกรรมได้นำไปใช้สำเร็จแล้ว

โปรดทราบว่าด้วยอัลกอริทึมนี้ การสูญเสียธุรกรรมจะเกิดขึ้นก็ต่อเมื่อทั้งโหนดได้รับการเปลี่ยนแปลงและโหนดแบบจำลองล้มเหลว ความน่าจะเป็นของความล้มเหลวดังกล่าวถือว่าต่ำและยอมรับความเสี่ยงเหล่านี้

แต่ด้วยวิธีนี้อาจมีความเสี่ยงที่จะเกิดการอ่าน Phantom ลองจินตนาการถึงสถานการณ์ต่อไปนี้: ในขั้นตอนที่ 4 เราไม่ได้รับการยืนยันจากแบบจำลองใดๆ เราต้องย้อนกลับธุรกรรมนี้และไม่ส่งคืนการยืนยันให้กับลูกค้า เนื่องจากข้อมูลถูกนำไปใช้ในขั้นตอนที่ 2 จึงมีช่องว่างเวลาระหว่างจุดสิ้นสุดของขั้นตอนที่ 2 และการย้อนกลับของธุรกรรม ในระหว่างที่ธุรกรรมแบบขนานสามารถดูการเปลี่ยนแปลงที่ไม่ควรอยู่ในฐานข้อมูล

การจำลองแบบกึ่งซิงค์ที่สูญเสียน้อยลง

หากคุณคิดสักนิด คุณก็สามารถย้อนกลับขั้นตอนของอัลกอริทึมและแก้ไขปัญหาการอ่าน Phantom ในสถานการณ์นี้ได้:

  1. การบันทึกธุรกรรมลงในบันทึกฐานข้อมูล
  2. การส่งข้อมูลจำลอง
  3. ได้รับการยืนยันจากแบบจำลองว่าได้รับการเปลี่ยนแปลงแล้ว (จะมีการนำไปใช้ "ในภายหลัง")
  4. การใช้ธุรกรรมในกลไกฐานข้อมูล
  5. ส่งคืนคำยืนยันให้กับลูกค้าว่าธุรกรรมได้นำไปใช้สำเร็จแล้ว

ตอนนี้เรายอมรับการเปลี่ยนแปลงเฉพาะเมื่อมีการจำลองแบบเท่านั้น

เอาท์พุต

เช่นเคย ไม่มีวิธีแก้ปัญหาในอุดมคติ มีชุดของวิธีแก้ปัญหา ซึ่งแต่ละวิธีก็มีข้อดีและข้อเสียของตัวเอง และเหมาะสำหรับการแก้ปัญหาประเภทต่างๆ นี่เป็นเรื่องจริงสำหรับการเลือกกลไกในการซิงโครไนซ์ข้อมูลในฐานข้อมูลที่ถูกจำลองแบบ ชุดข้อดีที่การจำลองแบบกึ่งซิงโครนัสมีความแข็งแกร่งและน่าสนใจเพียงพอจนถือว่าคุ้มค่าแก่ความสนใจ แม้ว่าจะมีความแพร่หลายต่ำก็ตาม

นั่นคือทั้งหมดที่ แล้วพบกันที่ คอร์ส!

ที่มา: will.com

เพิ่มความคิดเห็น