Firestore'a çok sayıda belge yazmanın en hızlı yolu nedir?


Yanıtlar:


26

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:

  1. ~105.4s sıralı bireysel yazma işlemleri kullanılırken
  2. ~ 2.8s (2) toplu yazma işlemleri kullanılırken
  3. ~ 1.5s paralel bireysel yazma işlemleri kullanılırken

Firestore'da çok sayıda yazma işlemi gerçekleştirmenin üç yaygın yolu vardır.

  1. Her bir yazma işlemini sırayla gerçekleştirin.
  2. Toplu yazma işlemlerini kullanma.
  3. Bireysel yazma işlemlerinin paralel olarak yapılması.

Bir dizi rastgele belge verisi kullanarak her birini aşağıda sırayla araştıracağız.


Bireysel sıralı yazma işlemleri

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 .


Toplu yazma işlemlerini kullanma

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 BatchedWritenesne 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.


Paralel bireysel yazma işlemleri

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, addiş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:

  • Bu testin tam kodunu Github'da bulabilirsiniz .
  • Test Node.js ile yapılırken, Yönetici SDK'sının desteklediği tüm platformlarda benzer sonuçlar elde edersiniz.
  • Ancak sonuçlar çok farklı ve çok daha az tahmin edilebilir olabileceğinden, istemci SDK'larını kullanarak toplu ekleme yapmayın.
  • Her zamanki gibi, gerçek performans makinenize, internet bağlantınızın bant genişliğine ve gecikmesine ve diğer birçok faktöre bağlıdır. Bunlara dayanarak, siparişin aynı kalmasını beklesem de, farklılıklarda da farklılıklar görebilirsiniz.
  • Kendi testlerinizde herhangi bir aykırı değer varsa veya tamamen farklı sonuçlar bulursanız, aşağıda bir yorum bırakın.
  • Yığın yazma işlemleri atomiktir. Bu nedenle, belgeler arasında bağımlılıklarınız varsa ve tüm belgeler yazılmalı ya da hiçbiri yazılmamalı, toplu bir yazma kullanmalısınız.

1
Bu çok ilginç, işi yaptığınız için teşekkür ederim! OOC, toplu yazıları paralel olarak çalıştırmayı test ettiniz mi? Açıkçası, bu durumda, herhangi bir belgenin her iki grupta olmasını önlemek için daha da emin olmanız gerekir.
14'te robsiemb

1
Paralel toplu yazmaları test etmek üzereydim, ancak kota bitti (ücretsiz bir proje ve yükseltmek için çok tembeltim). Bugün başka bir gün, bu yüzden denemek ve önemliyse cevabımı güncelleyebilirim.
Frank van Puffelen

2
@robsiemb Ben de paralel toplu yazımlarla test ettim. Performans tek tek paralel yazımlara çok benzer, bu yüzden testlerimde ilk kez bağlandıklarını söyleyebilirim. Toplu işlerin, arka uçta işlendikleri doğa nedeniyle daha hızlı bozulmasını bekliyorum. Çok daha karmaşık kodla birlikte, onları sadece atomisiteleri için kullanmanızı ve algılanan ancak var olmayan performans avantajı için değil, tavsiye ederim.
Frank van Puffelen

@FrankvanPuffelen paralel yazımları, belgeleri "eklemek" yerine "" koyarsam "daha hızlı olur mu? Yani, db.collection ('şehirler'). Doc ('LA'). Db.collection ('şehirler') yerine set (veri) ekle (veri)
alek6dj

Çağrı yapmak 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.
Frank van Puffelen
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.