Necesito escribir una gran cantidad de documentos en Firestore.
¿Cuál es la forma más rápida de hacer esto en Node.js?
fuente
Necesito escribir una gran cantidad de documentos en Firestore.
¿Cuál es la forma más rápida de hacer esto en Node.js?
TL; DR: la forma más rápida de realizar la creación de fechas masivas en Firestore es realizar operaciones de escritura individuales paralelas.
Escribir 1,000 documentos en Firestore toma:
~105.4s
cuando se utilizan operaciones de escritura individuales secuenciales~ 2.8s
cuando se utilizan (2) operaciones de escritura por lotes~ 1.5s
cuando se utilizan operaciones de escritura individuales paralelasHay tres formas comunes de realizar una gran cantidad de operaciones de escritura en Firestore.
Investigaremos cada uno a continuación, utilizando una matriz de datos de documentos aleatorios.
Esta es la solución más simple posible:
async function testSequentialIndividualWrites(datas) {
while (datas.length) {
await collection.add(datas.shift());
}
}
Escribimos cada documento por turno, hasta que hayamos escrito todos los documentos. Y esperamos que se complete cada operación de escritura antes de comenzar con la siguiente.
Escribir 1,000 documentos toma aproximadamente 105 segundos con este enfoque, por lo que el rendimiento es de aproximadamente 10 documentos escritos por segundo .
Esta es la solución más compleja.
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;
}
}
}
Puedes ver que creamos un BatchedWrite
objeto llamandobatch()
, llenándolo hasta su capacidad máxima de 500 documentos y luego escribiéndolo en Firestore. Le damos a cada documento un nombre generado que es relativamente probable que sea único (lo suficientemente bueno para esta prueba).
Escribir 1,000 documentos toma aproximadamente 2.8 segundos con este enfoque, por lo que el rendimiento es de aproximadamente 357 escrituras de documentos por segundo .
Eso es bastante más rápido que con las escrituras individuales secuenciales. De hecho: muchos desarrolladores usan este enfoque porque suponen que es más rápido, pero como los resultados anteriores ya mostraron, esto no es cierto. Y el código es, con mucho, el más complejo, debido a la restricción de tamaño en los lotes.
La documentación de Firestore dice esto sobre el rendimiento para agregar muchos datos :
Para la entrada de datos en masa, use una biblioteca cliente de servidor con escrituras individuales paralelas. Las escrituras por lotes funcionan mejor que las escrituras serializadas pero no mejor que las escrituras paralelas.
Podemos poner eso a prueba con este código:
async function testParallelIndividualWrites(datas) {
await Promise.all(datas.map((data) => collection.add(data)));
}
Este código inicia las add
operaciones lo más rápido que puede y luego Promise.all()
espera a que finalicen. Con este enfoque, las operaciones pueden ejecutarse en paralelo.
Escribir 1,000 documentos toma aproximadamente 1.5 segundos con este enfoque, por lo que el rendimiento es de aproximadamente 667 escrituras de documentos por segundo .
La diferencia no es tan grande como entre los dos primeros enfoques, pero sigue siendo 1,8 veces más rápida que las escrituras por lotes.
Algunas notas
add()
no hacen más que generar una ID única (puramente del lado del cliente), seguida de unaset()
operación. Entonces los resultados deberían ser los mismos. Si eso no es lo que observa, publique una nueva pregunta con el caso mínimo que reproduce lo que ha intentado.