ฉันต้องเขียนเอกสารจำนวนมากไปที่ Firestore
วิธีที่เร็วที่สุดในการทำสิ่งนี้ใน Node.js คืออะไร?
ฉันต้องเขียนเอกสารจำนวนมากไปที่ Firestore
วิธีที่เร็วที่สุดในการทำสิ่งนี้ใน Node.js คืออะไร?
คำตอบ:
TL; DR: วิธีที่เร็วที่สุดในการสร้างวันที่จำนวนมากบน Firestore คือการดำเนินการเขียนแต่ละแบบคู่ขนาน
การเขียนเอกสาร 1,000 ฉบับไปที่ Firestore ใช้เวลา:
~105.4s
เมื่อใช้การดำเนินการเขียนแต่ละรายการตามลำดับ~ 2.8s
เมื่อใช้ (2) การดำเนินการเขียนแบบแบตช์~ 1.5s
เมื่อใช้การดำเนินการเขียนเดี่ยวแบบขนานมีวิธีการทั่วไปสามวิธีในการดำเนินการเขียนจำนวนมากบน Firestore
เราจะตรวจสอบในลำดับต่อไปนี้โดยใช้อาร์เรย์ของข้อมูลเอกสารแบบสุ่ม
นี่เป็นวิธีที่ง่ายที่สุดที่เป็นไปได้:
async function testSequentialIndividualWrites(datas) {
while (datas.length) {
await collection.add(datas.shift());
}
}
เราเขียนเอกสารแต่ละฉบับจนกว่าเราจะเขียนเอกสารทุกฉบับ และเรารอให้การดำเนินการเขียนแต่ละครั้งเสร็จสิ้นก่อนที่จะเริ่มในการเขียนครั้งต่อไป
เขียน 1,000 เอกสารใช้เวลาประมาณ 105 วินาทีกับวิธีการนี้เพื่อให้ผ่านคือประมาณ10 เอกสารเขียนต่อวินาที
นี่คือทางออกที่ซับซ้อนที่สุด
async function testBatchedWrites(datas) {
let batch = admin.firestore().batch();
let count = 0;
while (datas.length) {
batch.set(collection.doc(Math.random().toString(36).substring(2, 15)), datas.shift());
if (++count >= 500 || !datas.length) {
await batch.commit();
batch = admin.firestore().batch();
count = 0;
}
}
}
คุณจะเห็นว่าเราสร้างBatchedWrite
วัตถุโดยการโทรbatch()
เติมให้เต็มความจุสูงสุดถึง 500 เอกสารแล้วเขียนไปที่ Firestore เราตั้งชื่อเอกสารที่สร้างขึ้นซึ่งมีแนวโน้มว่าจะไม่ซ้ำกัน (ดีพอสำหรับการทดสอบนี้)
เขียน 1,000 เอกสารใช้เวลาประมาณ 2.8 วินาทีกับวิธีการนี้เพื่อให้ผ่านคือประมาณ357 เขียนเอกสารต่อวินาที
ค่อนข้างเร็วกว่าการเขียนเรียงตามลำดับ ในความเป็นจริง: นักพัฒนาจำนวนมากใช้วิธีนี้เพราะพวกเขาคิดว่ามันเร็วที่สุด แต่เนื่องจากผลลัพธ์ข้างต้นแสดงให้เห็นว่าสิ่งนี้ไม่เป็นความจริง และรหัสนั้นซับซ้อนที่สุดเนื่องจากข้อ จำกัด ด้านขนาดสำหรับแบทช์
เอกสารของ Firestore บอกสิ่งนี้เกี่ยวกับประสิทธิภาพในการเพิ่มข้อมูลจำนวนมาก :
สำหรับการป้อนข้อมูลจำนวนมากให้ใช้ไลบรารีไคลเอนต์เซิร์ฟเวอร์ที่มีการเขียนแต่ละรายการแบบขนาน การเขียนแบบแบตช์ทำได้ดีกว่าการเขียนแบบต่อเนื่อง แต่ไม่ดีกว่าการเขียนแบบขนาน
เราสามารถนำไปทดสอบกับรหัสนี้:
async function testParallelIndividualWrites(datas) {
await Promise.all(datas.map((data) => collection.add(data)));
}
รหัสนี้เตะการadd
ดำเนินการให้เร็วที่สุดเท่าที่จะทำได้จากนั้นใช้Promise.all()
ในการรอจนกว่าจะเสร็จสิ้นทั้งหมด ด้วยวิธีนี้การดำเนินการสามารถทำงานแบบขนาน
เขียน 1,000 เอกสารใช้เวลาประมาณ 1.5 วินาทีด้วยวิธีการนี้เพื่อให้ผ่านคือประมาณ667 เขียนเอกสารต่อวินาที
ความแตกต่างนั้นไม่ค่อยดีเท่ากันระหว่างสองวิธีแรก แต่ก็ยังเร็วกว่าการเขียนแบบแบทช์มากกว่า 1.8 เท่า
หมายเหตุเล็กน้อย:
add()
ไม่ได้ทำอะไรมากไปกว่าการสร้าง ID เฉพาะ (ฝั่งไคลเอ็นต์ล้วน ๆ ) ตามด้วยการset()
ดำเนินการ ดังนั้นผลลัพธ์ควรเหมือนกัน หากนั่นไม่ใช่สิ่งที่คุณสังเกตเห็นให้โพสต์คำถามใหม่ด้วยตัวพิมพ์เล็ก ๆ น้อย ๆ ที่ทำซ้ำสิ่งที่คุณได้ลอง