Firestoreに大量のドキュメントを書き込む必要があります。
Node.jsでこれを行う最も速い方法は何ですか?
Firestoreに大量のドキュメントを書き込む必要があります。
Node.jsでこれを行う最も速い方法は何ですか?
回答:
TL; DR:Firestoreで一括データ作成を実行する最も速い方法は、個別の並列書き込み操作を実行することです。
1,000個のドキュメントをFirestoreに書き込むには、次のことが必要です。
~105.4s
順次個別書き込み操作を使用する場合~ 2.8s
(2)バッチ書き込み操作を使用する場合~ 1.5s
並列の個別書き込み操作を使用する場合Firestoreで多数の書き込み操作を実行するには、3つの一般的な方法があります。
以下では、ランダム化されたドキュメントデータの配列を使用して、それぞれを順に調査します。
これが最も簡単な解決策です。
async function testSequentialIndividualWrites(datas) {
while (datas.length) {
await collection.add(datas.shift());
}
}
すべてのドキュメントを作成するまで、各ドキュメントを順番に作成します。そして、各書き込み操作が完了するのを待ってから、次の操作を開始します。
このアプローチでは1,000ドキュメントの書き込みに約105秒かかるため、スループットは1秒あたり約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秒かかるため、スループットは1秒あたり約357ドキュメントの書き込みです。
これは、個別の順次書き込みよりもかなり高速です。実際、多くの開発者は、この方法が最速であると想定しているため、この方法を使用していますが、上記の結果がすでに示しているように、これは正しくありません。また、バッチのサイズ制限のため、コードははるかに複雑です。
Firestoreのドキュメントでは、大量のデータを追加する場合のパフォーマンスについて次のように述べています。
一括データ入力には、並列化された個々の書き込みを備えたサーバークライアントライブラリを使用します。バッチ処理された書き込みは、シリアル化された書き込みよりもパフォーマンスが優れていますが、並列書き込みよりも優れていません。
これを次のコードでテストできます。
async function testParallelIndividualWrites(datas) {
await Promise.all(datas.map((data) => collection.add(data)));
}
このコードは、add
可能な限り高速に操作を開始し、Promise.all()
すべてが完了するまで待機するために使用します。このアプローチでは、操作を並行して実行できます。
このアプローチでは、1,000ドキュメントの書き込みに約1.5秒かかるため、スループットは1秒あたり約667ドキュメントの書き込みです。
違いは最初の2つのアプローチほど大きくありませんが、バッチ書き込みよりも1.8倍以上高速です。
いくつかのメモ:
add()
は、一意のID(純粋にクライアント側)を生成し、その後にset()
操作を行うだけです。したがって、結果は同じになるはずです。それがあなたが観察したものではない場合、あなたが試みたものを再現する最小限のケースで新しい質問を投稿してください。