RabbitMQ กับ Kafka: ความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง

RabbitMQ กับ Kafka: ความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง

В บทความล่าสุด เราดูที่การทำคลัสเตอร์ RabbitMQ เพื่อดูความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง ตอนนี้เรามาเจาะลึกลงไปใน Apache Kafka กันดีกว่า

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

RabbitMQ กับ Kafka: ความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง
ข้าว. 1. สี่ส่วนกระจายระหว่างสามโบรกเกอร์

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

RabbitMQ กับ Kafka: ความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง

ความล้มเหลวของพาร์ติชัน

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

นายหน้า 3 ออกจากเครือข่าย และได้รับเลือกผู้นำคนใหม่สำหรับส่วนที่ 2 ที่นายหน้า 2

RabbitMQ กับ Kafka: ความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง
ข้าว. 2. นายหน้า 3 เสียชีวิต และผู้ติดตามของเขาในนายหน้า 2 ได้รับเลือกให้เป็นผู้นำคนใหม่ของพาร์ติชัน 2

จากนั้นนายหน้า 1 ก็จากไปและส่วนที่ 1 ก็สูญเสียผู้นำไปเช่นกัน ซึ่งบทบาทของเขาส่งต่อไปยังนายหน้าคนที่ 2

RabbitMQ กับ Kafka: ความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง
ข้าว. 3. เหลือนายหน้าหนึ่งคน ผู้นำทั้งหมดอยู่ในโบรกเกอร์เดียวโดยไม่มีความซ้ำซ้อน

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

RabbitMQ กับ Kafka: ความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง
ข้าว. 4. ผู้นำยังคงอยู่ในนายหน้า 2

เมื่อนายหน้า 3 ปรากฏขึ้น เราจะกลับไปเป็นสามเรพลิกาต่อพาร์ติชั่น แต่ผู้นำทั้งหมดยังคงอยู่ในนายหน้า 2

RabbitMQ กับ Kafka: ความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง
ข้าว. 5. ตำแหน่งผู้นำที่ไม่สมดุลหลังจากการฟื้นฟูโบรกเกอร์ 1 และ 3

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

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

เพื่อแก้ไขปัญหานี้ Kafka มีสองทางเลือก:

  • ตัวเลือก auto.leader.rebalance.enable=true อนุญาตให้โหนดตัวควบคุมกำหนดผู้นำกลับไปเป็นแบบจำลองที่ต้องการโดยอัตโนมัติ และด้วยเหตุนี้จึงคืนค่าการกระจายแบบสม่ำเสมอ
  • ผู้ดูแลระบบสามารถรันสคริปต์ได้ kafka-preferred-replica-election.sh สำหรับการมอบหมายใหม่ด้วยตนเอง

RabbitMQ กับ Kafka: ความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง
ข้าว. 6. การจำลองหลังการปรับสมดุลใหม่

นี่เป็นความล้มเหลวในรูปแบบที่เรียบง่าย แต่ความเป็นจริงนั้นซับซ้อนกว่าแม้ว่าจะไม่มีอะไรซับซ้อนเกินไปก็ตาม ทั้งหมดนี้มาจากการจำลองแบบซิงโครไนซ์ (In-Sync Replicas, ISR)

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

ISR คือชุดของเรพลิกาของพาร์ติชันที่ถือว่า "ซิงโครไนซ์" (ซิงค์กัน) มีผู้นำแต่อาจจะไม่มีผู้ตาม ผู้ติดตามจะถือว่าซิงโครไนซ์หากได้ทำสำเนาข้อความของผู้นำทั้งหมดอย่างถูกต้องก่อนที่ช่วงเวลาจะหมดลง แบบจำลอง.lag.time.max.ms.

ผู้ติดตามจะถูกลบออกจากชุด ISR หาก:

  • ไม่ได้ร้องขอให้เลือกตามช่วงเวลา แบบจำลอง.lag.time.max.ms (สันนิษฐานว่าตายแล้ว)
  • ไม่สามารถอัปเดตได้ในช่วงเวลาดังกล่าว แบบจำลอง.lag.time.max.ms (ถือว่าช้า)

ผู้ติดตามทำการร้องขอการสุ่มตัวอย่างในช่วงเวลา แบบจำลอง.fetch.wait.max.msซึ่งมีค่าเริ่มต้นอยู่ที่ 500ms

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

  • acks=0 ไม่ได้ส่งการยืนยัน
  • acks=1 การยืนยันจะถูกส่งหลังจากที่ผู้นำได้เขียนข้อความลงในบันทึกในเครื่องของเขา
  • acks=all การยืนยันจะถูกส่งหลังจากเรพลิกาทั้งหมดใน ISR ได้เขียนข้อความลงในบันทึกในเครื่องแล้ว

ในคำศัพท์เฉพาะของ Kafka หาก ISR บันทึกข้อความแล้ว ข้อความนั้นจะถือว่า "มุ่งมั่น" Acks=all เป็นตัวเลือกที่ปลอดภัยที่สุด แต่ยังเพิ่มความล่าช้าอีกด้วย ลองดูตัวอย่างความล้มเหลวสองตัวอย่างและวิธีที่ตัวเลือก 'acks' ต่างๆ โต้ตอบกับแนวคิด ISR

Acks=1 และ ISR

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

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

RabbitMQ กับ Kafka: ความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง
ข้าว. 7. ISR พร้อมแบบจำลองสามชุด

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

RabbitMQ กับ Kafka: ความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง
ข้าว. 8. ข้อความจะหายไปเมื่อเกิดปัญหา

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

RabbitMQ กับ Kafka: ความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง
ข้าว. 9. การส่งข้อความจะดำเนินต่อไปหลังจากพักช่วงสั้นๆ

นายหน้า 3 ยังตามหลังอยู่อีก มันส่งคำขอดึงข้อมูล แต่ไม่สามารถซิงค์ได้ นี่อาจเป็นเพราะการเชื่อมต่อเครือข่ายที่ช้าระหว่างโบรกเกอร์ ปัญหาการจัดเก็บข้อมูล ฯลฯ มันถูกลบออกจาก ISR ตอนนี้ ISR ประกอบด้วยแบบจำลองเดียว - ผู้นำ! ผู้ผลิตยังคงส่งข้อความและรับคำยืนยันต่อไป

RabbitMQ กับ Kafka: ความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง
ข้าว. 10. ผู้ติดตามบนโบรกเกอร์ 3 จะถูกลบออกจาก ISR

นายหน้า 1 ล้มลง และบทบาทผู้นำตกเป็นของนายหน้า 3 โดยสูญเสียข้อความไป 15286 ข้อความ! ผู้ผลิตได้รับข้อความแสดงข้อผิดพลาดในการเชื่อมต่อ การเปลี่ยนไปสู่ผู้นำนอก ISR เกิดขึ้นได้เนื่องจากการตั้งค่าเท่านั้น unclean.leader.election.enable=true. ถ้าจะติดตั้งใน เท็จจากนั้นการเปลี่ยนแปลงจะไม่เกิดขึ้น และคำขออ่านและเขียนทั้งหมดจะถูกปฏิเสธ ในกรณีนี้ เรารอให้โบรกเกอร์ 1 กลับมาพร้อมกับข้อมูลที่ครบถ้วนในแบบจำลอง ซึ่งจะเข้ามาเป็นผู้นำอีกครั้ง

RabbitMQ กับ Kafka: ความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง
ข้าว. 11.นายหน้า1ล้ม. เมื่อเกิดความล้มเหลว ข้อความจำนวนมากจะสูญหาย

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

RabbitMQ กับ Kafka: ความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง
ข้าว. 12. หลังจากพักช่วงสั้นๆ ข้อความจะถูกส่งอีกครั้งไปที่ส่วนที่ 0

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

Acks=ทั้งหมด และ ISR

เรามาทำซ้ำสถานการณ์นี้อีกครั้ง แต่ด้วย อั๊ค=ทั้งหมด. โบรกเกอร์ 3 มีเวลาแฝงเฉลี่ยสี่วินาที ผู้ผลิตส่งข้อความด้วย อั๊ค=ทั้งหมดและตอนนี้ไม่ได้รับการตอบกลับอย่างรวดเร็ว ผู้นำรอให้ข้อความถูกบันทึกโดยแบบจำลองทั้งหมดใน ISR

RabbitMQ กับ Kafka: ความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง
ข้าว. 13. ISR พร้อมแบบจำลองสามชุด อันหนึ่งช้า ส่งผลให้การบันทึกล่าช้า

หลังจากการหน่วงเวลาเพิ่มเติมสี่วินาที นายหน้า 2 จะส่งการตอบรับ ขณะนี้แบบจำลองทั้งหมดได้รับการอัปเดตอย่างสมบูรณ์แล้ว

RabbitMQ กับ Kafka: ความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง
ข้าว. 14. แบบจำลองทั้งหมดจะบันทึกข้อความและส่ง ack

ตอนนี้นายหน้า 3 ล้าหลังกว่าและถูกลบออกจาก ISR เวลาแฝงจะลดลงอย่างมากเนื่องจากไม่มีการจำลองที่ช้าเหลืออยู่ใน ISR ตอนนี้โบรกเกอร์ 2 รอเฉพาะโบรกเกอร์ 1 เท่านั้น และเขามีความล่าช้าโดยเฉลี่ย 500 ms

RabbitMQ กับ Kafka: ความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง
ข้าว. 15. แบบจำลองบนโบรกเกอร์ 3 ถูกลบออกจาก ISR

จากนั้นนายหน้า 2 ล้มลงและผู้นำส่งต่อไปยังนายหน้า 1 โดยไม่สูญเสียข้อความ

RabbitMQ กับ Kafka: ความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง
ข้าว. 16.นายหน้า2ตก

ผู้ผลิตพบผู้นำคนใหม่และเริ่มส่งข้อความถึงเขา เวลาแฝงจะลดลงอีกเนื่องจากขณะนี้ ISR ประกอบด้วยแบบจำลองเดียว! ดังนั้นทางเลือก อั๊ค=ทั้งหมด ไม่เพิ่มความซ้ำซ้อน

RabbitMQ กับ Kafka: ความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง
ข้าว. 17. การจำลองบนโบรกเกอร์ 1 เป็นผู้นำโดยไม่สูญเสียข้อความ

จากนั้นโบรกเกอร์ 1 ขัดข้อง และลูกค้าเป้าหมายไปที่โบรกเกอร์ 3 โดยมีข้อความสูญหาย 14238 ข้อความ!

RabbitMQ กับ Kafka: ความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง
ข้าว. 18. นายหน้า 1 เสียชีวิตและการเปลี่ยนผู้นำด้วยการตั้งค่าที่ไม่สะอาดส่งผลให้ข้อมูลสูญหายอย่างกว้างขวาง

เราไม่สามารถติดตั้งตัวเลือกนี้ได้ ไม่สะอาดผู้นำการเลือกตั้งเปิดใช้งาน สู่ความหมาย จริง. โดยค่าเริ่มต้นจะเท่ากัน เท็จ. การตั้งค่า อั๊ค=ทั้งหมด с unclean.leader.election.enable=true ให้การเข้าถึงด้วยความปลอดภัยของข้อมูลเพิ่มเติม แต่อย่างที่คุณเห็น เรายังคงสูญเสียข้อความได้

แต่ถ้าเราต้องการเพิ่มความปลอดภัยของข้อมูลล่ะ? คุณสามารถใส่ unclean.leader.election.enable = เท็จแต่สิ่งนี้ไม่ได้ปกป้องเราจากการสูญเสียข้อมูลเสมอไป หากผู้นำล้มเหลวและนำข้อมูลไปด้วย ข้อความจะยังคงสูญหาย และความพร้อมใช้งานจะสูญหายไปจนกว่าผู้ดูแลระบบจะกู้คืนสถานการณ์กลับคืนมา

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

Acks=all, min.insync.replicas และ ISR

ด้วยการกำหนดค่าหัวข้อ min.insync.replica เรากำลังเพิ่มระดับความปลอดภัยของข้อมูล เรามาดูส่วนสุดท้ายของสถานการณ์ก่อนหน้านี้อีกครั้ง แต่คราวนี้ด้วย min.insync.replicas=2.

ดังนั้นโบรกเกอร์ 2 จึงมีผู้นำแบบจำลองและผู้ติดตามของโบรกเกอร์ 3 จะถูกลบออกจาก ISR

RabbitMQ กับ Kafka: ความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง
ข้าว. 19. ISR จากสองแบบจำลอง

นายหน้า 2 ล้มลงและความเป็นผู้นำส่งต่อไปยังนายหน้า 1 โดยไม่สูญเสียข้อความ แต่ตอนนี้ ISR ประกอบด้วยแบบจำลองเดียวเท่านั้น ซึ่งไม่ตรงตามจำนวนขั้นต่ำในการรับบันทึก ดังนั้นนายหน้าจึงตอบสนองต่อความพยายามในการเขียนโดยมีข้อผิดพลาด จำลองไม่เพียงพอ.

RabbitMQ กับ Kafka: ความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง
ข้าว. 20. จำนวน ISR ต่ำกว่าที่ระบุไว้ใน min.insync.replicas หนึ่งอัน

การกำหนดค่านี้เสียสละความพร้อมใช้งานเพื่อความสอดคล้อง ก่อนที่จะตอบรับข้อความ เราตรวจสอบให้แน่ใจว่าได้เขียนข้อความลงในแบบจำลองอย่างน้อยสองรายการ สิ่งนี้ทำให้ผู้ผลิตมีความมั่นใจมากขึ้น ในที่นี้ ข้อความสูญหายจะเกิดขึ้นได้ก็ต่อเมื่อการจำลองสองรายการล้มเหลวพร้อมกันในช่วงเวลาสั้นๆ จนกว่าข้อความจะถูกจำลองไปยังผู้ติดตามเพิ่มเติม ซึ่งไม่น่าเป็นไปได้ แต่ถ้าคุณหวาดระแวงมาก คุณสามารถตั้งค่าปัจจัยการจำลองเป็น 5 และ min.insync.replica โดย 3 ที่นี่สามโบรกเกอร์ต้องล้มพร้อมกันจึงจะเสียสถิติ! แน่นอนว่าคุณต้องจ่ายค่าความน่าเชื่อถือนี้โดยมีเวลาแฝงเพิ่มเติม

เมื่อการเข้าถึงเป็นสิ่งจำเป็นเพื่อความปลอดภัยของข้อมูล

เช่นเดียวกับใน กรณีที่มี RabbitMQบางครั้งการเข้าถึงก็จำเป็นสำหรับการรักษาความปลอดภัยข้อมูล นี่คือสิ่งที่คุณต้องคำนึงถึง:

  • ผู้เผยแพร่สามารถส่งคืนข้อผิดพลาดและให้บริการอัปสตรีมหรือผู้ใช้ลองอีกครั้งในภายหลังได้หรือไม่
  • ผู้เผยแพร่สามารถบันทึกข้อความไว้ในเครื่องหรือในฐานข้อมูลเพื่อลองอีกครั้งในภายหลังได้หรือไม่

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

ความหมายของ ISR

ชุด ISR ช่วยให้คุณสามารถเลือกสมดุลที่เหมาะสมระหว่างความปลอดภัยของข้อมูลและเวลาแฝงได้ ตัวอย่างเช่น ตรวจสอบความพร้อมใช้งานในกรณีที่แบบจำลองส่วนใหญ่ล้มเหลว การลดผลกระทบของแบบจำลองที่ไม่ทำงานหรือช้าในแง่ของเวลาแฝง

เราเลือกความหมายเอง แบบจำลอง.lag.time.max.ms ตามความต้องการของคุณ โดยพื้นฐานแล้ว พารามิเตอร์นี้หมายถึงความล่าช้าที่เรายินดียอมรับเมื่อใด อั๊ค=ทั้งหมด. ค่าเริ่มต้นคือสิบวินาที หากมันยาวเกินไปสำหรับคุณ คุณสามารถลดมันลงได้ จากนั้นความถี่ของการเปลี่ยนแปลงใน ISR จะเพิ่มขึ้น เนื่องจากผู้ติดตามจะถูกลบออกและเพิ่มบ่อยขึ้น

RabbitMQ เป็นเพียงชุดมิเรอร์ที่ต้องจำลอง มิเรอร์ที่ช้าทำให้เกิดเวลาแฝงเพิ่มเติม และมิเรอร์ที่ไม่ทำงานสามารถรอจนกว่าแพ็กเก็ตที่ตรวจสอบความพร้อมใช้งานของแต่ละโหนด (เน็ตติ๊ก) เพื่อตอบสนอง ISR เป็นวิธีที่น่าสนใจในการหลีกเลี่ยงปัญหาเวลาแฝงเหล่านี้ แต่เราเสี่ยงที่จะสูญเสียความซ้ำซ้อนเนื่องจาก ISR สามารถลดขนาดลงเหลือเพียงผู้นำเท่านั้น เพื่อหลีกเลี่ยงความเสี่ยงนี้ ให้ใช้การตั้งค่า min.insync.replica.

รับประกันการเชื่อมต่อไคลเอนต์

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

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

สถาปัตยกรรมฉันทามติของคาฟคา

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

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

Zookeeper เก็บสถานะของคลัสเตอร์:

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

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

ตัวอย่างเช่น เรามาเริ่มหัวข้อใหม่ที่มีพาร์ติชั่น 3 พาร์ติชั่นและปัจจัยการจำลองที่ XNUMX คอนโทรลเลอร์จะต้องเลือกผู้นำสำหรับแต่ละพาร์ติชั่น โดยพยายามกระจายผู้นำอย่างเหมาะสมที่สุดระหว่างโบรกเกอร์

สำหรับตัวควบคุมแต่ละส่วน:

  • อัปเดตข้อมูลใน Zookeeper เกี่ยวกับ ISR และผู้นำ
  • ส่ง LeaderAndISRCommand ไปยังโบรกเกอร์แต่ละรายที่โฮสต์แบบจำลองของพาร์ติชันนี้ โดยแจ้งให้โบรกเกอร์ทราบเกี่ยวกับ ISR และผู้นำ

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

ผู้นำแต่ละคนมีหน้าที่รับผิดชอบในการสรรหา ISR การตั้งค่า แบบจำลอง.lag.time.max.ms กำหนดว่าใครจะเข้าไปที่นั่น เมื่อ ISR เปลี่ยนแปลง ผู้นำจะส่งข้อมูลใหม่ไปยัง Zookeeper

Zookeeper จะได้รับแจ้งเสมอถึงการเปลี่ยนแปลงใดๆ เพื่อที่ว่าในกรณีที่เกิดความล้มเหลว ฝ่ายบริหารจะเปลี่ยนไปสู่ผู้นำคนใหม่ได้อย่างราบรื่น

RabbitMQ กับ Kafka: ความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง
ข้าว. 21. ฉันทามติของคาฟคา

โปรโตคอลการจำลองแบบ

การทำความเข้าใจรายละเอียดของการจำลองแบบจะช่วยให้คุณเข้าใจสถานการณ์การสูญหายของข้อมูลที่อาจเกิดขึ้นได้ดีขึ้น

การสุ่มตัวอย่างแบบสอบถาม Log End Offset (LEO) และ Highwater Mark (HW)

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

ผู้นำและผู้ติดตามทั้งหมดจะบันทึกฉลาก Log End Offset (LEO) และ Highwater (HW) เครื่องหมาย LEO จะจัดเก็บออฟเซ็ตของข้อความสุดท้ายในโลคัลเรพลิกา และ HW จะเก็บออฟเซ็ตของคอมมิตสุดท้าย โปรดจำไว้ว่าสำหรับสถานะการคอมมิต ข้อความจะต้องคงอยู่ในแบบจำลอง ISR ทั้งหมด ซึ่งหมายความว่า LEO มักจะนำหน้า HW เล็กน้อย

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

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

ความล้มเหลวของผู้นำ

เมื่อผู้นำล้ม Zookeeper จะแจ้งเตือนผู้ควบคุม และเลือกแบบจำลองผู้นำใหม่ ผู้นำคนใหม่กำหนดเครื่องหมาย HW ใหม่ตาม LEO ของเขา ผู้ติดตามจะได้รับข้อมูลเกี่ยวกับผู้นำคนใหม่ ขึ้นอยู่กับเวอร์ชันของ Kafka ผู้ติดตามจะเลือกหนึ่งในสองสถานการณ์:

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

ผู้ติดตามอาจจำเป็นต้องตัดทอนบันทึกด้วยเหตุผลดังต่อไปนี้:

  • เมื่อผู้นำล้มเหลว ผู้ติดตามคนแรกในชุด ISR ที่ลงทะเบียนกับ Zookeeper จะชนะการเลือกตั้งและกลายเป็นผู้นำ ผู้ติดตามทุกคนใน ISR แม้จะถือว่า "ตรงกัน" ก็อาจไม่ได้รับสำเนาข้อความทั้งหมดจากอดีตผู้นำ เป็นไปได้ทั้งหมดว่าผู้ติดตามที่นำเสนอไม่มีสำเนาที่เป็นปัจจุบันที่สุด Kafka รับประกันว่าไม่มีความแตกต่างระหว่างแบบจำลอง ดังนั้น เพื่อหลีกเลี่ยงความคลาดเคลื่อน ผู้ติดตามแต่ละคนจะต้องตัดบันทึกของตนให้เหลือตามค่า HW ของผู้นำคนใหม่ในเวลาที่มีการเลือกตั้ง นี่เป็นอีกเหตุผลหนึ่งว่าทำไมการตั้งค่า อั๊ค=ทั้งหมด สำคัญมากสำหรับความสม่ำเสมอ
  • ข้อความจะถูกเขียนลงดิสก์เป็นระยะ หากโหนดคลัสเตอร์ทั้งหมดล้มเหลวในเวลาเดียวกัน เรพลิกาที่มีออฟเซ็ตต่างกันจะถูกจัดเก็บไว้ในดิสก์ เป็นไปได้ว่าเมื่อโบรกเกอร์กลับมาออนไลน์ ผู้นำคนใหม่ที่ได้รับเลือกจะตามหลังผู้ติดตามของเขา เพราะเขาถูกบันทึกไว้ในดิสก์ก่อนคนอื่นๆ

การรวมตัวใหม่กับคลัสเตอร์

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

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

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

สูญเสียการเชื่อมต่อ

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

ด้านล่างนี้คือสถานการณ์ความล้มเหลวในการเชื่อมต่อหลายประการ:

  • สถานการณ์ที่ 1: ผู้ติดตามไม่เห็นผู้นำ แต่ยังเห็นผู้ดูแลสวนสัตว์
  • สถานการณ์ที่ 2: ผู้นำไม่เห็นผู้ติดตามใดๆ แต่ยังคงเห็น Zookeeper
  • สถานการณ์ที่ 3: ผู้ติดตามมองเห็นผู้นำ แต่ไม่เห็นผู้ดูแลสวนสัตว์
  • สถานการณ์ที่ 4: ผู้นำมองเห็นผู้ติดตาม แต่ไม่เห็นผู้ดูแลสวนสัตว์
  • สถานการณ์ที่ 5: ผู้ติดตามแยกจากทั้งโหนด Kafka และ Zookeeper โดยสิ้นเชิง
  • สถานการณ์ที่ 6: ผู้นำแยกจากทั้งโหนด Kafka และ Zookeeper โดยสิ้นเชิง
  • สถานการณ์ที่ 7: โหนดตัวควบคุม Kafka ไม่สามารถมองเห็นโหนด Kafka อื่นได้
  • สถานการณ์ที่ 8: ตัวควบคุม Kafka ไม่เห็น Zookeeper

แต่ละสถานการณ์มีพฤติกรรมของตัวเอง

สถานการณ์ที่ 1: ผู้ติดตามไม่เห็นผู้นำ แต่ยังเห็น Zookeeper

RabbitMQ กับ Kafka: ความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง
ข้าว. 22. สถานการณ์ที่ 1: ISR ของแบบจำลองสามรายการ

ความล้มเหลวในการเชื่อมต่อแยกโบรกเกอร์ 3 ออกจากโบรกเกอร์ 1 และ 2 แต่ไม่ใช่จาก Zookeeper นายหน้า 3 ไม่สามารถส่งคำขอดึงข้อมูลได้อีกต่อไป หลังจากเวลาผ่านไป แบบจำลอง.lag.time.max.ms มันถูกลบออกจาก ISR และไม่มีส่วนร่วมในการส่งข้อความ เมื่อการเชื่อมต่อได้รับการกู้คืนแล้ว ระบบจะดำเนินการดึงข้อมูลคำขอต่อและเข้าร่วม ISR เมื่อตามทันผู้นำ ผู้ดูแลสัตว์จะยังคงได้รับปิงต่อไปและถือว่านายหน้ายังมีชีวิตอยู่และสบายดี

RabbitMQ กับ Kafka: ความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง
ข้าว. 23. สถานการณ์ที่ 1: นายหน้าจะถูกลบออกจาก ISR หากไม่ได้รับการร้องขอการดึงข้อมูลภายในช่วงเวลา

ไม่มีการระงับแบบแยกสมองหรือโหนดเหมือนใน RabbitMQ ความซ้ำซ้อนจะลดลงแทน

สถานการณ์ที่ 2: ผู้นำไม่เห็นผู้ติดตามใดๆ แต่ยังคงเห็น Zookeeper

RabbitMQ กับ Kafka: ความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง
ข้าว. 24. สถานการณ์ที่ 2. ผู้นำและผู้ติดตามสองคน

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

RabbitMQ กับ Kafka: ความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง
ข้าว. 25. สถานการณ์ที่ 2. ISR หดตัวลงเหลือเพียงผู้นำเท่านั้น

สถานการณ์ที่ 3 ผู้ติดตามมองเห็นผู้นำ แต่ไม่เห็นผู้ดูแลสัตว์

ผู้ติดตามจะถูกแยกออกจาก Zookeeper แต่ไม่ใช่จากนายหน้าที่มีผู้นำ เป็นผลให้ผู้ติดตามยังคงส่งคำขอดึงข้อมูลและเป็นสมาชิกของ ISR Zookeeper ไม่ได้รับ Ping และลงทะเบียนการขัดข้องของนายหน้าอีกต่อไป แต่เนื่องจากเป็นเพียงผู้ติดตามเท่านั้น จึงไม่มีผลกระทบใด ๆ หลังจากการกู้คืน

RabbitMQ กับ Kafka: ความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง
ข้าว. 26. สถานการณ์ที่ 3: ผู้ติดตามยังคงส่งคำขอดึงข้อมูลไปยังผู้นำ

สถานการณ์ที่ 4 ผู้นำมองเห็นผู้ติดตาม แต่ไม่เห็นผู้ดูแลสัตว์

RabbitMQ กับ Kafka: ความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง
ข้าว. 27. สถานการณ์ที่ 4. ผู้นำและผู้ติดตามสองคน

ผู้นำถูกแยกออกจาก Zookeeper แต่ไม่ใช่จากนายหน้าที่มีผู้ติดตาม

RabbitMQ กับ Kafka: ความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง
ข้าว. 28. สถานการณ์ที่ 4: ผู้นำที่ถูกโดดเดี่ยวจากผู้ดูแลสวนสัตว์

หลังจากนั้นสักพัก Zookeeper จะลงทะเบียนความล้มเหลวของนายหน้าและแจ้งให้ผู้ควบคุมทราบ เขาจะเลือกผู้นำคนใหม่ในหมู่ผู้ติดตามของเขา อย่างไรก็ตามผู้นำเดิมจะยังคงคิดว่าเป็นผู้นำและจะรับผลงานจากต่อไป อั๊ค=1. ผู้ติดตามจะไม่ส่งคำขอให้เขาอีกต่อไป ดังนั้นเขาจะถือว่าคำขอเหล่านั้นตายแล้วและพยายามย่อ ISR ให้เหลือเพียงตัวมันเอง แต่เนื่องจากมันไม่มีความเกี่ยวข้องกับ Zookeeper จึงไม่สามารถทำเช่นนี้ได้ และเมื่อถึงจุดนั้นก็จะปฏิเสธที่จะยอมรับการเข้าร่วมเพิ่มเติม

ข้อความ อั๊ค=ทั้งหมด จะไม่ได้รับการตอบรับเนื่องจาก ISR เปิดใช้งานแบบจำลองทั้งหมดก่อน และข้อความไปไม่ถึงพวกเขา เมื่อผู้นำดั้งเดิมพยายามลบพวกเขาออกจาก ISR ก็จะไม่สามารถทำได้และจะหยุดรับข้อความใดๆ เลย

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

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

สถานการณ์ที่ 5: ผู้ติดตามแยกจากทั้งโหนด Kafka และ Zookeeper โดยสิ้นเชิง

ผู้ติดตามถูกแยกออกจากทั้งโหนด Kafka และ Zookeeper โดยสิ้นเชิง เขาเพียงแต่ถอนตัวเองออกจาก ISR จนกว่าเครือข่ายจะได้รับการกู้คืน จากนั้นจึงติดต่อกับคนอื่นๆ

RabbitMQ กับ Kafka: ความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง
ข้าว. 30. สถานการณ์ที่ 5: ผู้ติดตามที่แยกออกมาจะถูกลบออกจาก ISR

สถานการณ์ที่ 6: ผู้นำแยกจากทั้งโหนด Kafka และ Zookeeper โดยสิ้นเชิง

RabbitMQ กับ Kafka: ความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง
ข้าว. 31. สถานการณ์ที่ 6. ผู้นำและผู้ติดตามสองคน

ผู้นำถูกแยกออกจากผู้ติดตาม ผู้ควบคุม และผู้ดูแลสวนสัตว์โดยสิ้นเชิง ในช่วงเวลาสั้นๆ จะยังคงเปิดรับผลงานจาก อั๊ค=1.

RabbitMQ กับ Kafka: ความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง
ข้าว. 32. สถานการณ์ที่ 6: แยกผู้นำออกจากโหนด Kafka และ Zookeeper อื่นๆ

ไม่ได้รับคำขอหลังจากหมดอายุ แบบจำลอง.lag.time.max.msจะพยายามย่อขนาด ISR ให้กับตัวเอง แต่จะทำไม่ได้เนื่องจากไม่มีการสื่อสารกับ Zookeeper จะหยุดรับการเขียน

ในขณะเดียวกัน Zookeeper จะทำเครื่องหมายนายหน้าที่ถูกแยกออกไปว่าตายแล้ว และผู้ควบคุมจะเลือกผู้นำคนใหม่

RabbitMQ กับ Kafka: ความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง
ข้าว. 33. สถานการณ์ที่ 6. ผู้นำสองคน

ผู้นำเดิมอาจยอมรับรายการเป็นเวลาสองสามวินาที แต่จากนั้นก็หยุดรับข้อความใดๆ ลูกค้าจะได้รับการอัปเดตทุกๆ 60 วินาทีด้วยข้อมูลเมตาล่าสุด พวกเขาจะได้รับแจ้งการเปลี่ยนแปลงผู้นำและจะเริ่มส่งรายการไปยังผู้นำคนใหม่

RabbitMQ กับ Kafka: ความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง
ข้าว. 34. สถานการณ์ที่ 6: ผู้ผลิตเปลี่ยนมาเป็นผู้นำคนใหม่

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

RabbitMQ กับ Kafka: ความทนทานต่อข้อผิดพลาดและความพร้อมใช้งานสูง
ข้าว. 35. สถานการณ์ที่ 6: ผู้นำเดิมกลายเป็นผู้ตามหลังจากกู้คืนการเชื่อมต่อเครือข่ายแล้ว

ในสถานการณ์นี้ การแยกทางลอจิคัลอาจเกิดขึ้นในช่วงเวลาสั้นๆ แต่จะเกิดขึ้นต่อเมื่อเท่านั้น อั๊ค=1 и min.insync.replica 1. การแยกทางลอจิคัลจะสิ้นสุดลงโดยอัตโนมัติหลังจากที่เครือข่ายได้รับการกู้คืน เมื่อผู้นำเดิมตระหนักว่าเขาไม่ได้เป็นผู้นำอีกต่อไป หรือเมื่อลูกค้าทั้งหมดตระหนักว่าผู้นำมีการเปลี่ยนแปลง และเริ่มเขียนถึงผู้นำคนใหม่ แล้วแต่ว่าเหตุการณ์ใดจะเกิดขึ้นก่อน ไม่ว่าในกรณีใดข้อความบางส่วนจะหายไปแต่เฉพาะกับ อั๊ค=1.

มีอีกสถานการณ์หนึ่งของสถานการณ์นี้ที่ก่อนที่เครือข่ายจะแยก ผู้ติดตามถูกทิ้งไว้ข้างหลังและผู้นำบีบอัด ISR ไว้เพียงตัวเขาเอง จากนั้นจะถูกแยกออกจากกันเนื่องจากขาดการเชื่อมต่อ มีการเลือกตั้งผู้นำคนใหม่ แต่ผู้นำเดิมยังคงยอมรับการเข้าร่วมด้วยซ้ำ อั๊ค=ทั้งหมดเพราะไม่มีใครใน ISR อีกแล้วนอกจากเขา บันทึกเหล่านี้จะหายไปเมื่อเครือข่ายได้รับการกู้คืน วิธีเดียวที่จะหลีกเลี่ยงตัวเลือกนี้คือ min.insync.replicas = 2.

สถานการณ์ที่ 7: โหนดตัวควบคุม Kafka ไม่เห็นโหนด Kafka อื่น

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

สถานการณ์ที่ 8: ตัวควบคุม Kafka ไม่เห็น Zookeeper

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

ข้อสรุปจากสถานการณ์

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

หากผู้นำถูกแยกออกจาก Zookeeper เนื่องจากขาดการเชื่อมต่อ อาจส่งผลให้ข้อความสูญหายได้ อั๊ค=1. การขาดการสื่อสารกับ Zookeeper ทำให้เกิดการแตกแยกทางตรรกะในช่วงสั้นๆ กับผู้นำทั้งสอง ปัญหานี้แก้ไขได้ด้วยพารามิเตอร์ อั๊ค=ทั้งหมด.

พารามิเตอร์ min.insync.replica ออกเป็นสองแบบจำลองขึ้นไปให้การรับประกันเพิ่มเติมว่าสถานการณ์ระยะสั้นดังกล่าวจะไม่ส่งผลให้ข้อความสูญหายดังในสถานการณ์ที่ 6

สรุปข้อความที่หายไป

มาดูวิธีสูญเสียข้อมูลใน Kafka กัน:

  • ความล้มเหลวของผู้นำใดๆ หากข้อความได้รับการยืนยันโดยใช้ อั๊ค=1
  • การเปลี่ยนแปลงความเป็นผู้นำที่ไม่สะอาดใดๆ กล่าวคือ ไปสู่ผู้ตามนอก ISR แม้กระทั่งกับก็ตาม อั๊ค=ทั้งหมด
  • แยกผู้นำออกจาก Zookeeper หากข้อความได้รับการยืนยันว่าใช้ อั๊ค=1
  • ความโดดเดี่ยวโดยสิ้นเชิงของผู้นำที่ได้ย่อกลุ่ม ISR ลงเหลือเพียงตัวเขาเอง ข้อความทั้งหมดจะหายไปด้วยซ้ำ อั๊ค=ทั้งหมด. นี่เป็นเรื่องจริงก็ต่อเมื่อ min.insync.replicas=1.
  • ความล้มเหลวพร้อมกันของโหนดพาร์ติชันทั้งหมด เนื่องจากข้อความได้รับการยอมรับจากหน่วยความจำ บางข้อความจึงอาจยังไม่ได้เขียนลงดิสก์ หลังจากรีบูตเซิร์ฟเวอร์ ข้อความบางส่วนอาจหายไป

การเปลี่ยนผ่านของผู้นำที่ไม่บริสุทธิ์สามารถหลีกเลี่ยงได้โดยการห้ามหรือรับรองว่ามีความซ้ำซ้อนอย่างน้อยสองครั้ง การกำหนดค่าที่ทนทานที่สุดคือการรวมกัน อั๊ค=ทั้งหมด и min.insync.replica มากกว่า 1

การเปรียบเทียบโดยตรงของความน่าเชื่อถือของ RabbitMQ และ Kafka

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

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

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

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

เดิมพันของ Kafka ก็คือหากข้อความถูกจัดเก็บไว้หลายโหนด จะสามารถรับทราบข้อความได้ทันทีที่เข้าถึงหน่วยความจำ ด้วยเหตุนี้ จึงมีความเสี่ยงที่จะสูญเสียข้อความทุกประเภท (แม้กระทั่ง อั๊ค=ทั้งหมด, min.insync.replicas=2) ในกรณีที่เกิดความล้มเหลวพร้อมกัน

โดยรวมแล้ว Kafka แสดงให้เห็นถึงประสิทธิภาพของซอฟต์แวร์ที่ดีกว่า และได้รับการออกแบบตั้งแต่ต้นจนจบสำหรับคลัสเตอร์ สามารถเพิ่มจำนวนผู้ติดตามเป็น 11 คนได้หากจำเป็นเพื่อความน่าเชื่อถือ ปัจจัยการจำลอง 5 และจำนวนเรพลิกาขั้นต่ำในการซิงโครไนซ์ min.insync.replicas=3 จะทำให้ข้อความสูญหายเป็นเหตุการณ์ที่หายากมาก หากโครงสร้างพื้นฐานของคุณสามารถรองรับอัตราส่วนการจำลองและระดับของความซ้ำซ้อนนี้ คุณสามารถเลือกตัวเลือกนี้ได้

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

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

สุดท้ายนี้ อย่าลืมเกี่ยวกับข้อบกพร่องจำนวนหนึ่งในกลไกการทำคลัสเตอร์และการจำลองแบบของทั้ง RabbitMQ และ Kafka เมื่อเวลาผ่านไป ระบบมีความสมบูรณ์และมีเสถียรภาพมากขึ้น แต่ไม่มีข้อความใดที่จะปลอดภัย 100% จากการสูญเสีย! นอกจากนี้ ยังเกิดอุบัติเหตุขนาดใหญ่ในศูนย์ข้อมูลอีกด้วย!

หากฉันพลาดบางสิ่งบางอย่าง ทำผิดพลาด หรือคุณไม่เห็นด้วยกับประเด็นใดๆ โปรดเขียนความคิดเห็นหรือติดต่อฉันได้

ฉันมักถูกถามว่า “จะเลือกอะไรดี Kafka หรือ RabbitMQ?” “แพลตฟอร์มไหนดีกว่ากัน” ความจริงก็คือมันขึ้นอยู่กับสถานการณ์ ประสบการณ์ปัจจุบัน ฯลฯ ของคุณจริงๆ ฉันลังเลที่จะแสดงความคิดเห็นเพราะมันจะง่ายเกินไปที่จะแนะนำแพลตฟอร์มเดียวสำหรับทุกกรณีการใช้งานและข้อจำกัดที่เป็นไปได้ ฉันเขียนบทความชุดนี้เพื่อให้คุณสามารถสร้างความคิดเห็นของคุณเองได้

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

ฉันเห็นเทคโนโลยีอื่นๆ ที่ขาดความน่าเชื่อถือและการรับประกันการสั่งซื้อ จากนั้นฉันก็ดูที่ RabbitMQ และ Kafka และตระหนักถึงคุณค่าอันเหลือเชื่อของทั้งสองระบบนี้

ที่มา: will.com

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