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

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

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

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

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

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

รหัสเอกสาร

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

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

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

ชื่อสนาม

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

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

ดัชนี

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

การทำธุรกรรมซ้ำ

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

อัพเดทเรียลไทม์

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

คำแนะนำ รายละเอียด
ลดอัตราการปั่นของผู้ฟังสแนปชอต

หลีกเลี่ยงการรบกวนผู้ฟังบ่อยๆ โดยเฉพาะอย่างยิ่งเมื่อฐานข้อมูลของคุณอยู่ภายใต้ภาระการเขียนที่สำคัญ

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

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

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

จำกัดผู้ฟังสแน็ปช็อตต่อลูกค้าหนึ่งราย

100

รักษาจำนวนผู้ฟังสแน็ปช็อตต่อไคลเอนต์ให้ต่ำกว่า 100

จำกัดอัตราการเขียนคอลเลกชัน

1,000 การดำเนินการ/วินาที

รักษาอัตราการดำเนินการเขียนสำหรับคอลเลกชันแต่ละรายการให้ต่ำกว่า 1,000 การดำเนินการ/วินาที

จำกัดอัตราการกดของลูกค้าแต่ละราย

1 เอกสาร/วินาที

รักษาอัตราของเอกสารที่ฐานข้อมูลส่งไปยังลูกค้าแต่ละรายภายใต้ 1 เอกสาร/วินาที

จำกัดอัตราการกดของลูกค้าทั่วโลก

1,000,000 เอกสาร/วินาที

รักษาอัตราของเอกสารที่ฐานข้อมูลส่งไปยังลูกค้าทั้งหมดให้ต่ำกว่า 1,000,000 เอกสาร/วินาที

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

จำกัดเพย์โหลดเอกสารแต่ละฉบับ

10 KiB/วินาที

รักษาขนาดเอกสารสูงสุดที่ดาวน์โหลดโดยไคลเอนต์แต่ละรายให้ต่ำกว่า 10 KiB/วินาที

จำกัดเพย์โหลดเอกสารทั่วโลก

1 GiB/วินาที

เก็บขนาดเอกสารสูงสุดที่ดาวน์โหลดในไคลเอนต์ทั้งหมดภายใต้ 1 GiB/วินาที

จำกัดจำนวนช่องต่อเอกสาร

100

เอกสารของคุณควรมีน้อยกว่า 100 ช่อง

ทำความเข้าใจขีดจำกัดมาตรฐานของ Cloud Firestore

คำนึงถึง ขีดจำกัดมาตรฐานสำหรับ Cloud Firestore

ให้ความสนใจเป็นพิเศษกับขีดจำกัดการเขียน 1 ครั้งต่อวินาทีสำหรับเอกสารและขีดจำกัดการเชื่อมต่อพร้อมกัน 1,000,000 ครั้งต่อฐานข้อมูล นี่เป็นข้อจำกัดแบบซอฟต์ที่ Cloud Firestore ไม่ได้หยุดคุณไม่ให้เกิน อย่างไรก็ตาม การใช้เกินขีดจำกัดเหล่านี้อาจส่งผลต่อประสิทธิภาพการทำงาน ขึ้นอยู่กับอัตราการอ่านและเขียนทั้งหมดของคุณ

ฟังก์ชั่นคลาวด์

การเปิดใช้งาน Cloud Function กับเหตุการณ์ Cloud Firestore มากกว่า 2,000 รายการต่อวินาที สามารถเพิ่มอัตราข้อผิดพลาดชั่วคราวและเพิ่มเวลาในการตอบสนองชั่วคราวได้หลายนาที ก่อนเปิดใช้งานฟังก์ชันที่มีปริมาณการใช้งานสูง คุณสามารถ ติดต่อฝ่ายสนับสนุน เพื่อเตรียมฐานข้อมูลของคุณสำหรับฟังก์ชันที่มีปริมาณการใช้งานสูงและหลีกเลี่ยงเวลาแฝงที่เพิ่มขึ้น

การออกแบบสำหรับมาตราส่วน

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

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

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

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

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

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

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

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

การอ่านแบบขนาน

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

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

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

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

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

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

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

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