Overview and System Design of Scalable E-commerce Platforms

บทความโดย ผศ.ดร.ณัฐโชติ พรหมฤทธิ์ และ อ.ดร.สัจจาภรณ์ ไวจรรยา
ภาควิชาคอมพิวเตอร์
คณะวิทยาศาสตร์
มหาวิทยาลัยศิลปากร



ยินดีต้อนรับสู่วิชา Server Side Web Programming วิชานี้จะมีการใช้ Use Case จริง ตามแนวทางของการพัฒนา E-commerce Platform ที่ประสบความสำเร็จในระดับโลก โดยในบทแรกเราจะเริ่มต้นการเดินทางด้วยการออกแบบ E-commerce Platform ให้สามารถรองรับผู้ใช้งานได้จำนวนหลายล้านคน

เมื่อพูดถึง E-commerce ไม่ใช่เพียงแค่เป็นเรื่องของการซื้อขายสินค้าออนไลน์ แต่หลังบ้านของมันเป็นระบบซับซ้อนที่ต้องมีการจัดการกับความท้าทายหลายด้าน ทั้งต้องรองรับปริมาณการใช้งานที่สูง (High Scalability) ต้องสามารถประมวลผลธุรกรรมจำนวนมาก (High Throughput) ในช่วง Flash Sale และการให้บริการที่ต้องรวดเร็วและเชื่อถือได้ตลอด 24 ชั่วโมง (High Availability)

เราจะเจาะลึกถึงภาพรวมของการพัฒนา E-commerce Platform โดยเริ่มจากการทำความเข้าใจ User Journey Flow ซึ่งจะช่วยให้เราเห็นภาพประสบการณ์ของผู้ใช้งาน E-commerce Platform ตั้งแต่การเข้าชม Website จนการทำธุรกรรมเสร็จสิ้น จากนั้น เราจะวิเคราะห์ปัญหา ความต้องการ ที่มักพบในการพัฒนา E-commerce Platform ขนาดใหญ่ และเรียนรู้วิธีการกำหนดขอบเขตการออกแบบที่เหมาะสม

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

เราจะปิดท้ายด้วยการศึกษาวิธีการออกแบบระบบแบบ Microservice Architecture ซึ่งเป็นแนวทางหนึ่งที่จะช่วยพัฒนาระบบขนาดใหญ่ที่มีความยืดหยุ่น ปรับขนาดได้ และสามารถบำรุงรักษาได้ง่าย รวมทั้งการจัดกลุ่ม User Journey ตาม Service หลัก ๆ

เมื่อจบบทนี้ เราจะมีพื้นฐานที่แข็งแกร่งเกี่ยวกับการออกแบบ E-commerce Platform และพร้อมที่จะเริ่มต้นการเดินทางสู่การเป็น Back End Developer หรือ Back End Engineer ที่มีความเชี่ยวชาญ

blog.bytebytego.com

เราจะเริ่มต้นการสร้างรากฐานสำหรับการพัฒนา E-commerce Platform ที่ยอดเยี่ยมด้วยกัน!

User Journey Flow

เราจะใช้ User Journey Flow ในการอธิบาย Scenario ต่าง ๆ ที่ลูกค้าคนหนึ่งจะซื้อสินค้าออนไลน์บน Platform ของเรา ดังตัวอย่างต่อไปนี้

สมมติว่า ลูกค้าสามารถเข้าสู่ระบบ E-commerce Platform หนึ่ง เพื่อซื้อสินค้าได้ 2 วิธี คือ 1. การเข้าสู่ระบบด้วย Account ที่สมัคร และ 2. การเข้าสู่ระบบด้วย Email OTP

เข้าสู่ระบบด้วย Account ที่สมัคร
1. ลูกค้าเข้าสู่เว็บไซต์ E-commerce
2. ลูกค้าสร้างบัญชีใหม่
3. ลูกค้าเข้าสู่ระบบด้วย Account ที่สร้าง -> ไปข้อที่ 8

เข้าสู่ระบบด้วย Email OTP
4. ลูกค้าเข้าสู่เว็บไซต์ E-commerce
5. ลูกค้ากรอก Email เพื่อยืนยันตัวตน
6. ระบบส่ง OTP ผ่าน Email
7. ลูกค้าเข้าสู่ระบบด้วย OTP ที่ส่งมาทาง Email -> ไปข้อที่ 8

8. ลูกค้าเรียกดูสินค้าผ่านหน้าแรก ดูตามหมวดหมู่สินค้า หรือการค้นหาด้วยการใส่คำค้น
9. ระบบแสดงรายการสินค้าพร้อมข้อมูล เช่น ชื่อ SKU ราคา รูปภาพ จำนวนที่ขายได้ ชื่อร้านค้า ส่วนลด (ส่วนลดจากร้าน และ Code ส่วนลด) คะแนนรีวิว
10. ลูกค้าเลือกดูรายละเอียดสินค้าที่สนใจ เช่น คำบรรยาย คุณสมบัติสินค้า การรับประกันและการคืนสินค้า
11. ลูกค้าเลือกจำนวนสินค้า
12. ลูกค้าเพิ่มสินค้าลงตะกร้า
13. ระบบแสดงโปรโมชั่นที่สามารถใช้ได้
14. ลูกค้าใส่รหัสคูปอง
15. ลูกค้าเลือกใช้คะแนนสะสม (ถ้ามี)
16. ลูกค้าเลือกวิธีการชำระเงิน
17. ลูกค้ากรอกข้อมูลที่อยู่จัดส่งและเลือกวิธีการจัดส่ง
18. ระบบคำนวณค่าจัดส่งและแสดงผลรวมราคาทั้งหมด
19. ลูกค้ากรอกข้อมูลการชำระเงิน
20. ระบบประสานงานกับระบบชำระเงินภายนอกเพื่อดำเนินการชำระเงิน
21 ระบบแจ้งผลการชำระเงินให้ลูกค้าทราบ
22. ระบบส่งอีเมลยืนยันคำสั่งซื้อให้ลูกค้า
23. ระบบอัพเดตสถานะคำสั่งซื้อเป็น "ชำระเงินแล้ว"
24. เมื่อได้รับการยืนยันการชำระเงิน, ระบบจะส่งคำสั่งซื้อไปยังคลังสินค้าเพื่อเตรียมจัดส่ง
25 ระบบจัดส่งสินค้าและอัพเดตสถานะคำสั่งซื้อเป็น "กำลังจัดส่ง"
26. ลูกค้าสามารถติดตามสถานะการจัดส่งผ่านเว็บไซต์
27. ลูกค้าได้รับสินค้า
28. ระบบอัพเดตสถานะคำสั่งซื้อเป็น "จัดส่งสำเร็จ"
29. ลูกค้าเขียนรีวิวและให้คะแนนสินค้า
30. ลูกค้าคืนสินค้าที่ไม่ต้องการ
31 ระบบดำเนินการตามนโยบายการคืนสินค้า

หน้าตาของ User Journey Flow จะเป็นไปตามภาพด้านล่าง ซึ่งเราจะยึดแนวทางการพัฒนา E-commerce Platform ตาม User Journey Flow นี้ไปจนจบ Course ครับ

Understand the Problem and Requirements

การสัมภาษณ์ Domain Expert ด้วยคำถามปลายเปิด เป็นวิธีหนึ่งในการทำความเข้าใจปัญหาและความต้องการ (Function Requirement) รวมทั้งเพื่อประเมิน Non-function Requirement สำหรับการออกแบบระบบให้มีประสิทธิภาพ โดยมีตัวอย่างดังต่อไปนี้

Interviewer: ลักษณะของ E-commerce Platform ที่เรากำลังพัฒนาเป็นอย่างไร
Domain Expert: เรากำลังจะพัฒนา Backend ของ E-commerce Platform อย่างเช่น NocNoc, Shopee, Lazada และ Amazon โดยจะมีการจัดการทุกอย่างเกี่ยวกับการขายสินค้าออนไลน์ จนการทำธุรกรรมเสร็จสิ้น

Interviewer: มีร้านค้ากี่ร้านบน Platform
Domain Expert: สมมติว่าเรากําลังสร้าง E-commerce Platform ที่มีร้านค้าจำนวน 10,000 ร้าน และสินค้า 500,000 SKU

Interviewer: ลูกค้าสามารถซื้อสินค้าจากหลายร้านได้พร้อมกันหรือไม่
Domain Expert: ได้

Interviewer: เราจะจัดการเรื่องการจัดส่งสินค้าอย่างไร
Domain Expert: เราจะใช้บริการขนส่งของบุคคลที่สาม แต่เราต้องมีการติดตามสถานะการจัดส่งในระบบของเรา

Interviewer: เราจะจัดการเรื่องสินค้าคงคลังอย่างไร
Domain Expert: ร้านค้าแต่ละร้านจะจัดการสินค้าคงคลังของตนเอง โดยเราต้องมีระบบที่อัปเดตสถานะสินค้าคงคลังแบบเรียลไทม์

Interviewer: เราต้องรองรับฟีเจอร์อะไรบ้างสำหรับผู้ซื้อและผู้ขาย
Domain Expert: สำหรับผู้ซื้อ เราต้องมีระบบค้นหาสินค้า ตะกร้าสินค้า ระบบรีวิวและให้คะแนน และประวัติการสั่งซื้อ สำหรับผู้ขาย เราต้องมีระบบจัดการสินค้า การจัดการคำสั่งซื้อ และรายงานยอดขาย

Interviewer: เราจะจัดการเรื่องโปรโมชั่นและส่วนลดอย่างไร
Domain Expert: ระบบต้องรองรับทั้งโปรโมชั่นที่จัดโดย Platform และจัดโดยร้านค้าแต่ละร้าน

Interviewer: Platform จะมีช่วง Flash Sale หรือไม่
Domain Expert: มี ระบบควรต้องรองรับการทํางานพร้อมกันสูง ในช่วง Flash Sale สินค้าบางรายการอาจมีลูกค้าจํานวนมากที่พยายามซื้อพร้อมกัน

Interviewer: ลูกค้าสามารถยกเลิกการซื้อของพวกเขาได้หรือไม่
Domain Expert: ได้

Interviewer: มีตัวเลือกในการชำระเงินแบบใดที่รองรับบ้าง เช่น Credit cards, PayPal, Bank cards, Line Pay ฯลฯ
Domain Expert: ระบบการชําระเงินควรรองรับตัวเลือกเหล่านี้ทั้งหมดในชีวิตจริง อย่างไรก็ตาม ในการ Course นี้ เราสามารถใช้การชําระเงินด้วย Line Pay เป็นตัวอย่างได้

Interviewer: Platform เป็นสากลหรือไม่? เราจําเป็นต้องสนับสนุนภาษา และสกุลเงินที่แตกต่างกันและการชําระเงินระหว่างประเทศหรือไม่?
Domain Expert: เป็นคําถามที่ดี ใช่ Platform จะเป็นสากล แต่ในตอนแรก เราจะเริ่มต้นด้วยการค้าภายในประเทศก่อนโดยใช้ภาษาไทยและสกุลเงินบาท แต่ระบบควรรองรับการขยายไปสู่การค้าระหว่างประเทศในอนาคต

Interviewer: มีการขายสินค้ากี่รายการต่อวัน
Domain Expert: สมมติให้ Platform มีการขาย 1 ล้านธุรกรรมต่อวัน

Interviewer: เรามีข้อกำหนดเรื่องประสิทธิภาพของระบบไหม
Domain Expert: ระบบต้องรองรับการทำธุรกรรมได้อย่างน้อย 2,000 รายการต่อวินาที และต้องมี Uptime อย่างน้อย 99.99%

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

Back-of-the-envelope Estimation

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

ระบบจําเป็นต้องประมวลผลธุรกรรม 1 ล้านรายการต่อวัน ซึ่งเท่ากับ 1,000,000 ธุรกรรม / 10^5 วินาที = 10 ธุรกรรมต่อวินาที (TPS) ซึ่ง 10 TPS ในช่วงการซื้อขายปกติ ไม่ใช่ตัวเลขขนาดใหญ่สําหรับฐานข้อมูลทั่วไป แต่ในช่วง Flash Sale อาจมีจำนวนธุระกรรมสูงกว่านี้อีก หลายเท่า

ต่อไป เรามาคํานวณ QPS (Queries Per Second) คร่าวๆ ของทุกหน้าในระบบกัน จาก 4 ขั้นตอนหลัก ๆ ในซื้อสินค้าของลูกค้า ดังนี้

  1. ลูกค้าเรียกดูสินค้าผ่านหน้าแรก ดูตามหมวดหมู่สินค้า หรือจากการค้นหา
  2. ลูกค้าดูหน้ารายละเอียดสินค้าพร้อมข้อมูล เช่น ชื่อสินค้า ราคา รูปภาพ จำนวนที่ขายได้ ชื่อร้านค้า ส่วนลด (ส่วนลดจากร้าน และ Code ส่วนลด) คะแนนรีวิว และเลือกสินค้าลงตะกร้า
  3. ลูกค้ายืนยันการสั้งซื้อสินค้าในตะกร้า เช่น จํานวนสินค้า ข้อมูลการชําระเงินก่อนการจ่ายจริง
  4. ซื้อสินค้า ลูกค้าคลิกที่ปุ่ม "จ่ายเงิน" เพื่อซื้อสินค้า

สมมติว่าจากขั้นตอนที่ 1 จากจำนวนลูกค้า 100% จะมีลูกค้าประมาณ 70% ไปต่อยังขั้นตอน ที่ 2 และในขั้นตอนที่ 2 เป็นต้นไป จะมีลูกค้าประมาณ 10% ไปต่อยังหน้าถัดไป ในขณะที่ลูกค้า 90% ที่เหลือออกจาก Flow ไปก่อน จากข้อมูลด้านบนเรารู้ว่า TPS ของขั้นตอนสุดท้ายคือ 10 ดังนั้นเราจึงสามารถคำนวณ QPS ย้อนหลังได้ โดย QPS ของหน้ายืนยันคําสั่งซื้อ (ขั้นตอนที่ 3) คือ 100 และ QPS สําหรับหน้ารายละเอียด (ขั้นตอนที่ 2) คือ 1,000 และหน้าเรียกดูสินค้าผ่านหน้าแรก ตามหมวดหมู่สินค้า หรือการค้นหา (ขั้นตอนที่ 1) คือ 1,429

การทำความเข้าใจปัญหาความต้องการ และกำหนดขอบเขตเช่นนี้ ช่วยให้เรามีข้อมูลที่ชัดเจนสำหรับการออกแบบ E-commerce Platform โดยครอบคลุมทั้งฟังก์ชันการทำงานหลัก ขนาดของระบบ และความต้องการด้านประสิทธิภาพ

From Zero to Millions of Users : A Guide to Scaling an E-commerce Platform

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

Single Server Setup
เพื่อความง่ายของระบบ ทุก ๆ อย่างจะรันบน Server เพียงเครื่องเดียว ทั้ง Web App, Database และการจัดเก็บไฟล์

ผู้ใช้จะเข้าถึง Website ผ่าน Domain Name ซึ่งโดยปกติ Domain Name System จะถูกให้บริการอยู่ภายนอก Server ของเรา IP Address จะถูกส่งมาที่ Web Browser หรือ Mobile App หลังจากนั้น HTTP Request จะถูกส่งไปยัง Web Server โดยตรง

Server จะ Return HTML Page หรือ JavaScript Object Notation (JSON) Response สำหรับการ Render บน Browser

จากภาพด้านบนจะเห็นว่า Traffic สามารถมายัง Web Server ได้จาก 2 แหล่ง คือ Web Application และ Mobile Application โดย Web Application จะประกอบไปด้วย Server-site Language เช่น Java, Python, Golang เพื่อจัดการ Business Logic รวมทั้งการจัดเก็บข้อมูล และ Client-site Language เช่น HTML และ JavaScript สำหรับงาน Presentation

ขณะที่ Mobile Application จะมีการสื่อสารกันระหว่าง Mobile App และ Web Server ผ่าน API โดยมีการส่งข้อมูลกลับจาก API ในรูปแบบ JSON เป็นหลัก

Spit Services and Database
เมื่อมีผู้ใช้เพิ่มขึ้น Server เพียงตัวเดียวจะไม่เพียงพอสำหรับการให้บริการ เราต้องการ Server เพิ่มสำหรับ Web/Mobile Traffic, Database และการจัดเก็บไฟล์ ซึ่งการแบ่งองค์ประกอบเช่นนี้จะทำให้สามารถขยายขนาดในแต่ละส่วนได้อย่างอิสระ

เราสามารถเลือกได้ระหว่าง  SQL (Structured Query Language) Database และ NoSQL (Not Only SQL) Database

SQL Database คือ Relational Database ที่ใช้ Structured Query Languag (SQL) เพื่อนิยามโครงสร้าง (Schema) และจัดการกับข้อมูลที่จัดเก็บในรูป Table ที่มีความสัมพันธ์กัน ทำให้เราสามารถใช้คำสั่งในการ Join ข้อมูลที่อยู่ต่าง Table กันได้

SQL Database เรียกอีกอย่างหนึ่งว่า Relational Database Management System (RDBMS) ซึ่ง RDBMS ที่เป็นที่นิยมในปัจจุบัน เช่น MySQL, PostgreSQL, Oracle, Microsoft SQL Server

ขณะที่  NoSQL Database คือ Non-relational Database ที่สามารถจัดการกับข้อมูลได้หลากหลาย เช่น ข้อมูลแบบ Document, Key-value, Wide-column และ Graph ที่ไม่ต้องการ Schema ที่คงที่เหมือนกับ SQL Database ทําให้โครงสร้างของข้อมูลสามารถเปลี่ยนแปลงเมื่อเวลาผ่านไปได้

NoSQL Database ที่เป็นที่นิยมในปัจจุบัน เช่น MongoDB (Document), Redis (Key-Value), Cassandra (Wide-Column), Neo4j (Graph) ซึ่งเราไม่สามารถใช้คำสั่งในการ Join ข้อมูลได้เหมือนกับ SQL Database

สำหรับนักพัฒนาส่วนใหญ่ SQL Database เป็นตัวเลือกที่ดีเนื่องจากมีการใช้งานบน Production มาอย่างยาวนาน และได้รับการพิสูจน์ว่ามันทำงานได้ดี โดยเฉพาะการปฏิบัติตาม ACID เพื่อรับรองธุรกรรมที่ต้องเชื่อถือได้ (Atomicity, Consistency, Isolation, Durability) เช่นในระบบ Banking

อย่างไรก็ตาม หาก Application ของเราต้องการ Latency ต่ำ เช่น ระบบการซื้อขายหุ้น ระบบเกมออนไลน์ หรือระบบควบคุมทางอุตสาหกรรม และต้องจัดการกับข้อมูลที่มีรูปแบบหลากหลายจำนวนมาก รวมทั้งโครงสร้างของข้อมูลสามารถปลี่ยนแปลงได้เมื่อเวลาผ่านไป NoSQL Database อาจจะเป็นตัวเลือกที่ดี หรือบางระบบก็อาจเลือกใช้ทั้ง SQL Database และ NoSQL Database

Split Services into clusters
เมื่อธุรกิจยังคงเติบโตอย่างต่อเนื่อง Application Server เพียงเครื่องเดียวจะทำงานหนักเกินไป ดังนั้นเราจึงใช้กลุ่ม Application Server เพื่อกระจาย Request ที่เข้ามา ไปยัง Application Server โดยเบื้องต้นอาจใช้เทคนิค Round Robin ของ DNS ก็ได้

Add load balancer
อย่างไรก็ตาม การใช้ DNS ในการกระจาย Request อาจไม่ใช่วิธีที่ดีนัก เนื่องจากมันไม่ได้ถูกออกแบบมาในการกระจายภาระงานโดยเฉพาะเหมือน Load balancer

เราจะวาง Load balancer ระหว่าง Web Browser/Mobile App และ Application Server โดย Load balancer จะกระจายโหลดจาก Client ไปยัง Application Server หลาย ๆ ตัว

ด้วยการใช้ Load balancer เราจะใช้ประโยชน์จากการทำ Failure Handling ซึ่งหาก Application Server เครื่องหนึ่งล้มเหลว Load balancer จะส่ง Request ไปยัง Server ที่มีสุขภาพดีให้โดยอัตโนมัติ ทำให้ระบบมีความพร้อมใช้งานและความยืดหยุ่นสูง

นอกจากการทำ Failure Handling แล้ว Load balancer จะติดตามสุขภาพของ Application Server แต่ละเครื่องเป็นระยะ ๆ และนําแต่ละ Server เข้าและออกจาก List การให้บริการของมันโดยอัตโนมัติตามสุขภาพของ Server ที่มีการเช็ค (Instance Health Check) ทําให้การให้บริการซอฟต์แวร์ไม่หยุดชะงักจากมุมมองของผู้ใช้ แม้จะมี Application Server บางตัวไม่สามารถให้บริการได้ แต่ก็ต้องการ Application Server แบบ Stateless ที่ไม่มีการเก็บข้อมูลต่าง ๆ เช่น Session เอาไว้ภายใน Server เนื่องจากการเข้ามาของผู้ใช้งานในครั้งต่อ ๆ ไป อาจจะไม่ได้เข้ามาที่เครื่องเดิมก็ได้

Separate DB read/write
ในขณะที่ธุรกิจของเรายังคงขยายขนาดต่อไป ปัญหาคอขวดเริ่มปรากฎขึ้น แม้เราจะมีการ Split Service และ Add load balancer แล้ว Database น่าจะเป็นอย่างแรกที่มีปัญหา

ใน E-commerce Platform ของเรา ลูกค้าจะเริ่มพบกับความล่าช้าเมื่อมีการค้นหาสินค้า ปัญหาคอขวดที่ Database ทำให้มันต้องรับมือกับการ Query (Read Transaction) ที่เข้ามาเป็นจำนวนมาก ขณะที่ Write Transaction ก็ได้รับผลกระทบจากจำนวน TPS (Transactions Per Second) รวมของระบบ

วิธีในการแก้ปัญหาขอขวดของ Database ที่ตรงไปตรงมา คือ การทำ Database Replication เพื่อสร้างสำเนาข้อมูลหลายชุด ด้วยการกระจายข้อมูลไปยัง Server หรือ Node หลาย ๆ  ตัว

เรามักใช้รูปแบบ Leader-follower Replication Architecture ที่ Node หนึ่งจะถูกกำหนดให้เป็น Leader ขณะที่ Node อื่น ๆ เป็น Follower โดย Leader Node จะรับหน้าที่จัดการการเขียนทั้งหมด ทั้งการ Insert, Update และ Delete เพื่อรับประกันเรื่องความสอดคล้องและถูกต้องของข้อมูล รวมทั้งจัดการเรื่องการ Read ด้วย เมื่อใดก็ตามที่มีการ Write บน Leader Node การเปลี่ยนแปลงนั้นจะถูกทำสำเนาโดยอัตโนมัติไปยัง Follower Node

ขณะที่ Follower Node จะรับผิดชอบการ Read ควบคู่ไปกับ Leader Node

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

แต่ปัญหาหนึ่งของ Relational Database คือ การไม่ Support การค้นหาแบบ Fuzzy ครับ การค้นหาแบบ Fuzzy ช่วยให้เราสามารถค้นหาข้อมูลได้แม้จะมีการพิมพ์ผิดในคำค้น ซึ่งมีประโยชน์มากสำหรับธุรกิจแบบ E-commerce Platform ซึ่งลูกค้าควรต้องพบสินค้าโดยการไม่ต้องมีการจับคู่คำค้นกับข้อมูลใน Database

โดยส่วนหนึ่งของข้อมูลใน Database จะมีการถูกทำสำเนามายัง Full-text Search Engine อย่างเช่น Elasticsearch เพื่อใช้การค้นหาแบบ Fuzzy

ทั้งนี้หลังจากการ Scale Database ด้วย Architecture แบบ Leader-follower Replication แล้ว Application ส่วนใหญ่ควรสามารถรองรับผู้ใช้งานได้ถึงหลายแสนคน

Add cache
อย่างไรก็ตามสำหรับ Application อย่างเช่น E-commerce Platform ที่มีการ Read ข้อมูลจาก Database อย่างหนัก โดยเฉพาะในช่วง Flash Sale การใช้ Architecture แบบ Leader-follower Replication อาจไม่สามารถรับมือกับ Traffic ที่พุ่งสูงขึ้นได้ดี ทำให้ลูกค้าอาจไม่สามารถ Load หน้าดูสินค้าได้ เราจึงต้องมีการเพิ่ม Cache Layer เพื่อเพิ่มประสิทธิภาพในการ Read ข้อมูล

Redis เป็น In-memory Cache ที่ได้รับความนิยมในการลดภาระการ Read สำหรับ Database ด้วยการทำ Caching ข้อมูลที่เข้าถึงบ่อยไว้ในหน่วยความจำหลัก ที่มีความเร็วในระดับ 100 ns แทนที่จะดึงข้อมูลจาก Database ที่เก็บไว้บน Disk ที่มีความเร็วในระดับ 1 ms ซึ่งช้ากว่าอย่างมาก Redis ที่เป็น In-memory Cache จึงช่วยลด Load ของ Database Cluster และเพิ่มประสิทธิภาพของระบบโดยรวม

https://colin-scott.github.io/personal_website/research/interactive_latency.html

สำหรับข้อมูลแบบ Static Content เช่น รูปภาพ วีดีโอ และ Style Sheet เราสามารถทำ Caching ข้อมูลที่ไม่ถูก Update บ่อย ๆ ด้วยการใช้บริการ Content Delivery Network (CDN)

CDN Provider อย่างเช่น Cloudflare จะให้บริการ Static Content จากเครือข่าย Server ที่อยู่ใกล้ผู้ใช้ปลายทาง ทำให้สามารถช่วยลด Latency และปรับปรุงความเร็วในการ Load หน้าเว็บ ส่งผลให้ผู้ใช้ได้รับประสบการณ์ที่ดีในการเข้าใช้บริการ

DB Sharding
การเพิ่ม Cache Layer สามารถบรรเทา Application ที่มีการ Read อย่างหนัก แต่เมื่อมี Request สำหรับการ Write จำนวนมาก การใช้ Architecture แบบ Leader-follower Replication จะทำให้ Leader Node ทำงานหนักมากเกินไป DB Sharding จะช่วยกระจายการ Write ไปยัง Server หลาย ๆ ตัว

ในการทำ Sharding เราจะแบ่งส่วนของ Table กระจายเก็บแยกตาม Server ต่าง ๆ ยกตัวอย่างเช่น เราสามารถแบ่ง Table user แบบ Horizontal Sharding ตาม user ID หรือแบ่ง Table user แบบ Vertical Sharding ตาม Column

อย่างไรก็ตามการทำ Sharding จะเพิ่มความซับซ้อนให้กับ Application เพราะข้อมูลถูกแบ่งและกระจายเก็บใน Database หลายตัว (หลาย Shard) ทำให้ยากต่อการรับประกันความสอดคล้องและความถูกต้องของข้อมูล รวมทั้งเพิ่ม Latency ของระบบเมื่อต้องการรวบรวมข้อมูลจากหลาย ๆ Shard

Object Store
สำหรับ Application ที่มี Static Content เป็นส่วนสำคัญในการให้บริการ File Server 1 ตัว อาจไม่เพียงพอในการให้บริการ เราสามารถจัดเก็บ Static Content ใน Distributed Object Store อย่างเช่น AWS S3 ที่สามารถ Scale พื้นที่จัดเก็บได้ไม่จำกัด และมีความทนทานสูง รวมทั้งมีการเรียกใช้งานและจัดเก็บผ่าน API โดยมันจะเป็นต้นทางในการ Sync ข้อมูลกับ CDN Server โดยตรง

Split and modularize services into microservice
เมื่อธุรกิจขยายตัวต่อไป Business Logic จะมีการพัฒนาและมีความซับซ้อนขึ้นตามธรรมชาติ Feature และบริการจะถูกพัฒนาในจังหวะที่แตกต่างกันตามกำหนดการเปิดตัว

Microservice Architecture แบ่งโครงสร้างของ Application เป็นชุดของบริการขนาดเล็กและเป็นอิสระ โดยแต่ละบริการจะมีกิจกรรมของตนเองและสื่อสารกันผ่าน Protocal อย่างเช่น gRPC นอกจากนี้โดยปกติเรายังแบ่ง Layer การให้บริการคำขอจาก Client ผ่าน REST API หรือ GraphQL

Database ในแบบ Microservice Architecture มักจะมีการให้บริการเฉพาะและถูกจัดการโดยทีมงานที่เป็นเจ้าของ Service

สำหรับ Request ที่ไม่ต้องการ Latency สูง เราอาจพิจารณาส่งไปใน Message Queue ที่มีการประมวลผลแบบ Asynchronous

User Journey Grouping

จาก User Journey Flow ของ E-commerce Platform เราสามารถแบ่งกลุ่ม Journey ตาม Service ได้ทั้งหมด 12 Service

Core Service
1. Product
2. User
3. Inventory
4. Shopping Cart
5. Order
6. Payment

Supporting Service
7. Login
8. Notification
9. Promotion
10. Shipping
11. Review and Rating
12. Return and Refund

เราจะจัดให้ Product, User, Inventory, Shopping Cart, Order และ Payment เป็น Core Service และ Login, Notification, Promotion, Shipping, Review and Rating และ Return and Refund เป็น Supporting Service

โดยแต่ละ Journey เกี่ยวข้องกับ Service ต่าง ๆ ดังต่อไปนี้

เข้าสู่ระบบด้วย Account ที่สมัคร
Product
1. ลูกค้าเข้าสู่เว็บไซต์ E-commerce

User
2. ลูกค้าสร้างบัญชีใหม่

Login
3. ลูกค้าเข้าสู่ระบบด้วย Account ที่สร้าง -> ไปข้อที่ 8

เข้าสู่ระบบด้วย Email OTP
Product
4. ลูกค้าเข้าสู่เว็บไซต์ E-commerce

Login
5. ลูกค้ากรอก Email เพื่อยืนยันตัวตน

Notification
6. ระบบส่ง OTP ผ่าน Email

Login
7. ลูกค้าเข้าสู่ระบบด้วย OTP ที่ส่งมาทาง Email -> ไปข้อที่ 8

8. ลูกค้าเรียกดูสินค้าผ่านหน้าแรก ดูตามหมวดหมู่สินค้า หรือการค้นหาด้วยการใส่คำค้น
9. ระบบแสดงรายการสินค้าพร้อมข้อมูล เช่น ชื่อ SKU ราคา รูปภาพ จำนวนที่ขายได้ ชื่อร้านค้า ส่วนลด (ส่วนลดจากร้าน และ Code ส่วนลด) คะแนนรีวิว
10. ลูกค้าเลือกดูรายละเอียดสินค้าที่สนใจ เช่น คำบรรยาย คุณสมบัติสินค้า การรับประกันและการคืนสินค้า
11. ลูกค้าเลือกจำนวนสินค้า

Shopping Cart
12. ลูกค้าเพิ่มสินค้าลงตะกร้า

Promotion
13. ระบบแสดงโปรโมชั่นที่สามารถใช้ได้
14. ลูกค้าใส่รหัสคูปอง
15. ลูกค้าเลือกใช้คะแนนสะสม (ถ้ามี)

Order
16. ลูกค้าเลือกวิธีการชำระเงิน

Shipping
17. ลูกค้ากรอกข้อมูลที่อยู่จัดส่งและเลือกวิธีการจัดส่ง

Order
18. ระบบคำนวณค่าจัดส่งและแสดงผลรวมราคาทั้งหมด
19. ลูกค้ากรอกข้อมูลการชำระเงิน

Payment
20. ระบบประสานงานกับระบบชำระเงินภายนอกเพื่อดำเนินการชำระเงิน

Order
21 ระบบแจ้งผลการชำระเงินให้ลูกค้าทราบ

Notification
22. ระบบส่งอีเมลยืนยันคำสั่งซื้อให้ลูกค้า

Order
23. ระบบอัพเดตสถานะคำสั่งซื้อเป็น "ชำระเงินแล้ว"

Shipping
24. เมื่อได้รับการยืนยันการชำระเงิน, ระบบจะส่งคำสั่งซื้อไปยังคลังสินค้าเพื่อเตรียมจัดส่ง

Order
25 ระบบจัดส่งสินค้าและอัพเดตสถานะคำสั่งซื้อเป็น "กำลังจัดส่ง"

Shipping
26. ลูกค้าสามารถติดตามสถานะการจัดส่งผ่านเว็บไซต์
27. ลูกค้าได้รับสินค้า

Order
28. ระบบอัพเดตสถานะคำสั่งซื้อเป็น "จัดส่งสำเร็จ"

Review and Rating
29. ลูกค้าเขียนรีวิวและให้คะแนนสินค้า

Return and Refund
30. ลูกค้าคืนสินค้าที่ไม่ต้องการ
31 ระบบดำเนินการตามนโยบายการคืนสินค้า

ในบทต่อไปเราจะลงลึกถึงการออกแบบ E-commerce Platform ด้วย Microservice Architecture รวมทั้งการศึกษา Best Practices ของการออกแบบ REST API และการทำ API Documentation ด้วย Swagger/OpenAPI กันครับ

Post-test : Overview and System Design of Scalable E-commerce Platforms

ก่อนจากกันในบทนี้ เรามี Challenge ให้ผู้อ่านได้ลองทำ Post-test ที่เป็นข้อสอบ Choice ทั้งหมด 32 ข้อ ไม่จำกัดเวลาในการทำ เมื่อ Submit แล้ว ผู้อ่านจะสามารถทราบผลทดสอบได้เลย

ขอให้สนุกกับการทำ Post-test นะครับ!

Post-test : Overview and System Design of Scalable E-commerce Platforms