แนวทางปฏิบัติแนะนำสำหรับ 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 รายการต่อเอกสาร หากไม่ได้ค้นหาตามอาร์เรย์หรือฟิลด์แผนที่ขนาดใหญ่ คุณควรยกเว้นฟิลด์ดังกล่าวจากการจัดทำดัชนี

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

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

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

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

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

Cloud Firestore SDK และไลบรารีไคลเอ็นต์จะลองทำธุรกรรมที่ล้มเหลวอีกครั้งโดยอัตโนมัติ เพื่อจัดการกับข้อผิดพลาดชั่วคราว หากแอปพลิเคชันเข้าถึง 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 ระบบอาจเก็บรหัสโปรเจ็กต์ Cloud ไว้หลังจากโปรเจ็กต์หมดอายุ
  • แนวทางปฏิบัติแนะนำด้านการปฏิบัติตามข้อกำหนดด้านข้อมูลคือเราไม่แนะนำให้จัดเก็บข้อมูลที่ละเอียดอ่อน ไว้ในชื่อเอกสารและชื่อฟิลด์เอกสาร

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

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

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