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

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

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

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

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

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

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

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

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

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

ชื่อช่องต่างๆ

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

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

ดัชนี

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

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

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

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

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

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

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

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

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

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

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

ช่อง TTL

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

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

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

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

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

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

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

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

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