ทำระบบเพื่อรองรับ 10 ล้าน Users

Chaowlert Chaisrichalermpol
3 min readFeb 23, 2020

--

Photo by Denys Nevozhai on Unsplash

มี presentation นึง ของ AWS ชื่อ Scaling up to your first 10 million users ซึ่งเนื้อหาผสมระหว่าง architecture และ product ของ AWS ในวันนี้ผมจะมาย่อยเฉพาะส่วนของ architecture มาให้อ่านกัน

เราควรเริ่มสร้างระบบเพื่อรองรับ 10 ล้านคน ตั้งแต่วันแรกหรือไม่?

ระบบที่ scale สูงๆ ข้อเสียคือ develop ยากกว่า, test ยากกว่า, deploy ยากกว่า แถมต้องมาใส่ใจเรื่อง cross cutting concern เช่น authentication, logging, caching, networking, และ monitoring ซึ่งเมื่อเทียบกับระบบเล็กๆ เรื่องพวกนี้แทบจะ bundle มากับ framework ที่เราใช้งาน โดยไม่ต้องพัฒนาอะไรเพิ่ม

โดยรวมคือ ถ้าคุณต้องการให้ระบบมัน Scale ได้มากขึ้นแต่แรก คุณก็ต้องแลกกับเวลาที่คุณเสียไปสำหรับ handle เรื่องต่างๆ ข้างต้น ดังนั้นก็ต้องย้อนกลับไปดูธุรกิจของคุณ ถ้า function งานใหม่น่าจะมีฐานผู้ใช้เยอะอยู่แล้ว คุณก็หลีกเลี่ยงไม่ได้ที่จะต้องทำระบบให้รองรับ user จำนวนมาก แต่ถ้าไม่เช่นนั้น ตาม concept ของ lean สร้างระบบให้ simple ปรับเปลี่ยนตาม requirement ใหม่ๆ ได้ง่าย น่าจะเป็นตัวเลือกที่ดีกว่า

แล้ว Database ควรจะใช้แบบ SQL หรือ NoSQL?

Image source: https://www.geeksforgeeks.org/sql-vs-nosql-which-one-is-better-to-use/

โดยทั่วไป คุณควรจะเลือก SQL ก่อน เนื่องจาก

  • Technology มัน mature กว่า NoSQL
  • คุณสามารถควบคุม transaction ได้
  • มีพวก metric ต่างๆ ให้โดยไม่ต้องลงอะไรเพิ่ม
  • สามารถ tuning ให้รองรับได้เป็นล้าน user โดยอาจไม่ต้องแก้โปรแกรมเลย

แต่คุณสามารถเลือก NoSQL ไปเลยก็ได้ถ้า

  • คุณต้องรองรับ workload มหาศาล
  • รูปแบบของ data มันเหมาะกับ NoSQL พอดี เช่น file, json, หรือ graph
  • ไม่มี concern เรื่อง transaction เช่น การทำ logging

เพื่อให้คุณเข้าใจพัฒนาการของ Architecture ที่รองรับ user ระดับ 10 ล้าน เราจะมาเริ่มต้นด้วยระบบขนาดเล็กก่อน

Architecture สำหรับ user หลักร้อย

ระบบที่มี user หลักร้อย อันนี้น่าจะเป็นภาพของ app ทั่วๆ ไป ใช้แค่เพียง app server และ database server แค่อย่างละตัว ณ จุดนี้คุณก็ focus ไปกับการเพิ่ม feature ของ app คุณให้มากที่สุด ส่วนการ scaling ก็ใช้เพิ่มขนาดเอา

Architecture สำหรับ user หลักพัน

สิ่งแรกที่เพิ่มเข้ามาคือ load balancer เพื่อกระจาย load ไปยัง app server มากกว่า 1 ตัว และคุณสามารถกระจายไปได้มากกว่า 1 availability zone การเพิ่ม availability zone จะทำให้ app ของคุณ reliable มากขึ้น กรณีที่ down ทั้ง site

Architecture สำหรับ user หลักหมื่น

ณ จุดนี้ในระดับ app คุณก็แค่ขยายจำนวนของ app instance แต่ในระดับ ops การจัดการก็จะซับซ้อนมากขึ้น เช่น การทำ logging, monitoring

Architecture สำหรับ user ระดับแสน

ณ จุดนี้มีหลายสิ่งที่สามารถเพิ่มเข้ามาเพื่อช่วย Scaling

  • Auto Scaling: เพื่อเพิ่มลดจำนวน app instance ตาม load ของผู้ใช้งาน
  • Read Replica: เพื่อลดภาระของ database ตัวหลักในการอ่านข้อมูล
  • Blob Storage (S3): เพื่อลดภาระของ app หรือ db ในการอ่าน asset files
  • CDN (CloudFront): เพื่อลด latency ของ user และลดภาระในการอ่าน asset files
  • Cache (ElastiCache): เพื่อลด latency และลดภาระของ app และ db ในการประมวลผล
  • NoSQL (DynamoDB): เพื่อรองรับ transaction ปริมาณสูงๆ

เมื่อถึงจุดนี้ ในแง่ของ Ops คุณจะต้องมี automation pipeline เพื่อช่วยให้การปรับเปลี่ยนบน test ขึ้นมาอยู่บน prod ได้อย่างรวดเร็วและไม่มีปัญหา

Architecture สำหรับ user ระดับล้าน

ณ จุดนี้ Master Database ตัวเดียวอาจจะรับไม่ไหวแล้ว เราต้อง break app ของเราเป็นส่วนย่อยๆ (Microservices) เพื่อที่จะกระจาย load สามารถ scale ได้อย่างอิสระ และเมื่อคุณมาถึงจุดนี้ คุณก็น่าจะมีหลายๆ ทีมอยู่ดี Microservices จะทำให้แต่ละทีม ทำงานอิสระต่อกัน

อีกหนึ่งสิ่งคือ เราควรเอาระบบ messaging มาใช้ ระบบแบบ request-response ไม่ดีต่อการ scaling ในภาพรวม ระบบ messaging มีประโยชน์ดังนี้

  • Loose coupling: การทำ pub/sub ทำให้ระบบไม่ต้องรู้จักต้นทาง ปลายทาง
  • Non-blocking: ไม่มี process การรอ request-response
  • Scaling: เนื่องจาก app แต่ละตัวไม่ได้ผูกกัน ทำให้ publisher และ subscriber มี scale ที่แตกต่างกันได้
  • Greater resiliency: เมื่อ service ตัวใดตัวหนึ่งตาย ก็ไม่ได้ทำให้ทั้ง operation นั้นตาย

แต่ถึงจุดนี้ ในแง่ Ops จะค่อนข้างซับซ้อนถึงขั้นสุด คุณอาจต้องมองหา tool สำหรับทำ distribute tracing และ service mesh

สรุป

  • ทุกอย่างมี trade-off ยิ่ง scale สูง ก็ยิ่งซับซ้อนมากขึ้น เราอาจจะไม่จำเป็นต้องรีบ scale ก็ได้
  • อย่างไรก็ตาม เราก็ควรทำ app ของเราให้ scale ง่ายๆ ตั้งแต่แรก เช่น ไม่เก็บ session ใน memory (แม้ load balancer จะ support sticky session แต่การปรับเปลี่ยนระบบจะวุ่นวายกว่า)
  • Database เป็นสิ่งเดียวที่ scale out ไม่ได้ แต่เราสามารถลดภาระของ db ได้โดยใช้ read replica, caching, และย้ายบาง function ไป NoSQL
  • นอกจากลดภาระ db แล้ว เราควรมองวิธี แตก app ออกมาเป็นส่วนๆ (Microservices) และเอาระบบ messaging ใช้
  • สุดท้าย อย่าลืมเรื่อง Ops (Automation, Metrics, Monitoring, Logging)

--

--