- Nanit เดิมใช้ AWS S3 ใน pipeline ประมวลผลวิดีโอ สำหรับวิเคราะห์การนอนของทารก แต่ด้วยการอัปโหลดหลายพันรายการต่อวินาที ทำให้ ค่า request ของ PutObject กลายเป็นต้นทุนหลักของระบบ
- นอกจากนี้ ข้อจำกัดการเก็บขั้นต่ำ 1 วันของ กฎ S3 Lifecycle ทำให้ต้องจ่าย ค่าจัดเก็บ 24 ชั่วโมง สำหรับวิดีโอที่จริง ๆ แล้วประมวลผลเสร็จภายใน 2 วินาที
- เพื่อแก้ปัญหานี้ บริษัทจึงสร้าง N3 ระบบจัดเก็บข้อมูลในหน่วยความจำที่พัฒนาด้วย Rust โดยใช้ S3 เป็นเพียง overflow buffer
- N3 ทำงานเข้ากันได้เต็มรูปแบบกับ pipeline เดิมผ่าน SQS FIFO พร้อมคง การรับประกันลำดับที่เข้มงวด และ ความเชื่อถือได้
- ผลลัพธ์คือช่วยลดค่าใช้จ่ายได้ราว 500,000 ดอลลาร์ต่อปี พร้อมได้สถาปัตยกรรมที่เรียบง่ายและเสถียร
ภูมิหลัง
ภาพรวมของ video processing pipeline
- กล้องของ Nanit จะบันทึก video chunk แล้วขอ S3 presigned URL จาก Camera Service เพื่อ อัปโหลดขึ้น S3 โดยตรง
- AWS Lambda จะ publish object key ไปยัง คิว SQS FIFO (shard ตาม baby_uid) จากนั้น pod ประมวลผลวิดีโอจะดึงจาก SQS แล้วดาวน์โหลดจาก S3 เพื่อนำไป inference สถานะการนอน
- ข้อดีของการตั้งค่านี้
- การลงจอดที่ S3 + การคิวผ่าน SQS ช่วย แยกการอัปโหลดจากกล้องออกจากการประมวลผลวิดีโอ ทำให้ไม่สูญเสียวิดีโอแม้ระหว่างบำรุงรักษาหรือ downtime ชั่วคราว
- ไม่จำเป็นต้องดูแล availability และ durability ผ่าน S3 ด้วยตัวเอง
- SQS FIFO + group ID ช่วยคงลำดับของแต่ละทารก และทำให้ node ประมวลผลส่วนใหญ่คงความเป็น stateless ได้
- กฎ S3 Lifecycle จัดการ garbage collection จึงไม่ต้องติดตามว่าวิดีโอใดประมวลผลแล้ว
ทำไมต้องเปลี่ยน
- ต้นทุน PutObject ครองสัดส่วนหลัก: วิดีโอเป็น object อายุสั้น ที่อยู่ใน landing area เพียง ไม่กี่วินาที เพื่อรอประมวลผล แต่เมื่อมีการอัปโหลดหลายพันรายการต่อวินาที ค่า request ต่อ object จึงกลายเป็นตัวขับต้นทุนที่ใหญ่ที่สุด
- หาก เพิ่มความถี่ในการ chunk (ส่ง chunk เล็กลงและถี่ขึ้น) เพื่อลด latency ต้นทุนก็จะ เพิ่มแบบเส้นตรง เพราะทุก chunk ใหม่คือ PutObject เพิ่มอีกหนึ่งครั้ง
- ค่าจัดเก็บเป็นการคิดซ้ำชั้นที่สอง: แม้จะประมวลผลเสร็จในราว 2 วินาที แต่ กฎลบของ Lifecycle ก็ยังทำให้ถูกคิด ค่าจัดเก็บประมาณ 24 ชั่วโมง
- จึงต้องการสถาปัตยกรรมที่ ยังคงความเชื่อถือได้และการรับประกันลำดับแบบเข้มงวด ขณะเดียวกันก็ หลีกเลี่ยงต้นทุนต่อ object บนเส้นทางปกติ และลด storage แบบ “จ่ายเพื่อรอ” ให้มากที่สุด
แผน
-
หลักการออกแบบ
- ความเรียบง่ายผ่านสถาปัตยกรรม: ไม่ใช่การเขียน implementation ที่ฉลาดล้ำ แต่คือการ ตัดความซับซ้อนออกตั้งแต่ระดับการออกแบบ
- ความถูกต้อง: ต้องเป็น ตัวแทนทดแทนที่โปร่งใสและสมบูรณ์ สำหรับส่วนอื่นของ pipeline
- ปรับให้เหมาะกับเส้นทางปกติ: ออกแบบเพื่อกรณีใช้งานทั่วไป และ ใช้ S3 เป็นตาข่ายนิรภัยสำหรับ edge case โดยให้ความสำคัญกับความเรียบง่ายมากกว่าการสร้างกลไกรับประกันที่ซับซ้อน เพราะอัลกอริทึมประมวลผลทนต่อช่องว่างเล็กน้อยได้อยู่แล้ว
-
ตัวขับการออกแบบ
- object อายุสั้น: segment อยู่ในพื้นที่พักเพียงไม่กี่วินาที
- ลำดับ: ต้องรักษา sequence ที่เข้มงวดต่อทารกหนึ่งคน (ไม่ประมวลผลตัวใหม่กว่าก่อน)
- throughput: อัปโหลดหลายพันรายการต่อวินาที ขนาด 2-6 MB ต่อ segment
- ข้อจำกัดฝั่ง client: กล้องมี จำนวนครั้ง retry จำกัด จึงสมมติว่าขอให้ส่งซ้ำได้ไม่ได้
- การปฏิบัติการ: ต้องรองรับ backlog หลายล้านรายการ ระหว่างการบำรุงรักษาหรือ scale-up
- ไม่เปลี่ยน firmware: ต้องทำงานร่วมกับกล้องเดิมได้
- การยอมรับการสูญหาย: ช่องว่างเล็กมากยอมรับได้ และอัลกอริทึมสามารถ mask ได้
- ต้นทุน: หลีกเลี่ยงค่า S3 ต่อ object บนเส้นทางปกติ และลด storage แบบ “จ่ายเพื่อรอ” ให้ต่ำที่สุด
ภาพรวมการออกแบบ (N3 เส้นทางปกติ + S3 overflow)
-
สถาปัตยกรรม
- N3 เป็น landing area แบบกำหนดเองที่ เก็บวิดีโอไว้ในหน่วยความจำเท่านั้น ในช่วงเวลาที่การประมวลผลต้องใช้เพื่อ drain งาน (ประมาณ 2 วินาที) และจะ ใช้ S3 เฉพาะเมื่อ N3 รับภาระไม่ไหว
- มี 2 คอมโพเนนต์
- N3-Proxy (stateless, dual interface)
- ภายนอก (เชื่อมต่ออินเทอร์เน็ต): รับการอัปโหลดจากกล้องผ่าน presigned URL
- ภายใน (private): ออก presigned URL ให้ Camera Service
- N3-Storage (stateful, ภายในเท่านั้น): เก็บ segment ที่อัปโหลดไว้ใน RAM และคิวไปยัง SQS พร้อม download URL ที่อ้างถึง pod ได้
- pod ประมวลผลวิดีโอจะดึงจาก SQS FIFO แล้วดาวน์โหลดจาก storage ที่ URL ชี้อยู่ (N3 หรือ S3)
-
การไหลปกติ (Happy Path)
- กล้องขอ upload URL จาก Camera Service
- Camera Service ขอ presigned URL จาก internal API ของ N3-Proxy
- กล้องอัปโหลดวิดีโอไปยัง external endpoint ของ N3-Proxy
- N3-Proxy ส่งต่อไปยัง N3-Storage
- N3-Storage เก็บวิดีโอไว้ในหน่วยความจำและคิวลง SQS พร้อม download URL ที่ชี้มาหาตัวเอง
- pod ประมวลผลดาวน์โหลดจาก N3-Storage แล้วนำไปประมวลผล
-
fallback สองชั้น
- Tier 1: fallback ระดับ proxy (ต่อ request)
- หาก N3-Storage รับอัปโหลดไม่ได้ เพราะแรงกดดันด้านหน่วยความจำ backlog การประมวลผล หรือ pod ล้มเหลว N3-Proxy จะอัปโหลดขึ้น S3 แทนกล้อง
- กล้องยังคงได้รับ N3 URL ไปแล้วก่อนที่จะตรวจพบความล้มเหลว
- Tier 2: reroute ระดับคลัสเตอร์ (ทุกทราฟฟิก)
- หาก N3-Proxy หรือ N3-Storage ไม่พร้อมใช้งาน Camera Service จะ หยุดออก N3 URL และคืนค่า S3 presigned URL โดยตรง
- ทราฟฟิกทั้งหมดจะไหลไปที่ S3 จนกว่า N3 จะฟื้นตัว
-
เหตุผลที่แยกเป็นสองคอมโพเนนต์
- ขอบเขตผลกระทบของความขัดข้อง: ถ้า storage crash proxy ยัง route ไป S3 ได้ แต่ถ้า proxy crash จะกระทบเฉพาะทราฟฟิกของ node นั้น โดย storage cluster ทั้งหมดยังปลอดภัย
- resource profile: proxy ใช้ CPU/เครือข่ายหนัก (TLS termination) ส่วน storage ใช้หน่วยความจำหนัก (เก็บวิดีโอ) จึงต้องการ instance type และการ scale ที่ต่างกัน
- ความปลอดภัย: storage ไม่สัมผัสอินเทอร์เน็ตโดยเด็ดขาด
- ความปลอดภัยในการ rollout: อัปเดต proxy (stateless) ได้โดยไม่แตะ storage ที่ถือข้อมูลใช้งานอยู่
การตรวจสอบการออกแบบ
-
สิ่งที่ต้องพิสูจน์
- ความจุและการกำหนดขนาด: ระยะเวลาการอัปโหลดจริงบนเครือข่ายของ client การใช้ compute ที่ต้องการ และ ขนาด upload buffer
- โมเดลการจัดเก็บ: จะเก็บทุกอย่างไว้ใน RAM ได้หรือจำเป็นต้องใช้ disk
- ความทนทานต่อปัญหา: วิธี load balancing ราคาถูกและการจัดการ node ที่ล้มเหลว
- นโยบายปฏิบัติการ: ความต้องการ GC ความคาดหวังเรื่อง retry และการลบตอน GET เพียงพอหรือไม่
- unknown unknowns: เมื่อแนวคิดไปเจอโลกจริง จะมี edge case อะไรโผล่มา
-
แนวทางที่ 1: synthetic stress test
- สร้าง load generator ที่ ผลักระบบไปจนถึงขีดจำกัด ด้วย concurrency หลายระดับ client ที่ช้า โหลดต่อเนื่อง และ downtime ระหว่างประมวลผล
- เป้าหมาย: หาเพดานระบบ ระบุ bottleneck ที่ไม่คาดคิด และได้ baseline แบบกำหนดได้แน่นอน สำหรับ capacity planning
-
แนวทางที่ 2: production PoC (mirror mode)
- การทดสอบสังเคราะห์ จำลองพฤติกรรมกล้องจริงไม่ได้: Wi‑Fi ไม่เสถียร firmware หลายเวอร์ชัน และสภาพเครือข่ายที่คาดเดาไม่ได้
- mirror mode: n3-proxy จะ เขียนลง S3 ก่อน (คงการทำงาน production) แล้วจึงเขียนลง N3-Storage ของ PoC (เชื่อมกับ SQS แบบ canary และ video processor) ด้วย
- cohort เป้าหมาย: แยกตามเวอร์ชัน firmware / รายการ Baby-UID
- data parity: เปรียบเทียบ สถานะการนอน ระหว่าง PoC กับ production และตรวจสอบความต่าง
- observability: dashboard แยกตามเส้นทาง (N3 vs S3), ความลึกคิว, latency/RPS, error budget, และการวิเคราะห์ egress
- feature flag (ใช้ Unleash) สำคัญมาก: สามารถ สลับ cohort แบบเรียลไทม์โดยไม่ต้อง deploy ทดสอบกับ slice แคบ ๆ (firmware เก่า กล้องที่ Wi‑Fi อ่อน) แล้ว rollback ได้ทันทีหากมีปัญหา
-
สิ่งที่ค้นพบ
- bottleneck: TLS termination กิน CPU เป็นหลัก และ AWS burstable networking ถูก throttle หลังเครดิตหมด
- storage บนหน่วยความจำล้วนใช้งานได้จริง: จากการกระจายตัวของเวลาการอัปโหลดและ concurrency จริง ยืนยันได้ว่า working set เก็บไว้ใน RAM ได้พร้อม margin ที่ปลอดภัย จึงไม่ต้องใช้ disk
- overhead ของ TCP timestamp: ประมาณ 85% ของจำนวนไบต์ที่ส่งทั้งหมดเป็น ACK frame การปิด TCP timestamp (
sysctl -w net.ipv4.tcp_timestamps=0) ช่วย ประหยัด 12 ไบต์ต่อ ACK
- ความเสี่ยง: หากมีการส่งข้อมูลจำนวนมากบน socket เดิม อาจเกิด sequence number wrap และทำให้ packet ที่มาช้าถูกรวมผิดจนข้อมูลเสียหาย
- วิธีลดความเสี่ยง: (1) ใช้ socket ใหม่ต่อหนึ่งอัปโหลด, (2) รีไซเคิล socket ระหว่าง n3-proxy ↔ n3-storage หลังส่งไปประมาณ 1 GB
- memory leak: หลังเปิดใช้งานช่วงแรก หน่วยความจำของ n3-proxy เพิ่มขึ้นอย่างต่อเนื่อง
- การ profile ด้วย
jemalloc พบการเพิ่มขึ้นในบัฟเฟอร์ hyper BytesMut ต่อการเชื่อมต่อ
- การเชื่อมต่อจาก client บางส่วน หยุดค้างระหว่างส่งข้อมูล และไม่ถูก cleanup ทำให้บัฟเฟอร์ค้างอยู่และหน่วยความจำเพิ่มต่อเนื่อง
- วิธีแก้: ทำให้ socket มีอายุสั้นและกำหนดเวลาเข้มขึ้น
- ปิด keep-alive: ปิดการเชื่อมต่อทันทีหลังอัปโหลดแต่ละครั้งเสร็จ
- เพิ่มความเข้มงวดของ timeout: กำหนด header/socket timeout เพื่อยุติการอัปโหลดที่ค้างและคืนบัฟเฟอร์
Storage
-
In-memory storage
- เริ่มจากเส้นทางที่ง่ายที่สุด: in-memory storage เพื่อหลีกเลี่ยงการจูน I/O และใช้โครงสร้างข้อมูลที่ตรงไปตรงมา
- ใช้
Arc<DashMap<Ulid, Bytes>> เก็บวิดีโอ โดยทุกการอัปโหลดจะเพิ่ม bytes_used และทุกการดาวน์โหลดจะลบวิดีโอพร้อมลดค่าดังกล่าว
- เริ่มปฏิเสธการอัปโหลดเมื่อใช้ความจุเกิน ประมาณ 80% เพื่อหลีกเลี่ยง OOM และส่งสัญญาณให้ n3-proxy หยุดเซ็น upload URL
- มี handle
control สำหรับ pause การอัปโหลดและ garbage collection แบบ manual
-
graceful restart
- เนื่องจากเป็น storage บนหน่วยความจำล้วน จึงต้องป้องกันการทำข้อมูลระหว่างทางสูญหายตอน restart
- กระบวนการ graceful restart
- pod ได้รับ
SIGTERM (StatefulSet ทำ rolling ทีละตัว)
- pod เปลี่ยนเป็นสถานะ Not Ready และออกจาก Service (ไม่มีอัปโหลดใหม่เข้า)
- ยังให้บริการดาวน์โหลดสำหรับวิดีโอที่อัปโหลดมาแล้วต่อไป
- เมื่อการดาวน์โหลดหยุดลง (ไม่มีการอ่านล่าสุด → งานประมวลผล drain แล้ว)
- รอให้ request ที่เปิดอยู่เสร็จ
- restart แล้วจึงไปยัง pod ถัดไป
- หากระบบปกติ pod จะ drain เสร็จภายในไม่กี่วินาที
-
GC
- ใช้กลไก cleanup สองแบบ
- ลบทันทีเมื่อดาวน์โหลด: ลบวิดีโอทันทีหลังดาวน์โหลด โดย PoC ยืนยันว่า ไม่มีการดาวน์โหลดซ้ำเลย และเพราะ video processor retry ภายในเอง จึงไม่จำเป็นต้องเก็บข้อมูลหรือสถานะว่า “ประมวลผลแล้ว”
- TTL GC สำหรับตัวที่หลุดรอด: การลบตอนดาวน์โหลดไม่ครอบคลุม segment ที่ processor ข้ามไป (ไม่ได้ดาวน์โหลด → ไม่ถูกลบ)
- จึงเพิ่ม TTL GC แบบเบา: สแกน DashMap ในหน่วยความจำเป็นระยะ และลบรายการที่เก่ากว่า threshold ที่กำหนดได้ (เช่น หลายชั่วโมง)
- maintenance mode: ระหว่าง downtime ที่วางแผนไว้สำหรับการประมวลผล สามารถ pause GC ผ่าน control ภายในเพื่อป้องกันการลบวิดีโอขณะไม่มีการ consume
บทสรุป
-
ผลลัพธ์สำคัญ
- การใช้ S3 เป็น fallback buffer และ N3 เป็น landing area หลัก ช่วย ลดค่าใช้จ่ายได้ราว 500,000 ดอลลาร์ต่อปี พร้อมคงระบบให้เรียบง่ายและเชื่อถือได้
- insight หลัก: การตัดสินใจแบบ “build vs buy” ส่วนใหญ่มักโฟกัสที่ฟีเจอร์ แต่เมื่ออยู่ใน ระดับสเกลใหญ่ เศรษฐศาสตร์จะเปลี่ยนสมการ
- สำหรับ object อายุสั้น (ราว 2 วินาทีในสภาวะปกติ) ไม่จำเป็นต้องมี replication หรือ durability ที่ซับซ้อน และ in-memory store แบบง่ายก็เพียงพอ
- เมื่อการประมวลผลช้าลงหรือการบำรุงรักษาทำให้อายุของ object ยาวขึ้น ก็ยังต้องอาศัย การรับประกันความเชื่อถือได้ของ S3
- ได้ข้อดีจากทั้งสองด้าน: N3 จัดการเส้นทางปกติอย่างมีประสิทธิภาพ ส่วน S3 ให้ durability เมื่อต้องเก็บ object นานขึ้น
- หาก N3 มีปัญหา (แรงกดดันด้านหน่วยความจำ, pod crash, ปัญหาระดับคลัสเตอร์) การอัปโหลดจะ fail over ไป S3 อย่างราบรื่น
-
ปัจจัยแห่งความสำเร็จ
- นิยามปัญหาให้ชัดตั้งแต่ต้น: ข้อจำกัด สมมติฐาน และขอบเขต ช่วยป้องกัน scope creep
- ตรวจสอบตั้งแต่เนิ่น ๆ ด้วย PoC แบบ mirror mode: พบ bottleneck (TLS, network throttling) และยืนยันสมมติฐานก่อน commit
- ช่วยเลี่ยงการ over-engineer และการย้อนแก้ครั้งใหญ่
-
ควรสร้างอะไรแบบนี้เมื่อไร
- ควรพิจารณา custom infrastructure เมื่อมี สเกลมากพอ ที่ทำให้ประหยัดต้นทุนได้อย่างมีนัยสำคัญ และมี ข้อจำกัดเฉพาะที่เอื้อให้ใช้โซลูชันง่าย ๆ ได้ ครบถ้วน
- แรงงานวิศวกรรม ที่ใช้สร้างและดูแลระบบต้อง น้อยกว่าต้นทุนโครงสร้างพื้นฐานที่ลดได้
- สำหรับ Nanit ความต้องการเฉพาะ (ที่เก็บชั่วคราว, ยอมรับการสูญหายได้, มี S3 fallback) ทำให้สามารถ สร้างระบบที่ง่ายพอจะคงต้นทุนการดูแลรักษาให้อยู่ในระดับต่ำ
- ถ้าขาดปัจจัยสองข้อนี้ ก็ควรใช้ managed service ต่อไป
- จะทำอีกไหม? ใช่ ระบบนี้ทำงานใน production ได้อย่างเสถียร และด้วยการออกแบบ fallback จึง หลีกเลี่ยงความซับซ้อนได้โดยไม่ต้องแลกกับความเชื่อถือได้
3 ความคิดเห็น
ผมสงสัยว่าแค่ให้ EC2 หรือพ็อดบน EKS รับอัปโหลดวิดีโอโดยตรงแล้วประมวลผลเลยไม่ได้หรือ
ถ้าถึงขั้นทำ proxy ขึ้นมาเอง ก็ดูเหมือนว่าน่าจะทำ EKS autoscaling ตามโหลดของพ็อดได้เพียงพอเหมือนกัน
ปกติการประมวลผลวิดีโอก็ไม่จำเป็นต้องโหลดไฟล์ทั้งก้อนขึ้นมาไว้ในหน่วยความจำอยู่แล้ว เลยรู้สึกว่าถ้าสร้างไฟล์ชั่วคราวบน local SSD ของแต่ละอินสแตนซ์แล้วประมวลผล ก็น่าจะไม่ต้องมี S3 fallback ด้วยซ้ำ
ดูเหมือนจะเป็นตัวอย่างของการใช้ serverless กับ S3 แบบผิด ๆ
แต่ดูเหมือนว่าวิธีแก้ก็แปลกยิ่งกว่าอีกครับ
ความคิดเห็นจาก Hacker News
เป็นบทความที่มีประโยชน์มาก ชอบมากที่เขาแชร์ กระบวนการเข้าหาปัญหาเชิงเทคนิค แบบนี้
ถึงผมจะไม่ได้เจอปัญหาเดียวกันด้วยตัวเอง แค่ได้เห็นว่าเขาคิดและเข้าหามันอย่างไรก็ได้เรียนรู้เยอะแล้ว
พูดตามตรง ถ้า ไม่ได้ใช้ serverless ตั้งแต่แรก น่าจะออกมาสะอาดกว่านี้มาก
รู้สึกเหมือนพยายามยัดข้อมูลระดับไม่กี่วินาทีเข้าไปในพาราไดม์ AWS serverless แบบฝืน ๆ จนเกิดค่าใช้จ่ายและความซับซ้อนที่ไม่จำเป็น
แต่ถึงอย่างนั้น การย้ายไปใช้โซลูชันที่อิงหน่วยความจำก็เป็นการตัดสินใจที่ดี
เขาบอกว่า TLS handshake ใช้ CPU มาก แต่ก็ดูไม่น่าใช่คอขวดหลัก
ถึงอย่างนั้น การลองออกแบบ ระบบให้เหมาะกับ workflow แบบเฉพาะทาง แบบนี้ก็น่าสนใจดี
จริง ๆ แล้ว ถ้าดูตามชื่อเรื่องมันไม่เชิงว่า “สร้าง S3 เอง” แต่เป็น สถาปัตยกรรมที่วาง memory cache ไว้หน้า S3 มากกว่า
มันเจ๋งอยู่ แต่ไม่ใช่การแทนที่ S3 แบบสมบูรณ์
ไม่ว่าชื่อเรื่องจะเป็นยังไง ก็เป็นโปรเจกต์ที่น่าสนใจอยู่ดี
ถ้าจะพูดในสไตล์ HN ผมอยากพูดถึงตัวบริษัท Nanit เองมากกว่า
Nanit ทำ กล้องเฝ้าดูเด็กแบบ cloud-based วิดีโอและเสียงทั้งหมดถูกอัปโหลดโดยไม่มี E2EE
ฮาร์ดแวร์ก็แพง และถ้าไม่มีค่าสมาชิกก็แทบใช้งานอะไรไม่ได้ แถมยังต้องซื้อขาตั้งราคา $200 ถึงจะปลดล็อกฟีเจอร์ติดตามการนอน
น่าเสียดายที่โครงสร้างแบบนี้ยิ่งตอกย้ำ โมเดลที่ผูกติดกับคลาวด์
แต่ถึงอย่างนั้น การลดการพึ่งพา S3 และย้ายไปใช้สตอเรจของตัวเองแบบในบทความนี้ก็ถือว่าทำได้ดี
ของเจ้าอื่นแอปไม่เสถียร ถ้ามีโซลูชันแบบ local-first + E2EE ก็คงดี แต่ในความเป็นจริง การใช้งานได้จริง สำคัญกว่า
ถ้าอยากได้ E2EE จริง ๆ ก็ต้องวิเคราะห์บนเครื่องโลคัลแล้วอัปโหลดเฉพาะผลลัพธ์
บทความนี้ให้ความรู้สึกเหมือนสร้างปัญหาขึ้นมาเองแล้วค่อยฉลองที่แก้มันได้
ถ้าขาย ฮาร์ดแวร์ที่เก็บข้อมูลในเครื่อง ตั้งแต่แรกก็น่าจะทั้งง่ายและถูกกว่า
การออกแบบที่ยึดคลาวด์เป็นศูนย์กลางตอนนี้ดูเป็น แนวทางแบบปี 2015 ไปแล้ว
บทความดีมาก แต่ก็อยากรู้เหมือนกันว่าถ้าใช้ delete on read บน S3 แล้วจะประหยัดค่าใช้จ่ายได้แค่ไหน
ถ้า S3 คิดเงินระดับวินาที จำนวนเงินที่ประหยัดได้อาจเยอะพอสมควร
อีกอย่าง โซลูชันนี้จริง ๆ ก็คล้ายกับตัวเลือก
reduced redundancyของ S3เขาบอกว่าประหยัดไป $500,000 แต่ไม่รู้ว่าต้นทุนรวมเท่าไร
ความหมายมันต่างกันมากระหว่าง $500,001 จาก $500,000 กับ $500,000 จาก $55 million
รู้สึกเหมือนเลือก สถาปัตยกรรมที่ผิดตั้งแต่ต้น แล้วค่อยเอาแคชมาทาทับ
วิดีโอเฉลี่ยยาว 2 วินาทีไม่มีเหตุผลอะไรให้ต้องอัปโหลดขึ้น S3 นอกจากเรื่องการเก็บซ้ำ
ถ้าประมวลผลตรงบนเซิร์ฟเวอร์ตั้งแต่แรก ก็น่าจะตัด S3, SQS และ Lambda ออกได้หมด
ไม่เข้าใจว่าทำไมถึงทำปัญหาง่าย ๆ ให้ซับซ้อนขนาดนี้
ฟังดูเหมือนบทเรียนคลาสสิกว่า “โฟกัสที่การพัฒนาแอป แล้วทำอินฟราให้เรียบง่าย”
เอาจริง ๆ ใส่แคชไว้ในเซิร์ฟเวอร์ประมวลผลวิดีโอโดยตรงน่าจะดีกว่า
ชื่อเรื่องจริง ๆ น่าจะเป็น “ใช้ S3 ผิดวิธี” มากกว่า
สุดท้ายก็ไปสร้าง memory store เอง ทั้งที่ใช้ Redis ก็น่าจะพอแล้ว
ถ้าระบบที่ทำเองล่ม วิดีโอก็หายเลยหรือเปล่า?
ถ้าส่งเข้า Kinesis หรือ SQS ตั้งแต่แรกก็น่าจะดีกว่ามาก