แนวทางปฏิบัติแนะนำสำหรับ Cloud Firestore

ใช้แนวทางปฏิบัติแนะนำที่ระบุไว้ที่นี่เป็นข้อมูลอ้างอิงด่วนเมื่อสร้างแอปพลิเคชันที่ใช้ Cloud Firestore

ตำแหน่งที่ตั้งของฐานข้อมูล

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

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

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

รหัสของเอกสาร

  • หลีกเลี่ยงรหัสเอกสาร . และ ..
  • หลีกเลี่ยงการใช้เครื่องหมายทับ / ในรหัสเอกสาร
  • อย่าใช้รหัสเอกสารที่เพิ่มขึ้นแบบโมโนโทน เช่น

    • Customer1, Customer2, Customer3, ...
    • Product 1, Product 2, Product 3, ...

    รหัสตามลำดับดังกล่าวอาจทำให้เกิดฮอตสปอตที่ส่งผลต่อเวลาในการตอบสนอง

ชื่อฟิลด์

  • หลีกเลี่ยงการใช้อักขระต่อไปนี้ในชื่อช่องเนื่องจากต้องมีการหลีกอักขระเพิ่มเติม

    • . จุด
    • [ วงเล็บเหลี่ยมเปิด
    • ] วงเล็บเหลี่ยมปิด
    • * ดอกจัน
    • แบ็กทิก ` ตัว

ดัชนี

ลดเวลาในการตอบสนองของการเขียน

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

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

  • ลดจำนวนเอกสารในธุรกรรม สำหรับการเขียนเอกสารจำนวนมาก ให้พิจารณาใช้เครื่องมือเขียนแบบกลุ่มแทนเครื่องมือเขียนแบบกลุ่มอะตอม

การยกเว้นดัชนี

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

การก คำอธิบาย
ช่องสตริงขนาดใหญ่

หากคุณมีช่องสตริงที่มักมีค่าสตริงยาวๆ ซึ่งคุณไม่ได้ใช้สำหรับการค้นหา คุณสามารถลดค่าใช้จ่ายในการจัดเก็บข้อมูลได้โดยยกเว้นช่องดังกล่าวจากการจัดทำดัชนี

อัตราการเขียนสูงไปยังคอลเล็กชันที่มีเอกสารซึ่งมีค่าตามลำดับ

หากคุณจัดทำดัชนีฟิลด์ที่เพิ่มขึ้นหรือลดลงตามลำดับระหว่างเอกสารในคอลเล็กชัน เช่น การประทับเวลา อัตราการเขียนสูงสุดไปยังคอลเล็กชันคือ 500 การเขียนต่อวินาที หากไม่ได้ค้นหาตามฟิลด์ที่มีค่าตามลำดับ คุณสามารถยกเว้นฟิลด์จากการจัดทำดัชนีเพื่อข้ามขีดจำกัดนี้ได้

ในกรณีการใช้งาน IoT ที่มีอัตราการเขียนสูง เช่น คอลเล็กชันที่มีเอกสารซึ่งมีช่องการประทับเวลาอาจมีอัตราการเขียนใกล้ถึงขีดจำกัด 500 ครั้งต่อวินาที

ช่อง TTL

หากคุณใช้นโยบาย TTL (Time-To-Live) โปรดทราบว่าช่อง TTL ต้องเป็นการประทับเวลา การจัดทำดัชนีในช่อง TTL จะเปิดใช้อยู่โดยค่าเริ่มต้น และอาจส่งผลต่อประสิทธิภาพเมื่อมีอัตราการเข้าชมสูงขึ้น แนวทางปฏิบัติแนะนำคือให้เพิ่มการยกเว้นการจัดทำดัชนีอัตโนมัติสำหรับช่อง TTL

ช่องอาร์เรย์หรือแผนที่ขนาดใหญ่

ฟิลด์อาร์เรย์หรือแผนที่ขนาดใหญ่อาจมีรายการดัชนีใกล้ถึงขีดจำกัด 40,000 รายการต่อเอกสาร หากไม่ได้ค้นหาตามอาร์เรย์ขนาดใหญ่หรือฟิลด์แผนที่ คุณควรยกเว้นฟิลด์ดังกล่าวจากการจัดทำดัชนี

การดำเนินการอ่านและเขียน

  • อัตราสูงสุดที่แน่นอนที่แอปสามารถอัปเดตเอกสารรายการเดียวได้นั้นขึ้นอยู่กับภาระงานเป็นอย่างมาก ดูข้อมูลเพิ่มเติมได้ที่การอัปเดตเอกสารเดียว

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

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

การลองทำธุรกรรมอีกครั้ง

SDK และไลบรารีของไคลเอ็นต์ของ Cloud Firestore จะลองทำธุรกรรมที่ล้มเหลวอีกครั้งโดยอัตโนมัติเพื่อจัดการกับข้อผิดพลาดชั่วคราว หากแอปพลิเคชันของคุณเข้าถึง Cloud Firestore ผ่าน REST หรือ RPC API โดยตรงแทนที่จะผ่าน SDK แอปพลิเคชันของคุณควรใช้การลองทำธุรกรรมซ้ำเพื่อเพิ่มความน่าเชื่อถือ

การอัปเดตแบบเรียลไทม์

ดูแนวทางปฏิบัติแนะนำเกี่ยวกับการอัปเดตแบบเรียลไทม์ได้ที่ทำความเข้าใจการค้นหาแบบเรียลไทม์ในวงกว้าง

การออกแบบเพื่อรองรับการปรับขนาด

แนวทางปฏิบัติแนะนำต่อไปนี้จะอธิบายวิธีหลีกเลี่ยงสถานการณ์ที่ทำให้เกิดปัญหาการช่วงชิงทรัพยากร

การอัปเดตเอกสารรายการเดียว

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

การดำเนินการเขียนเอกสารจะอัปเดตเอกสารและดัชนีที่เกี่ยวข้อง และCloud Firestoreใช้การดำเนินการเขียนแบบซิงโครนัสกับองค์ประชุมของตัวจำลอง เมื่อมีอัตราการเขียนสูงเพียงพอ ฐานข้อมูลจะเริ่มพบกับการแย่งชิงทรัพยากร เวลาในการตอบสนองที่สูงขึ้น หรือข้อผิดพลาดอื่นๆ

อัตราการอ่าน เขียน และลบสูงในช่วงเอกสารที่แคบ

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

  • สร้างเอกสารใหม่ในอัตราที่สูงมากและจัดสรรรหัสที่เพิ่มขึ้นแบบโมโนโทนิกของตัวเอง

    Cloud Firestore จะจัดสรรรหัสเอกสารโดยใช้อัลกอริทึมแบบกระจาย คุณไม่ควรพบปัญหาฮอตสปอตในการเขียนหากสร้างเอกสารใหม่โดยใช้รหัสเอกสารอัตโนมัติ

  • สร้างเอกสารใหม่ในอัตราสูงในคอลเล็กชันที่มีเอกสารไม่กี่รายการ

  • สร้างเอกสารใหม่ที่มีช่องที่เพิ่มขึ้นแบบโมโนโทนิก เช่น การประทับเวลา ในอัตราที่สูงมาก

  • ลบเอกสารในคอลเล็กชันในอัตราที่สูง

  • เขียนลงในฐานข้อมูลด้วยอัตราที่สูงมากโดยไม่ค่อยๆ เพิ่มการเข้าชม

หลีกเลี่ยงการข้ามข้อมูลที่ลบไปแล้ว

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

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

docs = db.collection('WorkItems').order_by('created').limit(100)
delete_batch = db.batch()
for doc in docs.stream():
  finish_work(doc)
  delete_batch.delete(doc.reference)
delete_batch.commit()

ทุกครั้งที่การค้นหานี้ทำงาน ระบบจะสแกนรายการดัชนีสำหรับช่อง created ในเอกสารที่ลบล่าสุด ซึ่งจะทำให้การค้นหาช้าลง

หากต้องการปรับปรุงประสิทธิภาพ ให้ใช้เมธอด start_at เพื่อค้นหาจุดเริ่มต้นที่ดีที่สุด เช่น

completed_items = db.collection('CompletionStats').document('all stats').get()
docs = db.collection('WorkItems').start_at(
    {'created': completed_items.get('last_completed')}).order_by(
        'created').limit(100)
delete_batch = db.batch()
last_completed = None
for doc in docs.stream():
  finish_work(doc)
  delete_batch.delete(doc.reference)
  last_completed = doc.get('created')

if last_completed:
  delete_batch.update(completed_items.reference,
                      {'last_completed': last_completed})
  delete_batch.commit()

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

การเพิ่มการเข้าชม

คุณควรค่อยๆ เพิ่มการเข้าชมไปยังคอลเล็กชันใหม่หรือเอกสารที่ใกล้เคียงกันตามพจนานุกรมเพื่อให้ Cloud Firestore มีเวลาเพียงพอในการเตรียมเอกสารสำหรับการเข้าชมที่เพิ่มขึ้น เราขอแนะนำให้เริ่มด้วยการดำเนินการสูงสุด 500 รายการต่อวินาทีไปยังคอลเล็กชันใหม่ แล้วจึงเพิ่มการเข้าชม 50% ทุกๆ 5 นาที คุณสามารถเพิ่มการเข้าชมการเขียนในลักษณะเดียวกันได้ แต่โปรดคำนึงถึงขีดจำกัดมาตรฐานของ Cloud Firestore ด้วย ตรวจสอบว่าการดำเนินการกระจายอย่างสม่ำเสมอทั่วทั้งช่วงคีย์ ซึ่งเรียกว่ากฎ "500/50/5"

การย้ายข้อมูลการเข้าชมไปยังคอลเล็กชันใหม่

การเพิ่มปริมาณการเข้าชมอย่างค่อยเป็นค่อยไปมีความสำคัญอย่างยิ่งหากคุณย้ายข้อมูลการเข้าชมแอปจากคอลเล็กชันหนึ่งไปยังอีกคอลเล็กชันหนึ่ง วิธีง่ายๆ ในการจัดการการย้ายข้อมูลนี้คือการอ่านจากคอลเล็กชันเก่า และหากไม่มีเอกสารดังกล่าว ให้อ่านจากคอลเล็กชันใหม่ อย่างไรก็ตาม การดำเนินการนี้อาจทำให้การเข้าชมเอกสารที่ใกล้เคียงกันตามพจนานุกรมในคอลเล็กชันใหม่เพิ่มขึ้นอย่างฉับพลัน Cloud Firestore อาจไม่สามารถเตรียมคอลเล็กชันใหม่สำหรับการเข้าชมที่เพิ่มขึ้นได้อย่างมีประสิทธิภาพ โดยเฉพาะอย่างยิ่งเมื่อมีเอกสารเพียงไม่กี่รายการ

ปัญหาที่คล้ายกันอาจเกิดขึ้นได้หากคุณเปลี่ยนรหัสเอกสารของเอกสารหลายรายการภายในคอลเล็กชันเดียวกัน

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

การอ่านพร้อมกัน

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

กลยุทธ์ที่เป็นไปได้ในการเพิ่มการอ่านหรือการเขียนไปยังคอลเล็กชันใหม่อย่างค่อยเป็นค่อยไปคือการใช้แฮชเชิงกำหนดของรหัสผู้ใช้เพื่อเลือกเปอร์เซ็นต์แบบสุ่มของผู้ใช้ที่พยายามเขียนเอกสารใหม่ ตรวจสอบว่าผลลัพธ์ของแฮชรหัสผู้ใช้ไม่คลาดเคลื่อนเนื่องจากฟังก์ชันหรือพฤติกรรมของผู้ใช้

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

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

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

ความเป็นส่วนตัว

  • หลีกเลี่ยงการจัดเก็บข้อมูลที่ละเอียดอ่อนไว้ในรหัสโปรเจ็กต์ที่อยู่ในระบบคลาวด์ ระบบอาจเก็บรักษารหัสโปรเจ็กต์ที่อยู่ในระบบคลาวด์ไว้นานกว่าอายุการใช้งานของโปรเจ็กต์
  • แนวทางปฏิบัติแนะนำด้านการปฏิบัติตามข้อกำหนดเกี่ยวกับข้อมูลคือ เราขอแนะนำว่าไม่ควรจัดเก็บข้อมูลที่ละเอียดอ่อนไว้ในชื่อเอกสารและชื่อช่องเอกสาร

ป้องกันการเข้าถึงโดยไม่ได้รับอนุญาต

ป้องกันการดำเนินการที่ไม่ได้รับอนุญาตในฐานข้อมูลด้วย Cloud Firestore Security Rules ตัวอย่างเช่น การใช้กฎจะช่วยหลีกเลี่ยงสถานการณ์ที่ผู้ใช้ที่เป็นอันตรายดาวน์โหลดฐานข้อมูลทั้งหมดของคุณซ้ำๆ

ดูข้อมูลเพิ่มเติมเกี่ยวกับการใช้ Cloud Firestore Security Rules