21 คะแนน โดย GN⁺ 2025-10-27 | 3 ความคิดเห็น | แชร์ทาง WhatsApp
  • 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 ความคิดเห็น

 
click 2025-10-28

ผมสงสัยว่าแค่ให้ EC2 หรือพ็อดบน EKS รับอัปโหลดวิดีโอโดยตรงแล้วประมวลผลเลยไม่ได้หรือ
ถ้าถึงขั้นทำ proxy ขึ้นมาเอง ก็ดูเหมือนว่าน่าจะทำ EKS autoscaling ตามโหลดของพ็อดได้เพียงพอเหมือนกัน
ปกติการประมวลผลวิดีโอก็ไม่จำเป็นต้องโหลดไฟล์ทั้งก้อนขึ้นมาไว้ในหน่วยความจำอยู่แล้ว เลยรู้สึกว่าถ้าสร้างไฟล์ชั่วคราวบน local SSD ของแต่ละอินสแตนซ์แล้วประมวลผล ก็น่าจะไม่ต้องมี S3 fallback ด้วยซ้ำ

 
t7vonn 2025-10-28

ดูเหมือนจะเป็นตัวอย่างของการใช้ serverless กับ S3 แบบผิด ๆ
แต่ดูเหมือนว่าวิธีแก้ก็แปลกยิ่งกว่าอีกครับ

 
GN⁺ 2025-10-27
ความคิดเห็นจาก Hacker News
  • เป็นบทความที่มีประโยชน์มาก ชอบมากที่เขาแชร์ กระบวนการเข้าหาปัญหาเชิงเทคนิค แบบนี้
    ถึงผมจะไม่ได้เจอปัญหาเดียวกันด้วยตัวเอง แค่ได้เห็นว่าเขาคิดและเข้าหามันอย่างไรก็ได้เรียนรู้เยอะแล้ว

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

    • สุดท้ายก็กลายเป็นว่าต้องรันอินสแตนซ์ตัวใหญ่เพื่อให้ได้ network throughput และ RAM ที่พอ แต่แทบไม่ได้ใช้ CPU เลย
      เขาบอกว่า TLS handshake ใช้ CPU มาก แต่ก็ดูไม่น่าใช่คอขวดหลัก
      ถึงอย่างนั้น การลองออกแบบ ระบบให้เหมาะกับ workflow แบบเฉพาะทาง แบบนี้ก็น่าสนใจดี
  • จริง ๆ แล้ว ถ้าดูตามชื่อเรื่องมันไม่เชิงว่า “สร้าง S3 เอง” แต่เป็น สถาปัตยกรรมที่วาง memory cache ไว้หน้า S3 มากกว่า
    มันเจ๋งอยู่ แต่ไม่ใช่การแทนที่ S3 แบบสมบูรณ์

    • ใช่ แต่ก็คงต้องเลียนแบบ S3 API เพราะเปลี่ยนไคลเอนต์เดิมได้ยาก
      ไม่ว่าชื่อเรื่องจะเป็นยังไง ก็เป็นโปรเจกต์ที่น่าสนใจอยู่ดี
    • ผมไม่ค่อยเข้าใจว่าทำไมต้องเป็น memory cache ด้วย ใช้ local storage ก็น่าจะพอแล้ว
  • ถ้าจะพูดในสไตล์ HN ผมอยากพูดถึงตัวบริษัท Nanit เองมากกว่า
    Nanit ทำ กล้องเฝ้าดูเด็กแบบ cloud-based วิดีโอและเสียงทั้งหมดถูกอัปโหลดโดยไม่มี E2EE
    ฮาร์ดแวร์ก็แพง และถ้าไม่มีค่าสมาชิกก็แทบใช้งานอะไรไม่ได้ แถมยังต้องซื้อขาตั้งราคา $200 ถึงจะปลดล็อกฟีเจอร์ติดตามการนอน
    น่าเสียดายที่โครงสร้างแบบนี้ยิ่งตอกย้ำ โมเดลที่ผูกติดกับคลาวด์
    แต่ถึงอย่างนั้น การลดการพึ่งพา S3 และย้ายไปใช้สตอเรจของตัวเองแบบในบทความนี้ก็ถือว่าทำได้ดี

    • ผมเป็นลูกค้าที่พอใจนะ เหตุผลที่เลือก Nanit ก็ง่าย ๆ คือ “มันใช้งานได้ดี”
      ของเจ้าอื่นแอปไม่เสถียร ถ้ามีโซลูชันแบบ local-first + E2EE ก็คงดี แต่ในความเป็นจริง การใช้งานได้จริง สำคัญกว่า
    • เรื่อง E2EE ในกรณีนี้มันเป็นไปไม่ได้อยู่แล้ว เพราะไม่ได้มีแค่การเก็บข้อมูล แต่ยัง วิเคราะห์วิดีโอบนคลาวด์ ด้วย
      ถ้าอยากได้ E2EE จริง ๆ ก็ต้องวิเคราะห์บนเครื่องโลคัลแล้วอัปโหลดเฉพาะผลลัพธ์
    • ผมเคย ทำแท่นวางไม้เอง ใช้อยู่ ตอนนั้นยังไม่มีข้อจำกัดทางซอฟต์แวร์ ไม่แน่ใจว่าตอนนี้เปลี่ยนไปหรือยัง
    • ผมไม่เห็นด้วยกับคำพูดที่ว่า “self-host วิดีโอไม่ใช่เรื่องยาก” สำหรับผู้ใช้ทั่วไปมันไม่ใช่ตัวเลือกที่เอามาพิจารณาเลย
    • จริง ๆ ก็ไม่แน่ใจว่ากล้องเฝ้าดูเด็กจำเป็นต้องพึ่งคลาวด์ขนาดนั้นไหม ยังไงก็มีผู้ใหญ่ที่ไว้ใจได้อยู่ใกล้ ๆ อยู่แล้ว
  • บทความนี้ให้ความรู้สึกเหมือนสร้างปัญหาขึ้นมาเองแล้วค่อยฉลองที่แก้มันได้
    ถ้าขาย ฮาร์ดแวร์ที่เก็บข้อมูลในเครื่อง ตั้งแต่แรกก็น่าจะทั้งง่ายและถูกกว่า
    การออกแบบที่ยึดคลาวด์เป็นศูนย์กลางตอนนี้ดูเป็น แนวทางแบบปี 2015 ไปแล้ว

  • บทความดีมาก แต่ก็อยากรู้เหมือนกันว่าถ้าใช้ delete on read บน S3 แล้วจะประหยัดค่าใช้จ่ายได้แค่ไหน
    ถ้า S3 คิดเงินระดับวินาที จำนวนเงินที่ประหยัดได้อาจเยอะพอสมควร
    อีกอย่าง โซลูชันนี้จริง ๆ ก็คล้ายกับตัวเลือก reduced redundancy ของ S3

  • เขาบอกว่าประหยัดไป $500,000 แต่ไม่รู้ว่าต้นทุนรวมเท่าไร
    ความหมายมันต่างกันมากระหว่าง $500,001 จาก $500,000 กับ $500,000 จาก $55 million

    • ใช่ จริง ๆ ปัญหาแบบนี้บางทีก็แก้ได้ด้วย การเจรจาราคา (PPA) กับ AWS มากกว่าเรื่องเทคนิค
    • แต่ถึงอย่างนั้น S3 ก็ยังเป็น บริการที่คุ้มค่ามาก อยู่ดี ดังนั้นต่อให้เราจะย้ายออกจาก AWS เราก็น่าจะยังใช้ S3 กับ SQS ต่อ
  • รู้สึกเหมือนเลือก สถาปัตยกรรมที่ผิดตั้งแต่ต้น แล้วค่อยเอาแคชมาทาทับ
    วิดีโอเฉลี่ยยาว 2 วินาทีไม่มีเหตุผลอะไรให้ต้องอัปโหลดขึ้น S3 นอกจากเรื่องการเก็บซ้ำ
    ถ้าประมวลผลตรงบนเซิร์ฟเวอร์ตั้งแต่แรก ก็น่าจะตัด S3, SQS และ Lambda ออกได้หมด

    • ใช่ S3 มีไว้เก็บ ไม่ได้มีไว้ประมวลผล
      ไม่เข้าใจว่าทำไมถึงทำปัญหาง่าย ๆ ให้ซับซ้อนขนาดนี้
  • ฟังดูเหมือนบทเรียนคลาสสิกว่า “โฟกัสที่การพัฒนาแอป แล้วทำอินฟราให้เรียบง่าย
    เอาจริง ๆ ใส่แคชไว้ในเซิร์ฟเวอร์ประมวลผลวิดีโอโดยตรงน่าจะดีกว่า

  • ชื่อเรื่องจริง ๆ น่าจะเป็น “ใช้ S3 ผิดวิธี” มากกว่า

    • จริงเลย ไม่เข้าใจว่าทำไมถึงพยายามเก็บไฟล์ชั่วคราวสั้น ๆ หลายล้านไฟล์ไว้ใน S3
      สุดท้ายก็ไปสร้าง memory store เอง ทั้งที่ใช้ Redis ก็น่าจะพอแล้ว
      ถ้าระบบที่ทำเองล่ม วิดีโอก็หายเลยหรือเปล่า?
      ถ้าส่งเข้า Kinesis หรือ SQS ตั้งแต่แรกก็น่าจะดีกว่ามาก