ใช้แนวทางปฏิบัติแนะนำที่ระบุไว้ที่นี่เป็นข้อมูลอ้างอิงอย่างรวดเร็วเมื่อสร้างแอปพลิเคชันที่ใช้ Cloud Firestore
ตำแหน่งที่ตั้งของฐานข้อมูล
เมื่อสร้างอินสแตนซ์ฐานข้อมูล ให้เลือกตำแหน่งฐานข้อมูลที่ใกล้กับผู้ใช้และทรัพยากรการประมวลผลมากที่สุด การข้ามเครือข่ายที่ไกลออกไปมีแนวโน้มที่จะเกิดข้อผิดพลาดและเพิ่มเวลาในการตอบสนองของการค้นหา
หากต้องการเพิ่มความพร้อมใช้งานและความทนทานของแอปพลิเคชัน ให้เลือกตำแหน่งหลายภูมิภาคและวางทรัพยากรการประมวลผลที่สำคัญในภูมิภาคอย่างน้อย 2 แห่ง
เลือกตำแหน่งระดับภูมิภาคเพื่อลดต้นทุน ลดเวลาในการตอบสนองการเขียน หากแอปพลิเคชันของคุณไวต่อเวลาในการตอบสนอง หรือใช้ร่วมกับทรัพยากร GCP อื่นๆ
รหัสเอกสาร
- หลีกเลี่ยงรหัสเอกสาร
.
และ..
- หลีกเลี่ยงการใช้เครื่องหมายทับ
/
ในรหัสเอกสาร อย่าใช้รหัสเอกสารที่เพิ่มขึ้นแบบเชิงเดี่ยว เช่น
Customer1
,Customer2
,Customer3
, ...Product 1
,Product 2
,Product 3
, ...
รหัสตามลําดับดังกล่าวอาจทําให้เกิดฮอตสปอตที่ส่งผลต่อเวลาในการตอบสนอง
ชื่อช่อง
หลีกเลี่ยงการใช้อักขระต่อไปนี้ในชื่อฟิลด์ เนื่องจากต้องมีการหลีกอักขระเพิ่มเติม
.
[
วงเล็บเปิด]
วงเล็บปิด*
เครื่องหมายดอกจัน`
แบ็กทิก
ดัชนี
ลดเวลาในการตอบสนองของการเขียน
ปัจจัยหลักที่ทำให้เกิดเวลาในการตอบสนองในการเขียนคือ Fanout ของดัชนี แนวทางปฏิบัติแนะนำเพื่อลดการแยกย่อยดัชนีมีดังนี้
ตั้งค่าการยกเว้นดัชนีระดับคอลเล็กชัน ค่าเริ่มต้นที่ง่ายคือปิดใช้การจัดเรียงจากน้อยไปมากและการจัดทำดัชนีอาร์เรย์ การนําค่าที่จัดทำดัชนีไว้แต่ไม่ได้ใช้งานออกยังช่วยลดต้นทุนพื้นที่เก็บข้อมูลด้วย
ลดจำนวนเอกสารในธุรกรรม หากต้องการเขียนเอกสารจํานวนมาก ให้พิจารณาใช้เครื่องมือเขียนไฟล์จํานวนมากแทนเครื่องมือเขียนไฟล์กลุ่มแบบอะตอม
การยกเว้นดัชนี
สําหรับแอปส่วนใหญ่ คุณสามารถใช้การจัดทำดัชนีอัตโนมัติ รวมถึงลิงก์ข้อความแสดงข้อผิดพลาดเพื่อจัดการดัชนีได้ อย่างไรก็ตาม คุณอาจต้องเพิ่มการยกเว้นช่องเดียวในกรณีต่อไปนี้
การก | คำอธิบาย |
---|---|
ช่องสตริงขนาดใหญ่ | หากมีฟิลด์สตริงที่มักเก็บค่าสตริงยาวๆ ที่คุณไม่ได้ใช้สำหรับค้นหา คุณสามารถลดค่าใช้จ่ายในการจัดเก็บได้โดยยกเว้นฟิลด์นั้นไม่ให้ได้รับการจัดทําดัชนี |
อัตราการเขียนสูงไปยังคอลเล็กชันที่มีเอกสารซึ่งมีค่าตามลำดับ | หากคุณจัดทำดัชนีช่องที่เพิ่มขึ้นหรือลดลงตามลำดับระหว่างเอกสารในคอลเล็กชัน เช่น การประทับเวลา อัตราเขียนสูงสุดไปยังคอลเล็กชันจะเป็น 500 ครั้งต่อวินาที หากไม่ได้ค้นหาตามช่องที่มีค่าตามลําดับ คุณสามารถยกเว้นช่องนั้นจากการจัดทำดัชนีเพื่อข้ามขีดจํากัดนี้ได้ ตัวอย่างเช่น ใน Use Case ของ IoT ที่มีอัตราการเขียนสูง คอลเล็กชันที่มีเอกสารซึ่งมีช่องการประทับเวลาอาจเข้าใกล้ขีดจํากัดการเขียน 500 ครั้งต่อวินาที |
ฟิลด์ TTL |
หากคุณใช้นโยบาย TTL (Time To Live) โปรดทราบว่าช่อง TTL ต้องเป็นการประทับเวลา ระบบจะเปิดใช้การจัดทำดัชนีในช่อง TTL โดยค่าเริ่มต้น ซึ่งอาจส่งผลต่อประสิทธิภาพเมื่ออัตราการเข้าชมสูงขึ้น แนวทางปฏิบัติแนะนำคือเพิ่มการยกเว้นช่องเดี่ยวสำหรับช่อง TTL |
ฟิลด์อาร์เรย์หรือแผนที่ขนาดใหญ่ | ฟิลด์อาร์เรย์หรือแผนที่ขนาดใหญ่อาจเข้าใกล้ขีดจํากัดของรายการดัชนี 40,000 รายการต่อเอกสาร หากคุณไม่ได้ค้นหาตามอาร์เรย์ขนาดใหญ่หรือฟิลด์แผนที่ คุณควรยกเว้นฟิลด์ดังกล่าวจากการจัดทำดัชนี |
การดำเนินการอ่านและเขียน
อัตราสูงสุดที่แน่นอนที่แอปจะอัปเดตเอกสารรายการเดียวได้นั้นขึ้นอยู่กับปริมาณงานเป็นอย่างมาก ดูข้อมูลเพิ่มเติมได้ที่การอัปเดตเอกสารเดียว
ใช้การเรียกแบบอะซิงโครนัส (หากมี) แทนการเรียกแบบซิงโครนัส การเรียกใช้แบบไม่พร้อมกันจะลดผลกระทบของเวลาในการตอบสนอง ตัวอย่างเช่น ลองพิจารณาแอปพลิเคชันที่ต้องอาศัยผลการค้นหาเอกสารและผลการค้นหาก่อนที่จะแสดงผลลัพธ์ หากการค้นหาและการค้นหาไม่มีข้อมูลที่ต้องพึ่งพากัน ก็ไม่จำเป็นต้องรอแบบซิงค์จนกว่าการค้นหาจะเสร็จสมบูรณ์ก่อนเริ่มการค้นหา
อย่าใช้ออฟเซต แต่ให้ใช้เคอร์เซอร์แทน การใช้ออฟเซตจะหลีกเลี่ยงการส่งเอกสารที่ข้ามไปยังแอปพลิเคชันของคุณเท่านั้น แต่ระบบจะยังคงดึงข้อมูลเอกสารเหล่านี้ภายใน เอกสารที่ข้ามจะส่งผลต่อเวลาในการตอบสนองของการค้นหา และระบบจะเรียกเก็บเงินจากแอปพลิเคชันของคุณสำหรับการดำเนินการอ่านที่จำเป็นในการดึงข้อมูลเอกสารเหล่านั้น
ธุรกรรมที่พยายามอีกครั้ง
Cloud Firestore SDK และไลบรารีไคลเอ็นต์จะพยายามทำธุรกรรมที่ดำเนินการไม่สำเร็จอีกครั้งโดยอัตโนมัติเพื่อจัดการกับข้อผิดพลาดชั่วคราว หากแอปพลิเคชันเข้าถึง Cloud Firestore ผ่าน API ของ REST หรือ RPC โดยตรงแทนที่จะผ่าน 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