ใช้ Kafka เป็น (CQRS) Eventstore ความคิดที่ดี?


219

ถึงแม้ว่าผมจะเคยเจอKafkaก่อนผมเพิ่งตระหนัก Kafka บางทีอาจจะใช้เป็น (พื้นฐานของการบริการ) CQRS , eventstore

หนึ่งในประเด็นหลักที่คาฟคาสนับสนุน:

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

เป็นที่ยอมรับว่าฉันไม่ใช่ 100% ที่เชี่ยวชาญในการจัดหา CQRS / การจัดหากิจกรรม แต่ดูเหมือนว่าใกล้เคียงกับร้านค้าที่ควรจะเป็น สิ่งที่ตลกคือ: ฉันไม่สามารถพบได้มากนักเกี่ยวกับการใช้คาฟคาในการเป็นสถานที่จัดงานดังนั้นฉันอาจจะพลาดอะไรบางอย่างไป

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

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


สวัสดี Geert-Jan เมื่อมองย้อนหลังคุณจัดการกับปัญหานี้อย่างไร ฉันมีคำถามที่เกี่ยวข้อง (เปิดเผยที่นี่: stackoverflow.com/questions/58763727/… ) คนส่วนใหญ่แนะนำว่าการยอมรับของคาฟคานั้นขึ้นอยู่กับประเด็นความไม่แน่นอนของการผนวกข้อมูลเข้าสู่ระบบปริมาณงานที่สูงและการรับประกันคำสั่งซื้อพาร์ติชันฉันเห็นปัญหาที่เกี่ยวข้องกับการค้นหาอย่างรวดเร็วภายในหัวข้อต่างๆ (การรับประกันการสั่งซื้อ 100% หมายถึงการใช้เพียง 1 พาร์ติชั่น
tony _008

ไม่ได้โน้มน้าวในท้ายที่สุดเพราะฉันสิ้นสุดโครงการด้านข้าง ดังนั้นจึงไม่มีคำตอบที่ชัดเจนฉันเกรง
Geert-Jan

คำตอบ:


119

Kafka มีวัตถุประสงค์เพื่อเป็นระบบส่งข้อความซึ่งมีความคล้ายคลึงกันหลายอย่างกับร้านค้าอีเวนต์

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

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

UPDATE

เอกสาร Kafka :

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

อัพเดท 2

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


16
ฉันกำลังดูคาฟคาและมีข้อกังวลอื่น: ฉันไม่ได้สังเกตอะไรเลยเกี่ยวกับการเห็นพ้องในแง่ดี เป็นการดีที่ฉันสามารถพูดได้: "เพิ่มเหตุการณ์นี้เป็นรายการ N + 1 เฉพาะเมื่อเหตุการณ์ล่าสุดของวัตถุยังคงเป็น N"
Darien

2
@Darien: ฉันอาจจะไปกับการตั้งค่าที่ Redis ฟีดคาฟคา (ใช้การแจ้งเตือน Redis ) เนื่องจาก Redis อนุญาตให้มีการทำงานพร้อมกันในแง่ดี (โดยใช้ Watch / multi-exec) สิ่งนี้ควรใช้งานได้
Geert-Jan

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

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

1
นอกจากนี้ยังมีข้อมูลที่มีค่าที่นี่: groups.google.com/forum/#!topic/dddcqrs/rm02iCfffUY
manuc66

283

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

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

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

ฉันได้เขียนบิตเกี่ยวกับรูปแบบของการใช้งาน Kafka นี้ที่นี่


2
กำลังจะโพสต์ลิงก์นั้น :) โพสต์บล็อกที่น่ากลัว คงจะดีที่ได้แสดงความคิดเห็นเพราะฉันมีคำถามมากมาย @ Geert-Jan ดูที่ "สถาปัตยกรรมแลมบ์ดา" ซึ่งคล้ายกันมากและชื่อนี้ได้รับมาจากผู้เขียนสตอร์มโดยส่วนใหญ่ใช้บันทึกเหตุการณ์ฮาพุดแบบบางส่วนในตัวอย่างมากมาย
เซบาสเตียน Lorber

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

2
มีการเปรียบเทียบระหว่างร้านคาฟคาและอีเวนต์หรือไม่? โดยเฉพาะฉันชอบโฟกัสที่ FRP ใน eventstore เรียกว่า Projections มีอะไรแบบนั้นใน Kafka / Samza หรือไม่?
CMCDragonkai

4
ฉันสนใจคำถามของ @ Geert-Jan กับ Jay Kafka ไม่เหมาะสำหรับการจัดหากิจกรรมการทำธุรกรรมจริงเนื่องจากต้องการกระแสของเหตุการณ์ (หัวข้อ) ต่อการรวมโดเมน (คิดเป็นล้าน) อย่างไรก็ตามมันเหมาะอย่างยิ่งที่จะให้มีการป้อนเหตุการณ์จากเช่น GetEventStore แต่สิ่งนี้จะใช้ได้กับเหตุการณ์ที่ถูกเก็บไว้อย่างไม่สิ้นสุด (ในกรณีของเรา) และนอกเหนือจากความคิดเห็นสั้น ๆ แล้วดูเหมือนว่านี่จะไม่ใช่กรณีการใช้งานที่สนับสนุนของ Kafka ใช่ไหม ฉันเข้าใจผิดนี่ไหม ตัวอย่างเช่น Samza สมมติว่ามีเพียงสองสถานการณ์เท่านั้น: การเก็บรักษาตามเวลาหรือการเก็บรักษาตามคีย์ มีคนอื่นอีก ..
สตีเฟ่น Drew

3
@eulerfx สมมติว่าเราต้องการใช้ Kafka เป็นที่เก็บข้อมูลสำหรับระบบที่มาจากเหตุการณ์วิธีที่การล็อก / การทำงานพร้อมกันในแง่ดีควรนำไปใช้อย่างไร
Krzysztof Branicki

51

ฉันกลับมาที่ QA นี้ต่อไป และฉันไม่พบคำตอบที่มีอยู่เหมาะสมพอฉันจึงเพิ่มคำตอบนี้

TL; DR ใช่หรือไม่ขึ้นอยู่กับการใช้งานการจัดหากิจกรรมของคุณ

มีเหตุการณ์หลักสองประเภทที่มาจากระบบที่ฉันรับรู้

ตัวประมวลผลเหตุการณ์ดาวน์สตรีม = ใช่

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

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

แอปพลิเคชันที่ควบคุมความจริง = ไม่

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

ขาดการแยกเอนทิตี

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

หนึ่งในเหตุผลหลักที่ใช้รูปแบบการเขียนชั่วคราวในวิธีนี้คือการเปลี่ยนแปลงตรรกะทางธุรกิจราคาถูกและใช้งานง่าย

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

ขาดการตรวจสอบความขัดแย้ง

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

ข้อมูลเพิ่มเติม


อัปเดตต่อความคิดเห็น

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

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

ในสถานการณ์แบบกระจายฉันเห็นการใช้งานที่แตกต่างกันสองอย่าง โครงการ Pantherของ Jet ใช้ Azure CosmosDBพร้อมคุณสมบัติ Change Feed เพื่อแจ้งเตือนผู้ฟัง การใช้งานที่คล้ายกันอีกอย่างที่ฉันเคยได้ยินเกี่ยวกับ AWS คือการใช้ DynamoDB พร้อมคุณสมบัติสตรีมเพื่อแจ้งผู้ฟัง คีย์พาร์ติชันอาจเป็นรหัสสตรีมสำหรับการกระจายข้อมูลที่ดีที่สุด (เพื่อลดปริมาณการจัดสรรพื้นที่ส่วนเกิน) อย่างไรก็ตามการเล่นซ้ำเต็มรูปแบบข้ามลำธารใน Dynamo นั้นมีราคาแพง (อ่านและคุ้มค่า) ดังนั้นสิ่งนี้จึงถูกตั้งค่าสำหรับ Dynamo Streams เพื่อทิ้งกิจกรรมลง S3 เมื่อผู้ฟังใหม่ออนไลน์หรือผู้ฟังที่มีอยู่ต้องการเล่นซ้ำแบบเต็มมันจะอ่าน S3 เพื่อให้ทันก่อน

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

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


1
@Dominik ฉันพูดถึง EventStore ในส่วน Update (ย่อหน้าที่ 2) ฉันจะกลับไปและเชื่อมโยงมัน ฉันได้ลองแล้วและมันก็มีความสมบูรณ์แบบที่น่าประทับใจ สำหรับทีมเล็ก ๆ ของเราการไม่แนะนำฐานข้อมูลอื่นถือว่ามีความสำคัญมากกว่าในตอนนี้ดังนั้น Postgres (ซึ่งใช้สำหรับการดู) เป็นไปได้ว่าเราจะย้ายไปที่ EventStore ในอนาคตหรือในอนาคตผลิตภัณฑ์
Kasey Speakman

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

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

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

2
@KaseySpeakman การใช้ Kafka ด้วยวิธีนี้ไม่ใช่เรื่องง่าย แต่อย่างใด แต่ถ้าคุณอยู่ในระดับที่คุณพิจารณา CQRS และการจัดหากิจกรรมอย่างจริงจังคุณจะอยู่ในระดับที่คุณไม่สามารถทำสิ่งต่าง ๆ ได้อย่างง่ายดาย โมเดลการทำงานพร้อมกันของคุณมีผลกระทบโดยตรงกับเครื่องชั่งของคุณ - อย่าเลือกโดยพลการ นอกจากนี้ HTTP ไม่ใช่การส่งผ่านที่เชื่อถือได้และอีกครั้งหากคุณอยู่ในระดับดังกล่าวคุณจะไม่สามารถใช้เวลาในการแก้ปัญหาข้อความที่สูญหายและ / หรือทำซ้ำได้ ทั้งหมดนี้สามารถแก้ไขได้โดยการใช้ Kafka ระหว่างไคลเอนต์และตัวประมวลผลคำสั่ง แต่ใช่มันมาพร้อมกับค่าใช้จ่ายของความซับซ้อน
Andrew Larsson

20

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

  • คาฟคารับประกันอย่างน้อยหนึ่งครั้งในการจัดส่งและมีรายการซ้ำในที่จัดเก็บกิจกรรมที่ไม่สามารถลบได้ อัปเดต: ที่ นี่คุณสามารถอ่านได้ว่าทำไมมันถึงยากนักกับคาฟคาและข่าวล่าสุดเกี่ยวกับวิธีการทำให้พฤติกรรมนี้สำเร็จ: https://www.confluent.io/blog/exactly-once-semantics-are-possible-heres-how -apache-Kafka-ไม่มัน /
  • เนื่องจากการเปลี่ยนแปลงไม่ได้จึงไม่มีวิธีจัดการกับที่จัดเก็บเหตุการณ์เมื่อแอปพลิเคชันวิวัฒนาการและกิจกรรมต้องมีการเปลี่ยนแปลง (มีวิธีการเรียนการสอนเช่นการอัปโหลด แต่ ... ) ครั้งหนึ่งอาจบอกว่าคุณไม่จำเป็นต้องแปลงเหตุการณ์ แต่นั่นไม่ใช่ข้อสันนิษฐานที่ถูกต้องอาจมีสถานการณ์ที่คุณทำการสำรองข้อมูลดั้งเดิม แต่คุณอัปเกรดเป็นรุ่นล่าสุด นั่นเป็นข้อกำหนดที่ถูกต้องในสถาปัตยกรรมที่ขับเคลื่อนด้วยเหตุการณ์
  • ไม่มีที่สำหรับเก็บสแนปชอตของเอนทิตี / มวลรวมและการเล่นซ้ำจะช้าลงและช้าลง การสร้างสแนปชอตจะต้องมีคุณสมบัติสำหรับการจัดเก็บเหตุการณ์จากมุมมองระยะยาว
  • พาร์ติชั่นของ Kafka นั้นมีการกระจายและยากที่จะจัดการและสำรองข้อมูลเปรียบเทียบกับฐานข้อมูล ฐานข้อมูลนั้นง่ายกว่า :-)

ดังนั้นก่อนที่คุณจะตัดสินใจเลือกคุณจะคิดสองครั้ง การจัดเก็บกิจกรรมเป็นการรวมกันของแอปพลิเคชันเลเยอร์อินเทอร์เฟซ (การตรวจสอบและการจัดการ), SQL / NoSQL store และ Kafka ในฐานะนายหน้าเป็นทางเลือกที่ดีกว่าการทิ้ง Kafka จัดการทั้งสองบทบาทเพื่อสร้างโซลูชันที่สมบูรณ์

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

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

โปรดดูที่เฟรมเวิร์กโอเพนซอร์สไมโครซอฟท์ eventuate.io เพื่อค้นหาเพิ่มเติมเกี่ยวกับปัญหาที่อาจเกิดขึ้น: http://eventuate.io/

อัปเดตตั้งแต่วันที่ 8 ก.พ. 2018

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

  1. อย่าใช้สปริง - มันยอดเยี่ยม (ฉันใช้ตัวเองมาก) แต่หนักและช้าในเวลาเดียวกัน และมันไม่ได้เป็นแพลตฟอร์มไมโครบริการเลย มันเป็นเพียงแค่กรอบที่จะช่วยให้คุณสามารถใช้งานได้ เฟรมเวิร์กอื่น ๆ คือ "เพียงแค่" REST ที่เบาหรือ JPA หรือเฟรมเวิร์กที่โฟกัสแตกต่างกัน ฉันขอแนะนำอาจเป็นแพลตฟอร์ม microservice ที่สมบูรณ์แบบโอเพ่นซอร์สที่ดีที่สุดในระดับพร้อมใช้งานซึ่งกลับมาที่รูท Java บริสุทธิ์: https://github.com/networknt

หากคุณสงสัยเกี่ยวกับประสิทธิภาพคุณสามารถเปรียบเทียบตัวเองกับชุดเบนช์มาร์กที่มีอยู่ https://github.com/networknt/microservices-framework-benchmark

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

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

  3. สำหรับการส่งข้อความลองดูที่ Chronicle Queue, Map, Engine, Network ฉันหมายถึงกำจัดโซลูชันcentric โบรคเกอร์ที่ล้าสมัยและไปกับระบบการส่งข้อความขนาดเล็ก Chronicle Queue นั้นเร็วกว่าคาฟคาจริงๆ แต่ฉันยอมรับว่ามันไม่ใช่ทั้งหมดในโซลูชันเดียวและคุณต้องทำการพัฒนาบางอย่างมิฉะนั้นคุณจะไปและซื้อรุ่น Enterprise (จ่ายหนึ่ง) ในที่สุดความพยายามในการสร้างจาก Chronicle เลเยอร์การส่งข้อความของคุณเองจะได้รับการชำระโดยลบภาระในการบำรุงรักษาคลัสเตอร์ Kafka


มุมมองที่น่าสนใจ สนใจที่จะอธิบายรายละเอียดเกี่ยวกับจุดไม่กี่? > Kafka รับประกันอย่างน้อยหนึ่งครั้งในการจัดส่งและมีรายการซ้ำในที่จัดเก็บกิจกรรมที่ไม่สามารถลบได้ คุณดูเหมือนจะบอกเป็นนัยว่ามีสิ่งนั้นเหมือนกับการส่งมอบครั้งเดียว afaik (และฉันค่อนข้างมั่นใจในเรื่องนี้) ไม่มีสิ่งนั้นในระบบกระจาย 2) สำหรับประเด็นของคุณ 2: โรงเรียนคลาสสิกของ (การจัดหากิจกรรม / dddd) คิดว่าเหตุการณ์ไม่เปลี่ยนรูปโดยเนื้อแท้ Ie: พวกเขามีความสุขไม่มีทางเปลี่ยนอดีต อะไรคือการใช้งานจริงของการเปลี่ยนแปลงพวกมันในการหวนกลับ? ขอบคุณ!
Geert-Jan

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

1) อย่างน้อยหนึ่งครั้ง + idempotence สำหรับผู้บริโภค Ie: ตรวจสอบว่ามีเหตุการณ์ที่เห็นอยู่แล้ว ถ้าข้ามไป หรือดีกว่ายังมีการกระทำ idempotent แน่นอนว่ามันเป็นไปไม่ได้เสมอไป 2) ฉันไม่เคยพบเหตุการณ์ที่ต้องใช้เวอร์ชัน ฉันมักจะปฏิบัติต่อเหตุการณ์เหล่านั้นเป็นแหล่งของความจริงและรวมถึงข้อมูลทั้งหมดที่ฉันต้องการ การทำเช่นนี้ฉันไม่เคยพบสถานการณ์ที่ฉันต้องการโครงสร้างเหตุการณ์และ / หรือข้อมูลอื่นเกี่ยวกับเหตุการณ์ แต่บางที ymmv สนใจที่จะรับฟังว่าสถานการณ์ใดที่คุณจะต้องมีการอัพเดทเหตุการณ์
Geert-Jan

1. ) สามารถเป็นทางเลือก .. 2. ) โครงสร้างข้อมูลของคุณนั้นสมบูรณ์แบบตั้งแต่เริ่มต้น :-) โชคดีนะฮ่าฮ่า ฉันอาจไม่ต้องการมันในโครงการปัจจุบันของฉัน แต่ฉันกำลังสร้างแพลตฟอร์มทั้งหมดบน forks ของ eventuate.io ที่รวมเข้ากับ JEE ที่มีประสิทธิภาพสูงวิธีการที่นำมาจากแสง eventuate 4j เท่านั้น ... การอภิปรายทั้งหมดนี้ไม่ได้มีไว้สำหรับคอมเม้นท์ stackoverflow แต่ถ้าคุณสนใจที่จะดำน้ำลึกฉันขอแนะนำบทความนี้: leanpub.com/esversioning/read
kensai

1
Kafka รองรับการจัดส่งทันทีเมื่อถึงตอนนี้ อัปเดต bullet 1
OneCricketeer

8

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

เกี่ยวกับ:

ความสามารถในการเล่นซ้ำบันทึกเหตุการณ์ซึ่งช่วยให้ความสามารถสำหรับสมาชิกใหม่ที่จะลงทะเบียนกับระบบหลังจากข้อเท็จจริง

นี่อาจเป็นเรื่องยุ่งยาก ฉันครอบคลุมรายละเอียดที่นี่: https://stackoverflow.com/a/48482974/741970


0

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


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