Firestore'a çok sayıda belge yazmam gerekiyor.
Node.js'de bunu yapmanın en hızlı yolu nedir?
Firestore'a çok sayıda belge yazmam gerekiyor.
Node.js'de bunu yapmanın en hızlı yolu nedir?
Yanıtlar:
TL; DR: Firestore'da toplu tarih oluşturma işlemini gerçekleştirmenin en hızlı yolu, paralel bireysel yazma işlemleri yapmaktır.
Firestore'a 1.000 belge yazmak:
~105.4s
sıralı bireysel yazma işlemleri kullanılırken~ 2.8s
(2) toplu yazma işlemleri kullanılırken~ 1.5s
paralel bireysel yazma işlemleri kullanılırkenFirestore'da çok sayıda yazma işlemi gerçekleştirmenin üç yaygın yolu vardır.
Bir dizi rastgele belge verisi kullanarak her birini aşağıda sırayla araştıracağız.
Bu mümkün olan en basit çözümdür:
async function testSequentialIndividualWrites(datas) {
while (datas.length) {
await collection.add(datas.shift());
}
}
Her belgeyi yazana kadar her belgeyi sırayla yazıyoruz. Bir sonraki işleme başlamadan önce her yazma işleminin tamamlanmasını bekliyoruz.
Bu yaklaşımla 1.000 belge yazmak yaklaşık 105 saniye sürer, bu nedenle işlem hacmi kabaca saniyede 10 belge yazar .
Bu en karmaşık çözümdür.
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;
}
}
}
Arayarak bir BatchedWrite
nesne oluşturduğumuzu görebilir, bunu batch()
maksimum 500 belge kapasitesine kadar doldurabilir ve ardından Firestore'a yazabilirsiniz. Her belgeye, benzersiz olması muhtemel olan oluşturulmuş bir ad veriyoruz (bu test için yeterince iyi).
Bu belgeyle 1.000 belge yazmak yaklaşık 2.8 saniye sürer, bu nedenle işlem hacmi yaklaşık olarak saniyede 357 belge yazar .
Bu sıralı bireysel yazımlardan biraz daha hızlıdır. Aslında: birçok geliştirici bu yaklaşımı en hızlı olduğunu varsaydığı için kullanır, ancak yukarıdaki sonuçların zaten gösterdiği gibi bu doğru değildir. Ve kod, partilerdeki boyut kısıtlaması nedeniyle açık ara en karmaşık olanıdır.
Firestore belgeleri, çok sayıda veri ekleme performansı hakkında şunları söylüyor :
Toplu veri girişi için, paralel yazımları olan bir sunucu istemci kitaplığı kullanın. Toplu yazma işlemleri, seri yazmalardan daha iyi performans gösterir, ancak paralel yazmalardan daha iyi performans göstermez.
Bunu şu kodla test edebiliriz:
async function testParallelIndividualWrites(datas) {
await Promise.all(datas.map((data) => collection.add(data)));
}
Bu kod, add
işlemleri olabildiğince hızlı başlatır ve sonra Promise.all()
hepsi bitene kadar beklemek için kullanır . Bu yaklaşımla işlemler paralel olarak gerçekleştirilebilir.
Bu yaklaşımla 1.000 belge yazmak yaklaşık 1.5 saniye sürer, bu nedenle işlem hacmi yaklaşık olarak saniyede 667 belge yazmaktadır .
Aradaki fark neredeyse ilk iki yaklaşım arasındaki kadar büyük değil, ama yine de toplu yazımlardan 1.8 kat daha hızlı.
Birkaç not:
add()
, benzersiz bir kimlik (yalnızca istemci tarafı) ve ardından bir set()
işlem oluşturmaktan başka bir şey yapmaz . Yani sonuçlar aynı olmalı. Gözlemlediğiniz şey bu değilse, denediğiniz şeyi yeniden üreten minimal vaka ile yeni bir soru gönderin.