node.js - 将大量文档写入Firestore的最快方法是什么?

标签 node.js firebase google-cloud-firestore

我需要向Firestore写大量文档。

在Node.js中最快的方法是什么?

最佳答案

TL; DR:在Firestore上执行批量日期创建的最快方法是执行并行的单独写入操作。

向Firestore写入1,000个文档需要:

  • 使用顺序单个写操作时的~105.4s
  • 使用(2)批处理写操作时的~ 2.8s
  • 使用并行单个写操作时的~ 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秒,因此吞吐量大约为每秒357t写入

    这比顺序进行单个写入要快得多。实际上:许多开发人员之所以使用这种方法是因为他们认为这是最快的方法,但是正如上面的结果所示,这是不正确的。由于批次的大小限制,代码是迄今为止最复杂的代码。

    并行的个别写入操作

    Firestore文档说明了有关performance for adding lots of data的信息:

    For bulk data entry, use a server client library with parallelized individual writes. Batched writes perform better than serialized writes but not better than parallel writes.



    我们可以使用以下代码对此进行测试:

    async function testParallelIndividualWrites(datas) {
      await Promise.all(datas.map((data) => collection.add(data)));
    }
    

    此代码以最快的速度启动add操作,然后使用Promise.all()等待它们全部完成。使用这种方法,操作可以并行运行。

    使用这种方法写入1,000个文档大约需要1.5秒,因此吞吐量大约为每秒667文档写入

    两者的区别不如前两种方法大,但仍比批量写入快1.8倍以上。

    一些注意事项:
  • 您可以在Github上找到此测试的完整代码。
  • 使用Node.js完成测试时,您可能会在Admin SDK支持的所有平台上获得相似的结果。
  • 不过,请勿使用客户端SDK执行批量插入,因为结果可能会大不相同,并且可预测性要差得多。
  • 像往常一样,实际性能取决于您的计算机,Internet连接的带宽和延迟以及许多其他因素。基于这些,尽管我希望顺序保持不变,但您可能也会看到差异。
  • 如果您自己的测试中有异常值,或者发现完全不同的结果,请在下面留下评论。
  • 批量写入是原子的。因此,如果您在文档之间有依赖关系,并且必须编写所有文档,或者都不写任何文档,则应使用批处理写入。
  • 关于node.js - 将大量文档写入Firestore的最快方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58897274/

    相关文章:

    javascript - Twitter Streaming api Node.js - 减慢流速度

    ios - Firebase 查询两个值

    javascript - Firestore没有执行操作的权限

    java - Firebase Firestore 在运行时错误时崩溃

    javascript - 将嵌套映射值添加到 firestore

    node.js - openwhisk actions/IBM Cloud Functions 中的第三方 npm 包

    javascript - JRE 与 Node 性能

    javascript - 为什么nodejs中http的CreateServer中调用了两次回调

    firebase - firebase现在可以在中国用作数据库吗

    javascript - firebaseio.com 和 firebaseapp.com 之间的区别