การจำลองแบบ MySQL ได้รับผลกระทบจากการเชื่อมต่อระหว่างกันที่มีความล่าช้าสูงหรือไม่


11

เรามี vanilla master และ MySQL setup ที่อยู่ในดาต้าเซ็นเตอร์ที่ต่างกันและสเลฟอื่นในดาต้าเซ็นเตอร์เดียวกับ master

แบนด์วิดท์ระหว่างดาต้าเซ็นเตอร์นั้นค่อนข้างสูง (ในการวัดประสิทธิภาพเครือข่ายที่เราทำเราสามารถไปถึง 15MB / วินาที) แต่มีความหน่วงแฝงอยู่ประมาณ 28ms มันไม่สูงด้วยวิธีใด ๆ แต่มันจะสูงกว่าเวลาแฝงย่อยที่สองในดาต้าเซ็นเตอร์เดียวกัน

ในบางครั้งเราพบความล่าช้าที่รุนแรง (2,000 วินาทีขึ้นไป) กับการลบสลาฟในขณะที่สลาฟท้องถิ่นจะอัปเดตอยู่เสมอ เมื่อดูที่ remote slave lagging, โดยปกติแล้วเธรด SQL จะใช้เวลาในการรอเธรด IO เพื่ออัพเดตล็อกรีเลย์ ต้นแบบแสดง "กำลังรอเน็ต" หรือบางอย่างในเวลาเดียวกัน

ดังนั้นหมายความว่าเป็นเครือข่าย แต่เรายังคงมีแบนด์วิดธ์ฟรีในขณะที่เกิดเหตุการณ์นี้

คำถามของฉันคือสามารถแฝงระหว่างศูนย์ข้อมูลที่มีผลต่อประสิทธิภาพการจำลองแบบหรือไม่ slave io thread เพียงแค่สตรีมเหตุการณ์จนกระทั่งต้นแบบหยุดส่งหรือว่ามันรวมกำไรหลักระหว่างเหตุการณ์หรือไม่?


2,000 วินาที ดังนั้นความล่าช้า 33 นาที?
ริชาร์ด

ใช่ ... มันขึ้นและลงตลอดทั้งวัน
shlomoid

2
+1 เพราะฉันชอบคำถามประเภทนี้ในเว็บไซต์นี้ โปรดบอกให้คนอื่น ๆ มาที่ไซต์นี้พร้อมกับคำถามเกี่ยวกับเรื่องนี้ !!!
RolandoMySQLDBA

คำตอบ:


7

คำตอบสำหรับคำถามของคุณโดยตรงคือใช่ แต่ขึ้นอยู่กับรุ่นของ MySQL ที่คุณใช้งาน ก่อน MySQL 5.5 การจำลองแบบจะทำงานดังนี้:

  • ปริญญาโทดำเนินการ SQL
  • Master บันทึกเหตุการณ์ SQL ในบันทึกไบนารี
  • Slave อ่านกิจกรรม SQL จากบันทึกไบนารีหลัก
  • Slave จัดเก็บเหตุการณ์ SQL ในบันทึกการทำงานรีเลย์ผ่านเธรด I / O
  • Slave อ่านกิจกรรม SQL ถัดไปจากบันทึกการส่งผ่าน SQL Thread
  • Slave เรียกใช้งาน SQL
  • Slave Acknowledges Master of the Execution สมบูรณ์ของเหตุการณ์ SQL

ในฐานะของ MySQL 5.5, ใช้Semisynchronous Replicationตอนนี้การจำลองแบบจะทำงานดังนี้:

  • ปริญญาโทดำเนินการ SQL
  • Master บันทึกเหตุการณ์ SQL ในบันทึกไบนารี
  • Slave อ่านกิจกรรม SQL จากบันทึกไบนารีหลัก
  • Slave Acknowledges Master of Receipt ของเหตุการณ์ SQL
  • Slave จัดเก็บเหตุการณ์ SQL ในบันทึกการทำงานรีเลย์ผ่านเธรด I / O
  • Slave อ่านกิจกรรม SQL ถัดไปจากบันทึกการส่งผ่าน SQL Thread
  • Slave เรียกใช้งาน SQL
  • Slave Acknowledges Master of the Execution สมบูรณ์ของเหตุการณ์ SQL

กระบวนทัศน์ใหม่นี้จะอนุญาตให้ Slave ซิงค์กับเจ้านายได้ใกล้ชิดยิ่งขึ้น

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

อัพเดท 2011-08-08 14:22 EDT

การกำหนดค่าของ MySQL 5.5 Semisynchronous Replication นั้นตรงไปตรงมา

ขั้นตอนที่ 1) เพิ่มบรรทัดสี่ (4) เหล่านี้ใน /etc/my.cnf

[mysqld]
plugin-dir=/usr/lib64/mysql/plugin
#rpl_semi_sync_master_enabled
#rpl_semi_sync_master_timeout=5000
#rpl_semi_sync_slave_enabled

ขั้นตอนที่ 2) รีสตาร์ท MySQL

service mysql restart

ขั้นตอนที่ 3) เรียกใช้คำสั่งเหล่านี้ในไคลเอนต์ MySQL

INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
INSTALL PLUGIN rpl_semi_sync_slave  SONAME 'semisync_slave.so';

ขั้นตอนที่ 4) ยกเลิกหมายเหตุตัวเลือกสามตัวเลือก rpm_semi_sync หลังจากตัวเลือก plugin-dir

[mysqld]
plugin-dir=/usr/lib64/mysql/plugin
rpl_semi_sync_master_enabled
rpl_semi_sync_master_timeout=5000
rpl_semi_sync_slave_enabled

ขั้นตอนที่ 5) รีสตาร์ท MySQL

service mysql restart

เสร็จหมดแล้ว !!! ตอนนี้เพียงตั้งค่าการจำลองแบบ MySQL ตามปกติ


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

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

โดยทั้งหมดฉันขอแนะนำให้ใช้ MySQL 5.5 เพื่อใช้ประโยชน์จากรูปแบบใหม่ของการจำลองแบบ MySQL นี้รวมถึงการปรับปรุง InnoDB
RolandoMySQLDBA

1
ใช่แน่นอนว่าเราใช้ MySQL 5.5 แต่นี่ไม่ใช่ประเภทการจำลองแบบเริ่มต้น คุณต้องทำตามขั้นตอนการกำหนดค่าทั้งหมดติดตั้งปลั๊กอินและเพื่อให้มันทำงานได้ในแบบกึ่งซิงโครนัส
shlomoid

2

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

ด้วยไคลเอ็นต์ลำดับของการดำเนินการสำหรับการจำลองแบบอะซิงโครนัสอาจเป็นดังนี้:

  1. ไคลเอ็นต์ส่งแบบสอบถาม SQL (ตัวอย่างเช่นแทรก) ไปยังต้นแบบโดยใช้ธุรกรรม

  2. Master ดำเนินการธุรกรรม ในกรณีที่ประสบความสำเร็จบันทึกจะถูกเก็บไว้ในดิสก์ แต่ยังไม่ได้ทำธุรกรรม

  3. Master บันทึกเหตุการณ์การแทรกในบันทึกไบนารีหลักหากต้นแบบไม่สามารถเก็บไว้ในบันทึกไบนารีธุรกรรมจะถูกย้อนกลับ

  4. ลูกค้าได้รับการตอบกลับจากต้นแบบ (สำเร็จหรือย้อนกลับ)

  5. ในกรณีที่ทำธุรกรรมสำเร็จเธรดดัมพ์บนมาสเตอร์จะอ่านเหตุการณ์จากบันทึกไบนารีและส่งไปยังเธรด slave I / O

  6. Slave I / O thread ได้รับเหตุการณ์และเขียนไปยังจุดสิ้นสุดของไฟล์บันทึกการถ่ายทอด

  7. เมื่อเหตุการณ์เข้าสู่บันทึกการถ่ายทอดแล้วเธรด SQL ของ SQL จะเรียก
    ใช้เหตุการณ์เพื่อใช้การเปลี่ยนแปลงกับฐานข้อมูลบนสลาฟ

ในสถานการณ์สมมตินี้ต้นแบบไม่สนใจเกี่ยวกับสลาฟและไคลเอนต์เท่านั้นที่รู้ว่ามีบางอย่างผิดปกติบนสลาฟโดยการรันคำสั่ง "SHOW SLAVE STATUS" ด้วยตนเอง

กรณีของการจำลองแบบกึ่งซิงโครนัสลำดับของการดำเนินการอาจเป็นดังต่อไปนี้:

  1. ไคลเอ็นต์ส่งแบบสอบถาม SQL (ตัวอย่างเช่นแทรก) ไปยังต้นแบบโดยใช้ธุรกรรม

  2. Master ดำเนินการธุรกรรม ในกรณีที่ประสบความสำเร็จบันทึกจะถูกเก็บไว้ในดิสก์ แต่ไม่ได้ทำธุรกรรม

  3. Master บันทึกเหตุการณ์การแทรกในบันทึกไบนารีหลักหากต้นแบบไม่สามารถเก็บไว้ในบันทึกไบนารีธุรกรรมที่ถูกย้อนกลับและลูกค้าได้รับการตอบกลับเฉพาะในกรณีย้อนกลับ

  4. เนื่องจากความสำเร็จของการทำธุรกรรมบนมาสเตอร์เธรดดัมพ์บนมาสเตอร์อ่านเหตุการณ์จากบันทึกไบนารีและส่งไปยังเธรด slave I / O

  5. Slave I / O thread ได้รับเหตุการณ์และเขียนไปยังจุดสิ้นสุดของไฟล์บันทึกการถ่ายทอด

  6. Slave Acknowledges Master ของการบันทึกเหตุการณ์ในไฟล์บันทึกการถ่ายทอด

  7. Master กระทำการแทรกธุรกรรม

  8. ลูกค้าได้รับการตอบสนองจากต้นแบบ (สำเร็จ)

  9. เมื่อเหตุการณ์เข้าสู่บันทึกการถ่ายทอดแล้วเธรด slave SQL จะเรียก
    ใช้เหตุการณ์ เจ้านายและลูกค้าไม่รู้ว่าการดำเนินการนั้นสำเร็จหรือไม่

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

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

หากช่วงเวลาที่รอคอยไม่มีที่สิ้นสุดตำแหน่งบันทึกไบนารีหลักจะซิงค์กับตำแหน่งบันทึกการถ่ายทอดทาสเสมอโดยสมมติว่าการสืบค้นทั้งหมดบนสลาฟนั้นสำเร็จ สมมติฐานนี้เป็นจริงแค่ไหน?

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

ยาโคบนิคม


1

รอบคัดเลือก : ฉันไม่ใช่ผู้ใช้ MySQL ดังนั้นส่วนใหญ่นี่เป็นเพียงการวิจัยของฉันบนอินเทอร์เน็ต

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


ต่อที่นี่ :

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

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

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


ต่อที่นี่ :

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

โดยส่วนตัวฉันจะลองทำสิ่งนี้ถ้าทุกอย่างล้มเหลว ฉันสงสัยว่าปัญหาเกิดขึ้นจากระบบการจำลองแบบเธรดเดี่ยวมากกว่าเวลาแฝงเครือข่าย เครือข่ายปกติจะใช้เวลานานก่อนเครื่องหมาย 30 นาที (30 นาที?!)


บุ๊กมาร์กแสนอร่อยของ JHammerb มีลิงก์เชื่อมโยงมากมายสำหรับการจำลองแบบ mysql ที่คุณอาจต้องการตรวจสอบเช่นกัน

ฉันหวังว่าจะช่วย


1
คุณจะได้รับ +1 สำหรับการกล่าวถึงวิธีการเรพลิเคท MySQL แบบเธรดเดียว แต่ฉันต้องผ่านการรับรองของคุณดังนี้: การเรพลิเคท MySQL เป็นเธรดคู่โดยใช้เธรด I / O สำหรับดาวน์โหลดเหตุการณ์ SQL จาก Master สู่ Slave และ SQL Thread สำหรับการประมวลผล เหตุการณ์ SQL แบบโลคัลบน Slave ทว่าการส่งเหตุการณ์ SQL นั้นเป็นเธรดเดี่ยวซึ่งถูกต้องตามบริบทสำหรับคำถามนี้
RolandoMySQLDBA

2
BTW โปรดอย่าใช้ LIMIT กับคำสั่ง UPDATE และ DELETE เพราะลำดับของแถวที่กำลังปรับปรุงหรือลบอาจไม่เหมือนกันใน Slave เหมือนกับที่มีใน Master หากเป็นจริงข้อความเตือนเกี่ยวกับสิ่งนี้จะปรากฏขึ้นเช่น "Statement Not BinLog-Safe" ในบันทึกข้อผิดพลาด
RolandoMySQLDBA

โอ้จุดดีเกี่ยวกับการไม่ใช้ LIMIT กับ UPDATE และ DELETE ฉันจะแก้ไขคำตอบของฉันเพื่อลบ
ริชาร์ด
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.