nodejsでzipおよびunzip操作をマルチスレッド化できますか?
yauzlのようなモジュールはたくさんありますが、どちらも複数のスレッドを使用しておらず、node-clusterなどで複数のスレッドを自分で開始することはできません。各zipファイルは単一のスレッドで処理する必要があるためです。
nodejsでzipおよびunzip操作をマルチスレッド化できますか?
yauzlのようなモジュールはたくさんありますが、どちらも複数のスレッドを使用しておらず、node-clusterなどで複数のスレッドを自分で開始することはできません。各zipファイルは単一のスレッドで処理する必要があるためです。
回答:
Zlibのドキュメントによると
スレッドプールの使用:明示的に同期されるものを除くすべてのzlib APIは、libuvのスレッドプールを使用します。これにより、一部のアプリケーションでは、パフォーマンスの低下(プールサイズを調整することで軽減できる)や、回復不能で壊滅的なメモリの断片化など、予期しない影響が生じる可能性があります。 https://nodejs.org/api/zlib.html#zlib_threadpool_usage
libuvのスレッドプールによると、環境変数UV_THREADPOOL_SIZE
を変更して最大サイズを変更できます
代わりに多数の小さなファイルを同時に圧縮したい場合は、ワーカースレッドhttps://nodejs.org/api/worker_threads.htmlを使用できます 。
もう一度質問を読むと、複数のファイルが必要なようです。ワーカースレッドを使用します。これらはメインスレッドをブロックせず、プロミスを介してメインスレッドから出力を取得できます。
Node JSはLibuvとワーカースレッドを使用します。ワーカースレッドは、マルチスレッド方式で操作を実行する方法です。libuvを使用することで(スレッドプールにスレッドを維持します)、デフォルトノードのjsサーバーのスレッドを増やすことができます。両方を使用して、操作のノードjsパフォーマンスを改善できます。
ワーカースレッドの公式ドキュメントは次のとおりです。https://nodejs.org/api/worker_threads.html
ここでノードjsのスレッドプールを増やす方法を参照してください。ノードjs 8でlibuvスレッドプールサイズを出力します。
ノードjsでマルチスレッドを実行する方法のヘルプ。以下の3つのファイルを作成する必要があります
index.mjs
import run from './Worker.mjs';
/**
* design your input list of zip files here and send them to `run` one file name at a time
* to zip, using a loop or something. It acts as promise.
* exmaple : run( <your_input> ).then( <your_output> );
**/
Worker.mjs
import { Worker } from 'worker_threads';
function runService(id, options) {
return new Promise((resolve, reject) => {
const worker = new Worker('./src/WorkerService.mjs', { workerData: { <your_input> } });
worker.on('message', res => resolve({ res: res, threadId: worker.threadId }));
worker.on('error', reject);
worker.on('exit', code => {
if (code !== 0)
reject(new Error(`Worker stopped with exit code ${code}`));
});
});
}
async function run(id, options) {
return await runService(id, options);
}
export default run;
WorkerService.mjs
import { workerData } from 'worker_threads';
// Here goes your logic for zipping a file, where as `workerData` will have <your_input>.
それが役立つかどうか私に知らせてください。
nodejsでzipおよびunzip操作をマルチスレッド化できますか?
はい。
...複数のスレッドを自分で開始することはできません...各zipファイルは単一のスレッドで処理する必要があるため
あなたの前提は間違っていると思います。なぜノードプロセスは複数のスレッドを開始できないと思いますか?これは私が実行しているアプリで、親プロセスがスーパーバイザとして機能し、2つの子プロセスがネットワークとディスクI / Oに大きく依存するタスクを実行する非常に成熟したnode.jsクラスタモジュールを使用しています。
C
列からわかるように、各プロセスは個別のスレッドで実行されています。これにより、ワーカープロセスがCPUまたはディスクにバインドされている間、マスタープロセスはコマンドと制御タスク(スポーン/リーピングワーカーなど)に対して応答性を維持できます。この特定のサーバーは、ネットワークからファイルを受け入れ、場合によってはそれらを解凍し、外部ファイルプロセッサを介してファイルを送ります。IOW、あなたが説明するような圧縮を含むそのタスク。
私はあなたがドキュメントからのこのスニペットに基づいてワーカースレッドを使用したいと思うかどうかわかりません:
ワーカー(スレッド)は、CPUを集中的に使用するJavaScript操作の実行に役立ちます。I / O集約型の作業にはあまり役立ちません。Node.jsの組み込み非同期I / O操作は、ワーカーよりも効率的です。
私には、その説明は「crypo!」と叫びます。過去には、高額なcrypo操作を実行する必要があるときに子プロセスを生成しました。
別のプロジェクトでは、ノードのchild_processモジュールを使用して、圧縮するファイルのバッチがあるたびに新しい子プロセスを開始します。その特定のサービスは、〜という名前の〜400個のファイルのリストを参照process-me-2019.11.DD.MM
し、それらを単一のprocess-me-2019-11-DD
ファイルに連結します。圧縮にはしばらく時間がかかるため、新しいプロセスを生成すると、メインスレッドでのブロックが回避されます。
サードパーティのライブラリを使用するまで、純粋なNodejsでマルチスレッドを実行する方法はありません。promiseを使用して、プロセスを並行して実行できます。ノードが使用するメインスレッドをオーバーロードしたくない場合は、RabitMQ(Redis Queue)を実装できます。独自のスレッドで実行されるため、メインスレッドがブロックされることはありません。