แนวทางปฏิบัติที่ดีที่สุดสำหรับ Cloud Firestore

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

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

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

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

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

รหัสเอกสาร

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

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

    ID ตามลำดับดังกล่าวสามารถนำไปสู่ ฮอตสปอต ที่ส่งผลต่อเวลาในการตอบสนอง

ชื่อฟิลด์

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

    • . ระยะเวลา
    • [ วงเล็บซ้าย
    • ] วงเล็บขวา
    • * เครื่องหมายดอกจัน
    • ` แบคติค

ดัชนี

ลดความล่าช้าในการเขียน

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

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

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

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

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

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

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

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

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

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

ฟิลด์ TTL

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

อาร์เรย์หรือฟิลด์แผนที่ขนาดใหญ่

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

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

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

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

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

ธุรกรรมลองใหม่

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

การอัปเดตตามเวลาจริง

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

การออกแบบสำหรับขนาด

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

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

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

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

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

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

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

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

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

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

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

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

หลีกเลี่ยงการข้ามข้อมูลที่ถูกลบ

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

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

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 Standard Limits ตรวจสอบให้แน่ใจว่าการดำเนินการมีการกระจายอย่างเท่าเทียมกันตลอดช่วงคีย์ สิ่งนี้เรียกว่ากฎ "500/50/5"

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

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

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

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

อ่านแบบขนาน

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

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

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

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

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

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

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

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

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

เรียนรู้เพิ่มเติมเกี่ยวกับ การใช้กฎความปลอดภัยของ Cloud Firestore