มันเป็นการปฏิบัติที่ไม่ถูกต้องหรือไม่ที่บริการต่างๆจะแบ่งปันฐานข้อมูลใน SOA


17

เมื่อเร็ว ๆ นี้ฉันได้อ่านรูปแบบการรวมองค์กรของ Hohpe และ Woolf หนังสือของ Thomas Erl บางตัวเกี่ยวกับ SOA และดูวิดีโอและพ็อดแคสต์ต่างๆโดย Udi Dahan และคณะ บน CQRS และระบบขับเคลื่อนเหตุการณ์

ระบบในที่ทำงานของฉันต้องทนทุกข์ทรมานจากการมีเพศสัมพันธ์สูง แม้ว่าแต่ละระบบจะมีฐานข้อมูลเป็นของตนเองในทางทฤษฎี ในทางปฏิบัติหมายความว่ามีฐานข้อมูลขนาดใหญ่หนึ่งระบบที่ใช้ทั้งหมด ตัวอย่างเช่นมีข้อมูลลูกค้าหนึ่งตาราง

สิ่งที่ฉันได้อ่านส่วนใหญ่ดูเหมือนว่าจะแนะนำข้อมูลที่ผิดปกติเพื่อให้แต่ละระบบใช้เฉพาะฐานข้อมูลของตน

ฉันคิดว่านี่เป็นวิธีหนึ่งในการบังคับใช้ขอบเขตใน SOA - แต่ละบริการควรมีฐานข้อมูลของตัวเอง แต่จากนั้นฉันอ่านสิ่งนี้:

/programming/4019902/soa-joining-data-across-multiple-services

และมันบอกว่านี่เป็นสิ่งที่ผิดที่ต้องทำ

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


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

ฉันเข้าใจว่าคำถามนั้นผิดมันเป็นคำตอบที่ทำให้ฉันประเมินความคิดของฉันใหม่
Paul T Davies

ฉันคิดว่าบริการจะต้องเชื่อมโยงกัน
B Seven

คำตอบ:


12

การแยกชิ้นส่วนจะทำงานได้เฉพาะในกรณีที่มีการแยกตัวจริงๆ พิจารณาว่าคุณมีระบบการสั่งซื้อหรือไม่:

  • ตาราง: ลูกค้า
  • ตาราง: สั่งซื้อ

ถ้านั่นคือทั้งหมดที่คุณมีไม่มีเหตุผลที่จะแยกพวกเขา ในทางกลับกันหากคุณมีสิ่งนี้:

  • ตาราง: ลูกค้า
  • ตาราง: สั่งซื้อ
  • ตาราง: CUSTOMER_NEWSLETTER

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

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

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


5
-1 พวกเขาควรจะอยู่ในฐานข้อมูลแยกต่างหากหากมีเหตุผลที่จะทำให้พวกเขามี คุณต้อง "เอาบางสิ่งออกไป" เพราะมันทำให้แอปของคุณซับซ้อนยิ่งขึ้น
scottschulthess

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

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

8

ฉันทำงานที่ไหนเรามีESBแอพพลิเคชั่น 6 ตัวที่แตกต่างกัน (หรือฉันควรจะพูดว่า "อุปกรณ์ปลายทาง") เชื่อมต่อกันแล้ว แอพพลิเคชั่นทั้ง 6 นั้นทำงานร่วมกับ Oracle schema ที่แตกต่างกัน 3 ตัวบนอินสแตนซ์ฐานข้อมูล 2 ตัว แอปพลิเคชันเหล่านี้บางส่วนอยู่ในสคีมาเดียวกันไม่ใช่เพราะเกี่ยวข้อง แต่เนื่องจากโครงสร้างพื้นฐานฐานข้อมูลของเราได้รับการจัดการโดยผู้ให้บริการภายนอกและการรับสคีมาใหม่ใช้เวลาตลอดไป (เช่นกันเราไม่สามารถเข้าถึง DBA ได้) ... ใช้เวลานานมากจนถึงจุดหนึ่งเราคิดว่าการนำ schema ที่มีอยู่ "ชั่วคราว" กลับมาใช้ใหม่เพื่อให้สามารถพัฒนาต่อไปได้ ในการบังคับใช้ "การแยก" ของข้อมูลชื่อตารางจะถูกนำหน้าเช่น "CST_" สำหรับลูกค้า นอกจากนี้เราต้องทำงานร่วมกับสคีมาด้วยเหตุผลที่ถูกต้องบางอย่างที่เราไม่สามารถเปลี่ยนแปลงได้อย่างสมบูรณ์ ... มันแปลกที่ฉันรู้ แน่นอนมันเกิดขึ้นเสมอ "ชั่วคราว"

แอปพลิเคชันต่าง ๆ ของเราเชื่อมต่อกับสคีมาฐานข้อมูลของตนและทำงานกับแพ็คเกจ PL / SQL ของตัวเองและเราห้ามไม่ให้เราโต้ตอบโดยตรงกับตาราง / ข้อมูลที่อยู่นอกโดเมนแอปพลิเคชันของเรา

เมื่อแอปพลิเคชันหนึ่งที่เชื่อมต่อกับ ESB ต้องการข้อมูลนอกโดเมนมันจะเรียกบริการที่เกี่ยวข้องใน ESB เพื่อรับข้อมูลแม้ว่าข้อมูลนั้นจะอยู่ในสคีมาเดียวกันจริง ๆ แล้วต้องมีคำสั่งเข้าร่วมเพียงเล็กน้อยในทฤษฎี หนึ่งของการร้องขอของ

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

ตอนนี้อาจดูแปลกและน่ากลัวจากภายนอก แต่มีเหตุผลที่และฉันต้องการแบ่งปันประสบการณ์ที่เป็นรูปธรรมนี้เพื่อแสดงให้คุณเห็นว่าฐานข้อมูลอย่างน้อยหนึ่งฐานไม่สำคัญ เดี๋ยวก่อน! ด้วยเหตุผลหลายประการ (+1 สำหรับ Scott Whitlock ดูย่อหน้าสุดท้ายเกี่ยวกับการสำรองข้อมูลและสิ่งที่ mya นำคุณไปสู่ปัญหา) แต่สิ่งสำคัญคือฉันคิดว่าการให้บริการ SOA ของคุณได้รับการออกแบบอย่างเหมาะสมอย่างน้อยก็เป็นความคิดของฉันและฉัน ไม่ใช่ DBA ท้ายที่สุดฐานข้อมูลทั้งหมดของคุณเป็นของ "คลังข้อมูลองค์กร" ใช่ไหม?

ในที่สุดฉันจะไม่ใช้ถ้อยคำในย่อหน้าสุดท้ายของ Scott Whitlock โดยเฉพาะสิ่งนี้

ฉันจะไม่แยกตารางออกเป็นฐานข้อมูลทางกายภาพที่แตกต่างกันเพียงเพราะแยกข้อกังวลออก

มันสำคัญมากจริงๆ อย่าทำอย่างนั้นถ้าไม่มีเหตุผล


8

ฉันเคยเห็นฝันร้ายที่เลวร้ายที่สุดที่เป็นไปได้ในสถาปัตยกรรมซอฟต์แวร์เนื่องจากการรวมข้อมูลและอาวุธที่ดีที่สุดสำหรับความยุ่งเหยิงประเภทนี้ที่ฉันเคยพบมาจนถึงตอนนี้ DDD-Style Bounded Contexts ซึ่งไม่ไกลจาก "SOA ทำถูกต้อง" ในแง่หนึ่ง

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

เพื่อให้ง่าย: หากคุณกำลังมองหาระบบที่เชื่อมต่อกันอย่างอิสระอย่าเชื่อมโยงกับข้อมูล ไปสำหรับ Weel encapsulated system และช่องทางการสื่อสารที่มีโครงสร้างที่ดีในระหว่างนั้นทำหน้าที่เป็น"lingua franca"


1
และ ... ตอบกลับไปยังคำถามไตเติ้ล: "ใช่ฉันคิดว่ามันเป็นการปฏิบัติที่เสี่ยงที่จะแบ่งปันฐานข้อมูลใน SOA" ถ้ามันดูเหมือนว่าสิ่งที่สมเหตุสมผลที่สุดที่จะทำ
ZioBrando

7

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


1

หากทำอย่างถูกต้องแยกกังวลทางธุรกิจลงในฐานข้อมูลที่แตกต่างกัน (หรืออย่างน้อย schema ที่แตกต่างกัน) เป็นคุณธรรม

โปรดดูคำอธิบายรูปแบบ CQRS ของ Martin Fowler :

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

และNServiceBus หลักการสถาปัตยกรรม :

การแยกแบบสอบถามคำสั่ง

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

และการแบ่งแยกความรับผิดชอบคำสั่งและแบบสอบถาม (CQRS)

การแบ่งแยกความรับผิดชอบคำสั่งและแบบสอบถาม

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

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