Start Small (เริ่มต้นเล็กๆ)
ใน The Art of Computer Programming (Addison-Wesley) Donald Knuth เคยกล่าวไว้อย่างมีชื่อเสียงว่า:
The real problem is that programmers have spent far too much time worrying about efficiency in the wrong places and at the wrong times; premature optimization is the root of all evil (or at least most of it) in programming.
การ optimize ระบบของเราเพื่อแก้ปัญหาที่เราไม่มีเป็นวิธีที่ดีในการเสียเวลาที่สามารถใช้ทำกิจกรรมอื่นได้ดีกว่า และยังทำให้เรามั่นใจได้ว่าเรามีระบบที่ซับซ้อนขึ้นโดยไม่จำเป็น การ optimize รูปแบบใดก็ตามควรถูกขับเคลื่อนโดยความต้องการจริง ตามที่เราพูดถึงใน "Robustness" การเพิ่มความซับซ้อนใหม่เข้าไปในระบบของเราสามารถนำเข้าจุดเปราะบางใหม่ๆ ได้ด้วยเช่นกัน ด้วยการ scale ส่วนหนึ่งของแอปพลิเคชันของเรา เราสร้างจุดอ่อนที่อื่น microservice Order ของเราอาจกำลังรันบน infrastructure ของตัวเองแล้ว ช่วยให้เรารับมือโหลดของระบบได้ดีขึ้น แต่เราก็มี microservice อีกตัวที่เราต้องมั่นใจว่ามันพร้อมใช้งานถ้าเราต้องการให้ระบบของเราทำงานได้ และ infrastructure เพิ่มเติมที่ต้องจัดการและทำให้ทนทาน
แม้ว่าคุณจะคิดว่าคุณระบุ bottleneck ได้แล้ว กระบวนการทดลองเป็นสิ่งสำคัญเพื่อให้แน่ใจว่าคุณคิดถูกและงานเพิ่มเติมมีเหตุผลรองรับ ผมทึ่งมากที่คนจำนวนมากที่จะเรียกตัวเองอย่างมีความสุขว่าเป็นนักวิทยาศาสตร์คอมพิวเตอร์ ดูเหมือนจะไม่มีความเข้าใจพื้นฐานเกี่ยวกับ scientific method เลยด้วยซ้ำ 5 ถ้าคุณระบุสิ่งที่คุณคิดว่าเป็นปัญหาแล้ว ลองระบุงานจำนวนเล็กน้อยที่สามารถทำได้เพื่อยืนยันว่าโซลูชันที่คุณเสนอจะใช้ได้ผลหรือไม่ ในบริบทของการ scale ระบบเพื่อรับมือโหลด การมีชุด automated load test เป็นตัวอย่างเช่น สามารถมีประโยชน์อย่างมาก รันเทสต์เพื่อได้ baseline และสร้าง bottleneck ที่คุณกำลังเจอขึ้นมาใหม่ ทำการเปลี่ยนแปลง และสังเกตความแตกต่าง นี่ไม่ใช่เรื่องยากอะไร แต่มันคือความพยายามที่จะเป็นวิทยาศาสตร์ในระดับหนึ่ง แม้จะเล็กน้อยมากก็ตาม
CQRS and Event Sourcing (CQRS และ Event Sourcing)
Pattern Command Query Responsibility Segregation (CQRS) หมายถึงโมเดลทางเลือกสำหรับการเก็บและ query ข้อมูล แทนที่เราจะมีโมเดลเดียวสำหรับทั้งการจัดการและดึงข้อมูล อย่างที่พบได้ทั่วไป ความรับผิดชอบสำหรับการอ่านและการเขียนถูกจัดการโดยโมเดลที่แยกกันแทน โมเดลอ่านและเขียนที่แยกกันเหล่านี้ ซึ่ง implement ในโค้ด สามารถ deploy เป็นหน่วยแยกกันได้ ให้ความสามารถแก่เราในการ scale การอ่านและเขียนแยกจากกัน CQRS มักถูกใช้ร่วมกับ event sourcing แม้จะไม่เสมอไป ซึ่ง—แทนที่จะเก็บสถานะปัจจุบันของ entity เป็น record เดียว—เราแทนที่ project สถานะของ entity ด้วยการดูประวัติของ event ที่เกี่ยวข้องกับ entity นั้น
อาจกล่าวได้ว่า CQRS กำลังทำสิ่งที่คล้ายกันมากใน application tier ของเรากับสิ่งที่ read replica ทำได้ใน data tier แม้ว่าเนื่องจากมีวิธีที่แตกต่างกันมากมายในการ implement CQRS นี่จึงเป็นการทำให้เรื่องง่ายเกินไป
ส่วนตัว แม้ว่าผมจะเห็นคุณค่าใน CQRS pattern ในบางสถานการณ์ มันเป็น pattern ที่ซับซ้อนที่จะทำให้ดีได้ ผมเคยคุยกับคนที่ฉลาดมากที่เจอปัญหาไม่น้อยในการทำให้ CQRS ใช้งานได้ ดังนั้น ถ้าคุณกำลังพิจารณา CQRS เป็นวิธีช่วย scale แอปพลิเคชันของคุณ ให้มองว่ามันเป็นหนึ่งใน scaling รูปแบบที่ยากที่สุดที่คุณจะต้อง implement และบางทีควรลองสิ่งที่ง่ายกว่าก่อน ตัวอย่างเช่น ถ้าคุณถูกจำกัดแค่การอ่านเท่านั้น read replica อาจเป็นวิธีที่มีความเสี่ยงน้อยกว่ามากและเร็วกว่าในการเริ่มต้น ความกังวลของผมเกี่ยวกับความซับซ้อนของการ implement นี้ขยายไปถึง event sourcing ด้วย—มีบางสถานการณ์ที่มันเหมาะสมมาก แต่มันก็มาพร้อมกับความปวดหัวหลายอย่างที่ต้องรองรับ ทั้งสอง pattern ต้องการการเปลี่ยนวิธีคิดค่อนข้างมากสำหรับนักพัฒนา ซึ่งทำให้สิ่งต่างๆ ท้าทายขึ้นเสมอ ถ้าคุณตัดสินใจใช้ pattern เหล่านี้ตัวใดตัวหนึ่ง แค่ต้องมั่นใจว่าภาระทางความคิดที่เพิ่มขึ้นบนนักพัฒนาของคุณนี้คุ้มค่า
ข้อสังเกตสุดท้ายเกี่ยวกับ CQRS และ event sourcing: จากมุมมองของสถาปัตยกรรม microservice การตัดสินใจใช้หรือไม่ใช้เทคนิคเหล่านี้เป็นรายละเอียด implementation ภายในของ microservice ถ้าคุณตัดสินใจ implement microservice โดยแบ่งความรับผิดชอบสำหรับการอ่านและการเขียนข้าม process และโมเดลที่แตกต่างกัน ตัวอย่างเช่น สิ่งนี้ควรมองไม่เห็นสำหรับ consumer ของ microservice ถ้า inbound request ต้อง redirect ไปยังโมเดลที่เหมาะสมตาม request ที่ทำ ให้สิ่งนี้เป็นความรับผิดชอบของ microservice ที่ implement CQRS การเก็บรายละเอียด implementation เหล่านี้ให้ซ่อนจาก consumer ให้ความยืดหยุ่นมากในการเปลี่ยนใจในภายหลัง หรือเปลี่ยนวิธีที่คุณใช้ pattern เหล่านี้