ไอเดียออกแบบระบบจอง

เมื่อเช้าวันที่ 24 มกราคม 2564 มีคนแห่จองหุ้น OR ทางเว็บ K-My Invest เป็นจำนวนมาก จนเว็บล่มเป็นระยะๆ เลยจะมาเล่าไอเดียการออกแบบระบบจอง แบบสนุกๆ กัน 😉 (แต่ผมจองได้นะ เจอหน้า error ไม่กี่ครั้ง สาเหตุปลายทางน่าจะ test พลาด สาเหตุต้นทางน่าจะประเมิน scenario พลาด และการพัฒนาระบบพลาด แต่ก็เอาใจช่วยครับ สู้ๆ เลิฟๆ ปรึกษาอดีตผู้บริหารที่ย้ายไปอยู่ KTB ได้ครับ ว่าเขาทำยังไงให้รับมือคนเข้ามาสมัครสิทธิโครงการคนละครึ่งได้ 1.34 ล้านคนเสร็จใน 9 นาที)

ระบบจองแบบที่ ‘อาจชนกันระดับข้อมูล’ มีหลายประเภท เช่น ระบบจองตั๋วภาพยนตร์, ระบบจองตั๋วการแสดงโชว์/คอนเสิร์ตแบบตั๋วผูกกับเลขที่นั่ง, ระบบจองตั๋วเครื่องบิน/รถไฟ/รถโดยสาร และรวมถึงระบบจองหุ้น, ระบบสมัครใช้สิทธิโครงการ ‘คนละครึ่ง’ และอีกหลายโครงการของภาครัฐ

ระบบแบบนี้มีคุณลักษณะ (characteristics) คล้ายกันหลักๆ ได้แก่

  1. คนจำนวนมากจากทุกสารทิศเข้ามา access ระบบพร้อมๆ กัน
  2. สินค้า (ตั๋ว/ที่นั่ง/สิทธิ/จำนวนหุ้น) มีจำนวนจำกัด
  3. มีความต้องการจองสินค้าเดียวกันพร้อมกัน (แบบจองตั๋วหนักสุด)
  4. มีระยะเวลาจองจำกัด

technical concern สำคัญ ได้แก่

  1. load & I/O ไล่ตั้งแต่เน็ตเวิร์กยัน bus ในเครื่องเลย
  2. state ของสินค้า
  3. operation เช่น ค้นหา แสดงผล จอง ยกเลิก ชำระเงิน
  4. ลูกค้า/ผู้ใช้บริการ ซื้อ/จอง/ใช้สิทธิ ได้ครั้งละเท่าไหร่ เช่น โครงการคนละครึ่งใช้ได้ 1 คน/1 สิทธิ, จองหุ้น OR ขั้นต่ำ 300 หุ้น
  5. resource utilization เช่น IT resource capacity ที่มีในมือ
  6. existing resources เช่น database, web/app server เป็นแบบไหน รองรับ scale out ได้หรือไม่ และยิ่งถ้ามีแต่ RDBMS ก็ฉิบหายแน่ ไม่ต้องเปิดตัว รอล่มได้เลย

โซลูชั่น คร่าวๆ แบบไม่แตะทฤษฎีและศัพท์เฉพาะ และขออธิบายเฉพาะท่อนสินค้า เพราะท่อนจัดการ load & scale out สมัยนี้ทำไม่ยากแล้ว ใช้ตังค์โยนงานขึ้นไปรันบนเมฆโลด

  1. แบ่งสินค้าออกเป็นหลายๆ ส่วน หากแบ่งแต่ละส่วนจำนวนเท่าๆ กันก็ง่ายหน่อย เช่น สมมุติหุ้น OR ที่เปิดจองมีทั้งหมด 120 ล้านหุ้น แบ่งเป็น 400,000 ส่วน ส่วนละ 300 หุ้น เศษที่เหลือก็อยู่ในส่วนสุดท้ายไป
  2. จัดกลุ่มสินค้าแต่ละส่วนเป็นจำนวน N กลุ่ม เช่น จัดกลุ่มละ 1,000 ส่วน จะได้กลุ่มละ 300,000 หุ้น ให้นึกถึงการเอาลูกสตรอเบอรี่ใส่กล่องกล่องละ 300 ลูก แล้วเอามาจัดกลุ่มกลุ่มละ 1,000 กล่อง
  3. กระจายสินค้าแต่ละกลุ่มไปเก็บคนละเครื่องกัน
  4. แต่ละเครื่องลง agent เพื่อติดตามสถานะคงเหลือของจำนวนกลุ่มสินค้า แล้วแจ้งสถานะไปยังเครื่องกลางที่แยกต่างหากเพื่อติดตามสถานะสินค้าในทุกเครื่อง
  5. ใช้การกระจาย load และ I/O โดยเมื่อมี request ของลูกค้า/ผู้ใช้บริการเข้ามาถึงระบบ ผ่านจุดต่างๆ เข้ามา จนจะถึงส่วนสินค้า ก็กระจาย request ไปยังเครื่องต่างๆ แบบสุ่ม
  6. หากจำนวนกลุ่มสินค้าในเครื่องใดมีเหลือน้อยกว่าความต้องการซื้อ/จองของลูกค้า/ผู้ใช้บริการคนใด ก็ฟอร์เวิร์ด request ไปยังเครื่องอื่นที่มีจำนวนเหลือพอ
  7. มีระบบ registry เพื่อบันทึกและค้นคืนสถานะจำนวนกลุ่มสินค้าในแต่ละเครื่อง จะได้ทราบว่าเครื่องไหนเหลือเท่าไหร่ แล้วหากเครื่องไหนไม่พอควรฟอร์เวิร์ด request ไปเครื่องไหนดี
  8. หาก stream I/O (request) ไหลทะลักเข้ามาล้นหลามราวน้ำป่าไหลหลาก ก็ต้องมีการ ‘หน่วงน้ำ’ และ ‘พักน้ำ’ และ ‘ระบายน้ำ’- หน่วงน้ำ และ พักน้ำ ด้วยการเอา request ไปเข้าคิว ในหน้าจอก็ขึ้นอะไรเพลินๆ ให้ลูกค้า/ผู้ใช้บริการดูหรือเล่นสนุกๆ รอไป แต่อย่าเสือกขึ้น error มันไม่เท่ จะทำให้ UX เสีย- พักน้ำ ข้อมูลกลุ่มสินค้าควรใช้เป็น in-memory เพื่อลด latency ในการ access disk แต่ถ้าใช้ cloud ค่า memory usage มันแพง จะใช้ disk ก็ได้ ถ้าลูกค้าไม่ด่าหากช้า- ระบายน้ำ ด้วยการโยน request ไปรันบนเมฆ แต่ต้องทำ provisioning รอไว้ก่อน ไม่ใช่อิมโพรไวซ์ด้นสด การ spawn instance ใหม่ไม่ใช่ 2 วิเสร็จ
  9. ออกแบบการจัดการทรานแซกชั่นจังหวะ จอง ยกเลิก จองเพิ่ม จองใหม่ โดยจัดการ state ดีๆ พยายามให้เป็น stateless ให้มากที่สุดเท่าที่จะเป็นได้ เช่น ถ้าจองปุ๊บก็ล็อกปั๊บ แล้วให้เวลาไปจ่ายเงิน เช่น 15 นาที ไม่เสร็จก็ยกเลิกการจองอัตโนมัติไป
  10. การแบ่งกลุ่ม, การกำหนดจำนวนกลุ่ม, การกำหนดจำนวนสินค้าต่อกลุ่ม, การออกแบบทรานแซกชั่น ต้องเข้าใจ business logic & business process & business concern & business constraint & business goal & requirement อย่างดี ไอทีอย่านั่งเทียนมั่วนิ่มคิดเอง

จริงๆ ยังมีอีกครับ แต่ขี้เกียจพิมพ์ละ ชักยาว จริงๆ มันคือการทำ multiple pool & pool partition, การจัดคิว, การทำ shadow process (หลอกให้ผู้ใช้เพลินกับหน้าจอไปก่อน แล้วแอบทำบางอย่างไป) จริงๆ มีศัพท์ที่คนทำส่วน frontend เค้าใช้กัน แต่ผมจำชื่อไม่ได้ นอกจากนี้ก็ใช้ cache, cloud, logging & monitoring, asynchronous, load balance

ที่เล่ามาทั้งหมด สังเกตได้ว่า ผมไม่แตะเทคโนโลยีสักเท่าใดเลยนะครับ เพราะผมไม่ชอบเริ่มแก้ปัญหาด้วยเทคโนโลยี แต่เริ่มด้วย design principle แทนครับ เพราะมัน beyond technology & implementation

ซึ่ง technology & implementation หรือ How ควรมาทีหลังครับ เราต้องเคลียร์กับ problem context, problem domain, business & system characteristics ก่อน

หุ้น และ สิทธิโครงการคนละครึ่ง มันไม่มี identity ไม่เหมือน ตั๋วภาพยนตร์ ตั๋วเครื่องบินที่มี identity เพราะผูกกับที่นั่ง ดังนั้น การจอง หุ้น และ สิทธิโครงการคนละครึ่ง จึงง่ายกว่าหน่อย และ เล่นกับการกระจาย I/O ได้เต็มที่กว่าจริงๆ ระบบจองตั๋วที่ผูกกับที่นั่งจะเล่นกับการกระจาย I/O จัดๆ ก็ได้ แต่ต้องออกแบบระบบ registry ดีๆ เร็วๆ

ในโลกการลงทุน มีระบบประเภทหนึ่งที่รันอยู่ในโลกตรงกลางระหว่างลูกค้า/ผู้ใช้บริการ กับ ปลายทาง (ตลาด/โบรกเกอร์) เรียกว่า dark pool เราจองหุ้น ซื้อ/ขายหุ้น เราไม่เห็นอยู่แล้วนี่ ว่า…เกิดอะไรขึ้นในนั้น ตั้งแต่คำสั่งออกจากเครื่องของเรา ก่อนไปถึงปลายทางหรือตลาดฯ หรือแม้แต่เมื่อไปถึงปลายทางแล้ว?

หวังว่าที่พิมพ์มายาวเหยียดจะพอเป็นประโยชน์ไม่มากก็น้อยนะครับ ^^

ใส่ความเห็น