Multiencadeamento para zip em nodejs

8

A operação zip e descompactar pode ser feita multithread no nodejs?

Existem vários módulos como o yauzl, mas nenhum deles usa vários encadeamentos e você não pode iniciar vários encadeamentos com cluster de nós ou algo assim, porque cada arquivo zip deve ser tratado em um único encadeamento

Alex
fonte
Você basicamente precisa de uma biblioteca com um módulo nativo que tenha acesso a threads. A arquitetura de nós permite que esses módulos tenham acesso aos encadeamentos.
Sn0bli
No Nó v10.5.0, você pode usar um sinalizador --experimental-worker para "Multithreading" por meio de threads de trabalho e no Nó v11.7.0 eles expuseram os trabalhadores por padrão e removeram o sinalizador, nodejs.org/en/blog/ release / v11.7.0 nodejs.org/en/blog/release/v10.5.0 , Você pode verificar os exemplos medium.com/@Trott/using-worker-threads-in-node-js-80494136dbb6
redhatvicky

Respostas:

5

De acordo com a documentação da Zlib

Uso do Conjunto de Threads: Todas as APIs do zlib, exceto aquelas explicitamente síncronas, usam o conjunto de threads do libuv. Isso pode levar a efeitos surpreendentes em alguns aplicativos, como desempenho abaixo da média (que pode ser atenuado pelo ajuste do tamanho do conjunto) e / ou fragmentação irrecuperável e catastrófica da memória. https://nodejs.org/api/zlib.html#zlib_threadpool_usage

De acordo com o threadpool do libuv, você pode alterar a variável de ambiente UV_THREADPOOL_SIZEpara alterar o tamanho máximo

Se você deseja compactar muitos arquivos pequenos ao mesmo tempo, pode usar os Threads do Trabalhador https://nodejs.org/api/worker_threads.html

Ao ler sua pergunta novamente, parece que você deseja vários arquivos. Use Threads de Trabalho, eles não bloquearão seu thread principal e você poderá obter a saída deles através de promessas.

Strike Eagle
fonte
2

O nó JS usa Libuv e thread de trabalho. O encadeamento de trabalho é uma maneira de realizar operações de maneira multithread. Ao usar o libuv (ele mantém o encadeamento no conjunto de encadeamentos), é possível aumentar o encadeamento do servidor js do nó padrão. Você pode usar os dois para melhorar o desempenho do nó js para sua operação.

Então, aqui está a documentação oficial para o thread de trabalho: https://nodejs.org/api/worker_threads.html

Veja como você pode aumentar o conjunto de encadeamentos no nó js aqui: print libuv threadpool size in node js 8

Slim Coder
fonte
1

Ajuda sobre como executar multiencadeamento no nó js. Você terá que criar abaixo de três arquivos

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

Deixe-me saber se isso ajuda.

Akshay
fonte
1

A operação zip e descompactar pode ser feita multithread no nodejs?

Sim.

... e você não pode iniciar vários threads por conta própria ... porque cada arquivo zip deve ser tratado em um único thread

Eu suspeito que sua premissa está com defeito. Por que exatamente você acha que um processo de nó não pode iniciar vários encadeamentos? Aqui está um aplicativo que estou executando, que está usando o módulo de cluster node.js muito maduro , com um processo pai atuando como supervisor e dois processos filhos, realizando tarefas ligadas à E / S de rede e de disco.

saída superior mostrando os processos node.js usando encadeamentos da CPU

Como você pode ver na Ccoluna, cada processo está sendo executado em um encadeamento separado. Isso permite que o processo mestre permaneça responsivo às tarefas de comando e controle (como gerar / colher trabalhadores) enquanto os processos de trabalho são vinculados à CPU ou ao disco. Esse servidor específico aceita arquivos da rede, às vezes os descompacta e os alimenta através de processadores de arquivos externos. IOW, é uma tarefa que inclui compactação como você descreve.

Não tenho certeza se você deseja usar threads de trabalho com base nesse snippet dos documentos :

Trabalhadores (threads) são úteis para executar operações JavaScript com uso intenso de CPU. Eles não ajudarão muito no trabalho intensivo de E / S. As operações de E / S assíncrona incorporadas do Node.js. são mais eficientes do que os Trabalhadores.

Para mim, essa descrição grita "crypo!" No passado, eu gerava processos filhos ao ter que executar operações caras de crypo.

Em outro projeto, uso o módulo child_process do nó e inicio um novo processo filho cada vez que tenho um lote de arquivos para compactar. Esse serviço específico vê uma lista de ~ 400 arquivos com nomes como process-me-2019.11.DD.MMe os concatena em um único process-me-2019-11-DDarquivo. Demora um pouco para compactar, o que gera um novo processo, evitando o bloqueio do encadeamento principal.

Matt Simerson
fonte
Um processo de nó pode iniciar vários threads, mas como eles não compartilham o mesmo código e variáveis, você não pode usá-los para compactar o mesmo arquivo ou extrair do mesmo arquivo. Como posso extrair de um zip usando vários threads, sem abrir o mesmo arquivo em todos os threads?
Alex
OIC, você deseja usar vários threads para [des] compactar um único arquivo. O mais próximo que você pode chegar disso é gerar um processo externo que executa um utilitário de compactação paralelo como o pigz . Ou você deseja que um único archive seja aberto e tenha outros processos de nó capazes de ler a partir dele (usando IPC)?
Matt Simerson 02/12/19
0

Não há como você executar multithreading em Nodejs puros até usar qualquer biblioteca de terceiros. Você pode executar o processo em paralelo usando promessas. Se você não deseja sobrecarregar o encadeamento principal usado pelo nó, pode implementar o RabitMQ (Redis Queue). Ele será executado em seu próprio encadeamento, para que seu encadeamento principal nunca seja bloqueado.

Sudhir Roy
fonte
Isto está incorreto. Nodejs permite threads de trabalho. Leia mais aqui: nodejs.org/api/worker_threads.html
Strike Eagle
O trabalhador não é multi-threading, em vez disso, é executado em um processo totalmente diferente. RabitMQ (projeto do trabalhador, mas tem um monte de capacidade)
Sudhir Roy
"Tecnicamente", no final do dia, você tem a mesma capacidade de executar instruções em um encadeamento diferente e receber a saída.
Strike Eagle