Common Risks (ความเสี่ยงที่พบบ่อย)

ไม่น่าแปลกใจที่ความเสี่ยงส่วนใหญ่ที่เกี่ยวข้องกับ space-based architectural style จะเกี่ยวกับข้อมูล เนื่องจากมีการใช้ caching และการ synchronize ข้อมูลแบบ background หัวข้อต่อไปนี้จะอธิบายความเสี่ยงที่พบ บ่อยบางส่วน

Frequent Reads from the Database (การอ่านฐานข้อมูลบ่อยครั้ง)

space-based architecture บรรลุ scalability และ concurrency ระดับสูงได้ด้วยการใช้ caching สำหรับข้อมูล transactional ทั้งหมด สิ่งนี้ป้องกันไม่ให้ระบบต้องอ่านและเขียนฐานข้อมูลมากเกินไป ซึ่งอาจลด scalability, elasticity และ responsiveness โดยรวมของระบบ ทำให้ยากที่จะได้ประโยชน์เต็มที่จาก architectural style นี้

การอ่านฐานข้อมูลมักเกิดขึ้นใน 2 สถานการณ์เท่านั้น คือการอ่านข้อมูล archive (เช่น ประวัติคำสั่งซื้อหรือ bank statement เก่า) หรือการ cold-start processing unit (การ start processing unit ครั้งแรกเมื่อไม่มี instance อื่นทำงานอยู่) ถ้า data volume ที่ cache ไว้สูงมากจนข้อมูลส่วนใหญ่ต้องถูก archive และดึงกลับมาจาก backing database หรือถ้า processing unit crash หรือถูก redeploy บ่อยครั้ง architecture นี้อาจไม่เหมาะกับ problem domain นั้น

Data Synchronization and Consistency (การ Synchronize และ Consistency ของข้อมูล)

เนื่องจาก data pump และ data writer จะ synchronize ข้อมูลระหว่าง in-memory cache กับฐานข้อมูล ข้อมูล ใน space-based architecture จึงเป็น eventually consistent เสมอ อย่างไรก็ตาม เนื่องจาก style นี้มักถูก ใช้ในสถานการณ์ที่มี concurrent user load สูงมาก bottleneck ใน data pump จึงเป็นเรื่องปกติ bottleneck เหล่านี้อาจทำให้ข้อมูลไปถึง backing database ช้าลงอย่างมาก นี่อาจเป็นความเสี่ยงสำคัญ ถ้าระบบ downstream ต้องการข้อมูลที่อัปเดตแล้วอย่างรวดเร็ว

อีกความเสี่ยงหนึ่งที่มากับ data synchronization คือการสูญหายของข้อมูลภายใน data pump ความเสี่ยงนี้มัก ถูกบรรเทาด้วยการใช้ persisted queue (ซึ่งข้อมูลใน queue จะถูกเก็บไว้บน disk เช่นเดียวกับใน memory) และการใช้ client-acknowledgment mode ใน data writer เมื่ออ่านจาก data pump client-acknowledgment mode จะเก็บ message ไว้ใน queue จนกว่า data writer จะ acknowledge กับ message broker ว่าประมวลผลเสร็จแล้ว ระหว่างการประมวลผล message message broker จะรับประกันว่าจะไม่มี data writer ตัวอื่นอ่าน message ที่กำลังประมวลผลอยู่ แม้เทคนิคเหล่านี้จะ ช่วยป้องกันการสูญหายของข้อมูลใน data pump แต่ก็อาจทำให้ responsiveness โดยรวมช้าลงและลด data consistency ได้

High Data Volumes (Data Volume สูง)

เนื่องจาก transactional memory ทั้งหมดถูก cache ไว้ใน processing unit data volume จึงต้องอยู่ในระดับ ค่อนข้างต่ำ โดยเฉพาะเมื่อมีการเพิ่ม instance ของ processing unit มากขึ้น สิ่งนี้ทำให้จำเป็นต้องให้ ความสำคัญอย่างมากกับขนาดของ in-memory cache เพื่อหลีกเลี่ยงไม่ให้ processing unit หน่วยความจำหมด จนถึงขั้น crash

Data Collisions (Data Collision)

data collision เกิดขึ้นเมื่อข้อมูลถูกอัปเดตใน cache instance หนึ่ง (cache A) และระหว่างที่ replicate ไปยัง cache instance อีกตัว (cache B) ข้อมูลชุดเดียวกันนั้นถูกอัปเดตโดย cache นั้นเอง (cache B) สิ่งนี้สามารถเกิดขึ้นได้เมื่อใช้ replicated caching ใน active/active state ซึ่งหมายความว่า processing unit หลายตัวสามารถอัปเดตข้อมูลชุดเดียวกันพร้อมกันได้ collision มักเกิดขึ้นเมื่อ update rate ของข้อมูลใน cache สูงเกิน replication latency (RL) —เวลาที่ใช้ในการ synchronize cache ชื่อเดียวกันแต่ละคู่ ในสถานการณ์นี้ การอัปเดตข้อมูล local ใน cache B จะถูกทับด้วยข้อมูลเก่าจาก cache A และข้อมูลชุดเดียวกันใน cache A ก็จะถูกทับด้วยการอัปเดตจาก cache B เช่นกัน ทำให้ข้อมูลใน cache แต่ละตัวไม่สอดคล้องกัน

เพื่อแสดงให้เห็นปัญหา data collision ลองสมมติว่ามี service instance สองตัว (A และ B) ของ order placement service แต่ละตัวมี replicated cache ของสินค้าคงคลัง (blue widget) flow เป็นดังนี้:

  1. จำนวนสินค้าคงคลังปัจจุบันคือ 500 หน่วย ในทั้ง instance A และ B

  2. instance A ได้รับ request จากลูกค้าให้ซื้อ 10 หน่วย และอัปเดต inventory cache ของ blue widget เป็น 490 หน่วย

  3. ก่อนที่ข้อมูลของ instance A จะถูก replicate ไปยัง instance B, instance B ได้รับ purchase request สำหรับ 5 หน่วย และอัปเดต inventory cache ของ blue widget เป็น 495 หน่วย

  4. cache ใน instance B ถูกอัปเดตเป็น 490 หน่วย เนื่องจากการ replication จากการอัปเดตของ instance A

  5. cache ใน instance A ถูกอัปเดตเป็น 495 หน่วย เนื่องจากการ replication จากการอัปเดตของ instance B

  6. cache ทั้งสองผิดพลาดและไม่ sync กัน: สินค้าคงคลังที่ถูกต้องควรเป็น 485 หน่วยในแต่ละ instance

มีหลายปัจจัยที่มีผลต่อจำนวน data collision ที่อาจเกิดขึ้น ได้แก่ จำนวน processing-unit instance ที่มี cache เดียวกัน, update rate ของ cache, ขนาดของ cache และ RL ของ caching product เราสามารถคำนวณความ น่าจะเป็นของจำนวน data collision ที่อาจเกิดขึ้นได้โดยอิงจากปัจจัยเหล่านี้ ด้วยสูตรต่อไปนี้:

𝐶𝑜𝑙𝑙𝑖𝑠𝑖𝑜𝑛 𝑅𝑎𝑡𝑒 \= N * U R 2 S * R L

ในที่นี้ N แทนจำนวน service instance ที่ใช้ cache ชื่อเดียวกัน UR แทน update rate เป็นมิลลิวินาที (ยกกำลังสอง) S คือขนาด cache (จำนวนแถว) และ RL คือ replication latency ของ caching product (เป็นมิลลิวินาที)

สูตรนี้มีประโยชน์ในการหาเปอร์เซ็นต์ของ data collision ที่มีแนวโน้มจะเกิดขึ้น โดยอิงจากการอัปเดตภายใน ช่วงเวลาที่กำหนด (เช่น ทุกชั่วโมง) และดังนั้นจึงบอกได้ว่าระบบนี้จะสามารถใช้ replicated caching ได้ เหมาะสมแค่ไหน ตัวอย่างเช่น ลองพิจารณาค่าต่าง ๆ ใน Table 16-2 สำหรับปัจจัยที่เกี่ยวข้องในการคำนวณนี้

Table 16-2. ค่าฐาน (Base Values)

Update rate (UR):

20 updates/second

จำนวน Instance (N):

5

ขนาด Cache (S):

50,000 แถว

Replication latency (RL):

100 มิลลิวินาที

จำนวนการอัปเดต:

72,000 ครั้งต่อชั่วโมง

อัตรา Collision:

14.4 ครั้งต่อชั่วโมง

เปอร์เซ็นต์:

0.02%

การใช้ปัจจัยเหล่านี้ในสูตรจะได้ 72,000 การอัปเดตต่อชั่วโมง โดยมีความน่าจะเป็นสูงที่ 14 การอัปเดตต่อ ข้อมูลชุดเดียวกัน อาจ เกิด collision กัน เนื่องจากเปอร์เซ็นต์ต่ำ (0.02%) การทำ replication จึงเป็นตัวเลือกที่ใช้ได้

ความแปรผันของ RL สามารถส่งผลกระทบอย่างมากต่อ data consistency replication latency ขึ้นอยู่กับหลาย ปัจจัย รวมถึงประเภทของเครือข่ายและระยะทางทางกายภาพระหว่าง processing unit ค่า RL ต้องถูกคำนวณและได้ มาจากการวัดจริงใน production environment ซึ่งเป็นเหตุผลว่าทำไมจึงไม่ค่อยมีการเผยแพร่ ค่า 100 ms ที่ใช้ ในตัวอย่างก่อนหน้าเป็นตัวเลขวางแผนที่ดี หากไม่มีค่า RL จริง ตัวอย่างเช่น การเปลี่ยน RL จาก 100 ms เป็น 1 ms จะให้จำนวนการอัปเดตเท่าเดิม (72,000 ต่อชั่วโมง) แต่ทำให้ความน่าจะเป็นที่จะเกิด collision ต่ำลง มาก (0.1 collision ต่อชั่วโมง) สถานการณ์นี้แสดงอยู่ใน Table 16-3 .

Table 16-3. ผลกระทบของ Replication Latency

Update rate (UR):

20 updates/second

จำนวน Instance (N):

5

ขนาด Cache (S):

50,000 แถว

Replication latency (RL):

1 มิลลิวินาที (เปลี่ยนจาก 100)

จำนวนการอัปเดต:

72,000 ครั้งต่อชั่วโมง

อัตรา Collision:

0.1 ครั้งต่อชั่วโมง

เปอร์เซ็นต์:

0.0002%

จำนวน processing unit ที่มี cache ชื่อเดียวกัน (แทนด้วย N ) ก็มีความสัมพันธ์แบบแปรผันตรงกับจำนวน data collision ที่อาจเกิดขึ้นเช่นกัน ตัวอย่างเช่น การลดจำนวน processing unit จาก 5 instance เหลือ 2 instance จะให้อัตรา data-collision เพียง 6 ครั้งต่อชั่วโมง จากการอัปเดต 72,000 ครั้งต่อชั่วโมง ดังแสดงใน Table 16-4 .

Table 16-4. ผลกระทบของจำนวน Processing-Unit Instance

Update rate (UR):

20 updates/second

จำนวน Instance (N):

2 (เปลี่ยนจาก 5)

ขนาด Cache (S):

50,000 แถว

Replication latency (RL):

100 มิลลิวินาที

จำนวนการอัปเดต:

72,000 ครั้งต่อชั่วโมง

อัตรา Collision:

5.8 ครั้งต่อชั่วโมง

เปอร์เซ็นต์:

0.008%

ขนาดของ cache เป็นปัจจัยเดียวที่แปรผกผันกับอัตรา collision คือเมื่อขนาด cache ลดลง อัตรา collision จะเพิ่มขึ้น ในตัวอย่างนี้ การลดขนาด cache จาก 50,000 แถว เหลือ 10,000 แถว (โดยให้ปัจจัยอื่นเหมือนเดิม กับตัวอย่างแรก) จะให้อัตรา collision 72 ครั้งต่อชั่วโมง ซึ่งสูงกว่าตอนที่มี 50,000 แถวอย่างมาก ดัง แสดงใน Table 16-5 .

Table 16-5. ผลกระทบของขนาด Cache

Update rate (UR):

20 updates/second

จำนวน Instance (N):

5

ขนาด Cache (S):

10,000 แถว (เปลี่ยนจาก 50,000)

Replication latency (RL):

100 มิลลิวินาที

จำนวนการอัปเดต:

72,000 ครั้งต่อชั่วโมง

อัตรา Collision:

72.0 ครั้งต่อชั่วโมง

เปอร์เซ็นต์:

0.1%

โดยทั่วไป ระบบส่วนใหญ่จะไม่มี update rate ที่คงที่ตลอดช่วงเวลานาน ๆ (เช่น วันทำงานแปดชั่วโมง) เมื่อใช้ การคำนวณนี้ เราแนะนำให้ทำความเข้าใจ maximum update rate ของระบบในช่วง peak usage และคำนวณอัตรา collision ทั้งขั้นต่ำ ปกติ และช่วง peak .