ไม่เพียงแต่การประมวลผลเท่านั้น: วิธีที่เราสร้างฐานข้อมูลแบบกระจายจาก Kafka Streams และสิ่งที่เกิดขึ้น

เฮ้ ฮับ!

เราขอเตือนคุณว่าต่อไปนี้เป็นหนังสือเกี่ยวกับ Kafka เราได้ตีพิมพ์ผลงานที่น่าสนใจไม่แพ้กันเกี่ยวกับห้องสมุด Kafka สตรีม API.

ไม่เพียงแต่การประมวลผลเท่านั้น: วิธีที่เราสร้างฐานข้อมูลแบบกระจายจาก Kafka Streams และสิ่งที่เกิดขึ้น

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

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

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

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

เหตุใดเราจึงคิดว่าถึงเวลาเปลี่ยนวิธีการทำงานของเรากับรัฐที่ใช้ร่วมกัน

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

ไม่เพียงแต่การประมวลผลเท่านั้น: วิธีที่เราสร้างฐานข้อมูลแบบกระจายจาก Kafka Streams และสิ่งที่เกิดขึ้น

รูปที่ 1: สถานการณ์การแยกสถานะทั่วไปที่เห็นก่อนการเปลี่ยนไปใช้
Kafka และ Kafka Streams: เจ้าหน้าที่สื่อสารมุมมองของตนผ่าน API สถานะที่อัปเดตจะถูกคำนวณผ่านฐานข้อมูลกลาง

พบกับ Kafka Streams ทำให้ง่ายต่อการสร้างไมโครเซอร์วิสสถานะที่ใช้ร่วมกัน

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

ไมโครเซอร์วิสเก็บสถานะแต่ละรายการที่เราสร้างขึ้นสร้างขึ้นบนอินสแตนซ์ Kafka Streams ด้วยโทโพโลยีที่ค่อนข้างเรียบง่าย ประกอบด้วย 1) แหล่งที่มา 2) ตัวประมวลผลที่มีที่เก็บคีย์-ค่าถาวร 3) ซิงก์:

ไม่เพียงแต่การประมวลผลเท่านั้น: วิธีที่เราสร้างฐานข้อมูลแบบกระจายจาก Kafka Streams และสิ่งที่เกิดขึ้น

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

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

ไม่เพียงแต่การประมวลผลเท่านั้น: วิธีที่เราสร้างฐานข้อมูลแบบกระจายจาก Kafka Streams และสิ่งที่เกิดขึ้น

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

เฮ้ ที่เก็บคีย์-ค่าในตัวนี้มีประโยชน์มากจริงๆ!

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

ตัวเลือก #1: ใช้ที่เก็บคีย์-ค่าสำหรับการคำนวณ

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

ไม่เพียงแต่การประมวลผลเท่านั้น: วิธีที่เราสร้างฐานข้อมูลแบบกระจายจาก Kafka Streams และสิ่งที่เกิดขึ้น

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

ตัวเลือก #2: การสร้าง CRUD API บน Kafka Streams

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

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

ไม่เพียงแต่การประมวลผลเท่านั้น: วิธีที่เราสร้างฐานข้อมูลแบบกระจายจาก Kafka Streams และสิ่งที่เกิดขึ้น

รูปที่ 5: การใช้ที่เก็บคีย์-ค่าในตัวเพื่อรับสถานะที่คำนวณล่วงหน้าของออบเจ็กต์

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

ไม่เพียงแต่การประมวลผลเท่านั้น: วิธีที่เราสร้างฐานข้อมูลแบบกระจายจาก Kafka Streams และสิ่งที่เกิดขึ้น

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

ภาวะแทรกซ้อนเล็กน้อย: Kafka มีหลายพาร์ติชัน

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

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

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

ไม่เพียงแต่การประมวลผลเท่านั้น: วิธีที่เราสร้างฐานข้อมูลแบบกระจายจาก Kafka Streams และสิ่งที่เกิดขึ้น

รูปที่ 7: การใช้ข้อมูลเมตาของสตรีม เราจะพิจารณาว่าอินสแตนซ์ใดที่จะสืบค้นสถานะของออบเจ็กต์ที่ต้องการ ใช้วิธีการที่คล้ายกันกับ GET ALL API

การค้นพบที่สำคัญ

ร้านค้าของรัฐใน Kafka Streams สามารถทำหน้าที่เป็นฐานข้อมูลแบบกระจายโดยพฤตินัย

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

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

ที่มา: will.com

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