ทำความเข้าใจเกี่ยวกับโบรกเกอร์ข้อความ เรียนรู้กลไกการส่งข้อความด้วย ActiveMQ และ Kafka บทที่ 3 คาฟคา

ความต่อเนื่องของการแปลหนังสือเล่มเล็ก:
ทำความเข้าใจเกี่ยวกับโบรกเกอร์ข้อความ
ผู้แต่ง: Jakub Korab ผู้จัดพิมพ์: O'Reilly Media, Inc. วันที่เผยแพร่: มิถุนายน 2017 ISBN: 9781492049296

ส่วนที่แปลก่อนหน้านี้: ทำความเข้าใจเกี่ยวกับโบรกเกอร์ข้อความ เรียนรู้กลไกการส่งข้อความด้วย ActiveMQ และ Kafka บทที่ 1 บทนำ

บทที่ 3

Kafka

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

ด้วยเป้าหมายสูงสุดนี้ ข้อกำหนดอื่นๆ จึงเกิดขึ้นเองตามธรรมชาติ คาฟคาควร:

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

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

โมเดลปลายทางแบบครบวงจร

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

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

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

คำว่า "บันทึก" และ "ตัวชี้" ไม่ปรากฏใน เอกสารของคาฟคา. คำศัพท์ที่รู้จักกันดีเหล่านี้ใช้ที่นี่เพื่อช่วยให้เข้าใจ

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

ทำความเข้าใจเกี่ยวกับโบรกเกอร์ข้อความ เรียนรู้กลไกการส่งข้อความด้วย ActiveMQ และ Kafka บทที่ 3 คาฟคา
รูปที่ 3-1 คาฟคาพาร์ติชัน

เมื่อโปรดิวเซอร์ส่งข้อความไปยังหัวข้อ Kafka ผู้ผลิตจะเป็นผู้ตัดสินใจว่าจะส่งข้อความไปยังพาร์ติชันใด เราจะดูรายละเอียดเพิ่มเติมในภายหลัง

การอ่านข้อความ

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

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

ปัญหาการอ่านสามารถแสดงได้ดังนี้

  • หัวข้อมีหลายพาร์ติชัน
  • ผู้บริโภคหลายกลุ่มสามารถใช้หัวข้อได้ในเวลาเดียวกัน
  • กลุ่มผู้บริโภคสามารถมีอินสแตนซ์แยกกันได้หลายรายการ

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

ผู้บริโภคและกลุ่มผู้บริโภค

มาเป็นจุดเริ่มต้นหัวข้อที่มีหนึ่งพาร์ติชัน (รูปที่ 3 2-).

ทำความเข้าใจเกี่ยวกับโบรกเกอร์ข้อความ เรียนรู้กลไกการส่งข้อความด้วย ActiveMQ และ Kafka บทที่ 3 คาฟคา
รูปที่ 3-2 ผู้บริโภคอ่านจากพาร์ติชัน

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

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

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

ผู้บริโภคในกลุ่มผู้บริโภค

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

ทำความเข้าใจเกี่ยวกับโบรกเกอร์ข้อความ เรียนรู้กลไกการส่งข้อความด้วย ActiveMQ และ Kafka บทที่ 3 คาฟคา
รูปที่ 3-4 ผู้บริโภคสองคนในกลุ่มผู้บริโภคเดียวกันอ่านจากพาร์ติชันเดียวกัน

โหมดการประมวลผลนี้ซึ่งจำนวนอินสแตนซ์ของผู้บริโภคเกินจำนวนของพาร์ติชัน อาจถูกพิจารณาว่าเป็นผู้บริโภคพิเศษประเภทหนึ่ง สิ่งนี้มีประโยชน์หากคุณต้องการการจัดคลัสเตอร์ "active-passive" (หรือ "hot-warm") ของอินสแตนซ์คอนซูมเมอร์ของคุณ แม้ว่าการเรียกใช้คอนซูมเมอร์หลายตัวพร้อมกัน ("active-active" หรือ "hot-hot") จะเป็นเรื่องปกติมากกว่า ผู้บริโภค อยู่ในโหมดสแตนด์บาย

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

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

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

วิธีที่เป็นที่ยอมรับในการแก้ปัญหานี้ใน Kafka คือการใช้ bОพาร์ติชันเพิ่มเติม

การแบ่งพาร์ติชัน

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

ทำความเข้าใจเกี่ยวกับโบรกเกอร์ข้อความ เรียนรู้กลไกการส่งข้อความด้วย ActiveMQ และ Kafka บทที่ 3 คาฟคา
รูปที่ 3-5 ผู้บริโภครายหนึ่งอ่านจากหลายพาร์ติชัน

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

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

ทำความเข้าใจเกี่ยวกับโบรกเกอร์ข้อความ เรียนรู้กลไกการส่งข้อความด้วย ActiveMQ และ Kafka บทที่ 3 คาฟคา
รูปที่ 3-6 ผู้บริโภคสองคนในกลุ่มผู้บริโภคเดียวกันอ่านจากพาร์ติชันที่แตกต่างกัน

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

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

สิ่งที่นายหน้า Kafka ต้องทำคือส่งข้อความตามลำดับไปยังผู้บริโภคเมื่อคนหลังร้องขอ

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

การส่งข้อความ

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

ในขณะที่ใน JMS เราใช้โครงสร้างข้อความที่มีข้อมูลเมตา (ส่วนหัวและคุณสมบัติ) และเนื้อความที่มีเพย์โหลด (เพย์โหลด) ใน Kafka ข้อความคือ จับคู่ "คีย์-ค่า". เพย์โหลดข้อความถูกส่งเป็นค่า ในทางกลับกัน คีย์ส่วนใหญ่จะใช้สำหรับการแบ่งพาร์ติชันและต้องมี คีย์เฉพาะของตรรกะทางธุรกิจเพื่อใส่ข้อความที่เกี่ยวข้องในพาร์ติชันเดียวกัน

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

  1. บัญชีผู้ใช้ได้รับการกำหนดค่า
  2. เงินจะเข้าบัญชี
  3. มีการเดิมพันที่ถอนเงินออกจากบัญชี

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

อินเทอร์เฟซนี้มีลักษณะดังนี้:

interface Partitioner {
    int partition(String topic,
        Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster);
}

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

การเขียนกลยุทธ์การแบ่งพาร์ติชันของคุณเอง

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

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

{
  "signature": "541661622185851c248b41bf0cea7ad0",
  "accountId": "10007865234"
}

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

Kafka มี checksums เพื่อตรวจหาความเสียหายของข้อความใน Store และมีคุณสมบัติด้านความปลอดภัยครบชุด ถึงกระนั้นก็ตาม ความต้องการเฉพาะของอุตสาหกรรม เช่น ข้อกำหนดข้างต้น บางครั้งก็ปรากฏขึ้น

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

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

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

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

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

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

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

โบรกเกอร์ JMS จำเป็นต้องจัดการกับข้อกำหนดดังกล่าวด้วย ที่น่าสนใจคือ กลไกในการส่งข้อความที่เกี่ยวข้องไปยังผู้บริโภครายเดียวกันซึ่งใช้งานผ่าน JMS Message Groups (รูปแบบหนึ่งของกลยุทธ์ Sticky Load Balancing (SLB)) กำหนดให้ผู้ส่งทำเครื่องหมายข้อความว่าเกี่ยวข้องด้วย ในกรณีของ JMS นายหน้ามีหน้าที่รับผิดชอบในการส่งข้อความที่เกี่ยวข้องกลุ่มนี้ไปยังผู้บริโภคหนึ่งรายจากจำนวนมาก และโอนความเป็นเจ้าของของกลุ่มหากผู้บริโภคตกลงไป

ข้อตกลงผู้ผลิต

การแบ่งพาร์ติชันไม่ใช่สิ่งเดียวที่ควรพิจารณาเมื่อส่งข้อความ มาดูเมธอด send() ของคลาส Producer ใน Java API:

Future < RecordMetadata > send(ProducerRecord < K, V > record);
Future < RecordMetadata > send(ProducerRecord < K, V > record, Callback callback);

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

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

RecordMetadata metadata = producer.send(record).get();

เพิ่มเติมเกี่ยวกับการอ่านข้อความ

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

ConsumerRecords < K, V > poll(long timeout);

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

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

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

กลับไปที่โมเดลการอ่านที่กล่าวถึงก่อนหน้านี้ การประมวลผลข้อความประกอบด้วยสามขั้นตอน:

  1. ดึงข้อความสำหรับอ่าน
  2. ประมวลผลข้อความ
  3. ยืนยันข้อความ

ผู้บริโภค Kafka มาพร้อมกับตัวเลือกการกำหนดค่า Enable.auto.commit. นี่เป็นการตั้งค่าเริ่มต้นที่ใช้บ่อย เช่นเดียวกับการตั้งค่าที่มีคำว่า "อัตโนมัติ"

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

ใน Kafka 0.10 โค้ดไคลเอนต์ถูกเปลี่ยน เพื่อให้คอมมิตถูกทริกเกอร์เป็นระยะโดยไลบรารีไคลเอนต์ ตามที่กำหนดค่าไว้ auto.commit.ช่วง.ms. ลักษณะการทำงานนี้อยู่ระหว่างโหมด JMS AUTO_ACKNOWLEDGE และ DUPS_OK_ACKNOWLEDGE เมื่อใช้การคอมมิตอัตโนมัติ ข้อความอาจถูกคอมมิตโดยไม่คำนึงว่าข้อความนั้นได้รับการประมวลผลจริงหรือไม่ ซึ่งอาจเกิดขึ้นได้ในกรณีของผู้บริโภคที่ช้า หากผู้บริโภคยกเลิก ข้อความจะถูกดึงโดยผู้บริโภครายถัดไป โดยเริ่มต้นที่ตำแหน่งที่ยืนยัน ซึ่งอาจส่งผลให้ได้รับข้อความที่ไม่ได้รับ ในกรณีนี้ Kafka ไม่ได้สูญเสียข้อความ โค้ดที่อ่านไม่ได้ประมวลผล

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

ตามที่กล่าวไว้ใน “การอ่านข้อความจากคิว” ในหน้า 21 ไม่มีสิ่งที่เรียกว่าการส่งข้อความเพียงครั้งเดียวในระบบการส่งข้อความเมื่อคำนึงถึงโหมดความล้มเหลว

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

คุณสามารถควบคุมกระบวนการคอมมิตออฟเซ็ตด้วยตนเองใน Kafka consumer API ได้โดยการตั้งค่าพารามิเตอร์ Enable.auto.commit เป็นเท็จและเรียกวิธีใดวิธีหนึ่งต่อไปนี้อย่างชัดเจน:

void commitSync();
void commitAsync();

หากคุณต้องการประมวลผลข้อความ "อย่างน้อยหนึ่งครั้ง" คุณต้องยอมรับออฟเซ็ตด้วยตนเองด้วย คอมมิตซิงค์()โดยดำเนินการคำสั่งนี้ทันทีหลังจากประมวลผลข้อความ

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

  • ย้อนกลับข้อความปลอมโดยอัตโนมัติ ผู้บริโภคเองต้องจัดการกับข้อยกเว้นที่เกิดจากเพย์โหลดที่มีปัญหาและการหยุดทำงานของแบ็กเอนด์ เนื่องจากพวกเขาไม่สามารถพึ่งพานายหน้าในการส่งข้อความซ้ำได้
  • ส่งข้อความไปยังหลายหัวข้อในการดำเนินการปรมาณูเพียงครั้งเดียว ดังที่เราจะเห็นในไม่ช้า การควบคุมหัวข้อและพาร์ติชันต่างๆ สามารถอยู่ในเครื่องต่างๆ ในคลัสเตอร์ Kafka ซึ่งไม่ประสานธุรกรรมเมื่อส่ง ในขณะที่เขียนบทความนี้ มีการดำเนินการบางอย่างเพื่อให้เป็นไปได้ด้วย KIP-98
  • เชื่อมโยงการอ่านหนึ่งข้อความจากหัวข้อหนึ่งกับการส่งข้อความอื่นไปยังอีกหัวข้อหนึ่ง อีกครั้ง สถาปัตยกรรมคาฟคาขึ้นอยู่กับเครื่องจักรอิสระหลายเครื่องที่ทำงานเป็นบัสเดียว และไม่มีความพยายามที่จะซ่อนสิ่งนี้ ตัวอย่างเช่น ไม่มีคอมโพเนนต์ API ที่จะอนุญาตให้คุณเชื่อมโยง ผู้บริโภค и ผู้ผลิต ในการทำธุรกรรม ใน JMS สิ่งนี้จัดทำโดยวัตถุ เซสชั่นซึ่งสร้างขึ้นจาก ผู้ผลิตข้อความ и ข้อความผู้บริโภค.

ถ้าเราไม่สามารถพึ่งพาธุรกรรมได้ เราจะให้ความหมายที่ใกล้เคียงกับระบบส่งข้อความแบบเดิมได้อย่างไร

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

void seek(TopicPartition partition, long offset);
void seekToBeginning(Collection < TopicPartition > partitions);

วิธี แสวงหา() สามารถใช้กับวิธีการ
offsetsForTimes(แผนที่ การประทับเวลาเพื่อค้นหา) เพื่อย้อนกลับไปยังสถานะ ณ จุดใดจุดหนึ่งในอดีต

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

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

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

ความพร้อมใช้งานสูง

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

คลัสเตอร์ Kafka ประกอบด้วยอินสแตนซ์ของนายหน้าหลายตัวที่ทำงานบนเซิร์ฟเวอร์ที่แตกต่างกัน Kafka ได้รับการออกแบบมาให้ทำงานบนฮาร์ดแวร์แบบสแตนด์อโลนทั่วไป โดยแต่ละโหนดจะมีที่เก็บข้อมูลเฉพาะของตนเอง ไม่แนะนำให้ใช้ที่เก็บข้อมูลแนบเครือข่าย (SAN) เนื่องจากโหนดคอมพิวเตอร์หลายโหนดสามารถแย่งชิงเวลาได้Ыe ช่วงเวลาการจัดเก็บและสร้างข้อขัดแย้ง

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

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

ในกรณีพื้นฐาน หัวข้อจะถูกสร้างขึ้นในคลัสเตอร์ Kafka ที่มีคุณสมบัติดังต่อไปนี้:

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

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

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

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

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

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

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

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

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

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

ผลของการ

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

ส่วนที่แปลก่อนหน้านี้: ทำความเข้าใจเกี่ยวกับโบรกเกอร์ข้อความ เรียนรู้กลไกการส่งข้อความด้วย ActiveMQ และ Kafka บทที่ 1

แปลเสร็จแล้ว: tele.gg/middle_java

จะยังคง ...

เฉพาะผู้ใช้ที่ลงทะเบียนเท่านั้นที่สามารถเข้าร่วมในการสำรวจได้ เข้าสู่ระบบ, โปรด.

Kafka ใช้ในองค์กรของคุณหรือไม่?

  • มี

  • ไม่

  • เมื่อก่อนใช้ ตอนนี้ไม่ใช้แล้ว

  • เราวางแผนที่จะใช้

ผู้ใช้ 38 คนโหวต ผู้ใช้ 8 รายงดออกเสียง

ที่มา: will.com

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