กับดักการทำ JOIN ใน Firestore

คุณกำลังเผชิญกับปัญหาทั่วไปใน Firestore เมื่อ Firebase function ของคุณแจ้งข้อผิดพลาดเกี่ยวกับขนาด batch สูงสุด (maximum batch size error) คุณจำเป็นต้อง JOIN ข้อมูลระหว่าง orders และ customers เพื่อทำ dashboard โดยปกติแล้วคุณมักจะใช้วิธีทำข้อมูลซ้ำ (duplicate data) เพื่อแก้ปัญหานี้ แต่ตอนนี้ข้อมูลของคุณกลับไม่อัปเดตและไม่สอดคล้องกัน (stale and inconsistent)

Google ได้ประกาศเปิดตัว Pipelines API เพื่อแก้ปัญหานี้ ซึ่งช่วยให้สามารถทำ operation แบบ JOIN ข้าม collection ได้โดยไม่ต้องทำข้อมูลซ้ำ นักพัฒนาบางส่วนรายงานว่าความเร็วในการ query นั้นรวดเร็วในการทดสอบขนาดเล็ก

ผมใช้เวลาหนึ่งสัปดาห์ในการทดสอบ API นี้ภายใต้ภาระงานหนัก (heavy load) และนี่คือสิ่งที่เอกสารไม่ได้บอกคุณ

  1. ค่าใช้จ่ายสูง ทุกการรัน pipeline จะมีการอ่านข้อมูลจากทุก collection ที่เกี่ยวข้อง การทำ JOIN ระหว่างสอง collection จะคิดค่าบริการการอ่าน (reads) จากทั้งสองฝั่ง หากคุณ JOIN สอง collection ที่มีเอกสาร 50,000 ฉบับ ค่าใช้จ่ายของคุณจะพุ่งสูงขึ้นอย่างรวดเร็ว มันไม่ใช่ค่าใช้จ่ายแบบเส้นตรง (linear cost) ที่เรียบง่าย

  2. ข้อจำกัดด้านประสิทธิภาพ จากการทดสอบของผม pipeline ที่จัดการกับเอกสาร 10,000 ฉบับใช้เวลา 380ms แต่เมื่อผมทดสอบกับเอกสาร 100,000 ฉบับ การ query กลับหมดเวลา (timeout) ที่ 30 วินาที คุณไม่ได้กำลังแก้ปัญหา แต่คุณแค่กำลังเปลี่ยนจาก error เรื่อง batch ไปเป็น error เรื่อง timeout แทน

  3. ปัญหา Cold Start Pipelines สร้าง execution context แยกต่างหาก ในสภาพแวดล้อมแบบ serverless อย่าง Cloud Functions สิ่งนี้จะเพิ่มความล่าช้าไปอีก 2 ถึง 4 วินาที ผู้ใช้ของคุณจะรู้สึกว่าแอปของคุณทำงานช้า

Pipelines API เป็นเครื่องมือสำหรับการทำต้นแบบ (prototyping) หรือใช้กับ collection ขนาดเล็กที่มีเอกสารน้อยกว่า 5,000 ฉบับ มันไม่ใช่สิ่งที่จะมาแทนที่ฐานข้อมูลเชิงสัมพันธ์ (relational database) Google มอบสิ่งนี้มาเพื่อช่วยให้คุณยังคงอยู่ในระบบนิเวศของ Firebase แทนที่จะย้ายไปใช้ PostgreSQL หรือ Spanner

หากคุณใช้ Pipelines ให้ปฏิบัติตามกฎเหล่านี้:

ตรวจสอบขนาด collection ของคุณ หาก collection มีเอกสารเกิน 20,000 ฉบับ ให้คำนวณค่าใช้จ่ายในการ JOIN ก่อนเสมอ • จำกัดความซับซ้อน การ JOIN ข้ามสาม collection ขึ้นไปถือเป็นสัญญาณที่ไม่ดี • ติดตามค่าใช้จ่ายในการอ่าน (read costs) ทุกสัปดาห์ การอ่านผ่าน Pipeline จะปรากฏในบิลของคุณแตกต่างออกไป • เก็บข้อมูลแบบ denormalized ของคุณไว้ ใช้ Pipelines เป็นส่วนเสริม ไม่ใช่การแทนที่ทั้งหมด • ทดสอบด้วย traffic จริง การทดสอบประสิทธิภาพ (benchmarks) บน collection ที่ไม่มีการใช้งาน ไม่สามารถสะท้อนความเป็นจริงในระบบ production ได้

อย่าใช้การแก้ปัญหาแบบชั่วคราวเพื่อหลีกเลี่ยงการตัดสินใจทางสถาปัตยกรรมที่แท้จริง

คุณจัดการความสัมพันธ์ (relationships) ใน Firestore อย่างไร? คุณใช้วิธี denormalization หรือการทำ client-side joins? บอกผมในคอมเมนต์ได้เลย

Source: https://dev.to/xu_xu_b2179aa8fc958d531d1/the-firestore-join-trap-what-googles-new-pipelines-api-costs-you-that-nobodys-talking-about-an7