node.js의 동시 작업에는 어느 것이 더 좋습니까? 섬유? 웹 작업자? 또는 스레드?


111

언젠가 node.js를 우연히 만났고 많이 좋아했습니다. 하지만 곧 CPU 집약적 인 작업을 수행하는 능력이 부족하다는 것을 알게되었습니다. 그래서 저는 인터넷 검색을 시작했고 문제를 해결하기 위해 Fibers, Webworkers 및 Threads (thread-a-gogo)와 같은 답을 얻었습니다. 이제 어떤 것을 사용해야하는지 혼란스럽고 그중 하나를 사용해야합니다. 결국 IO 만 잘하는 서버를 갖는 목적은 무엇입니까? 제안이 필요합니다!

최신 정보:

나는 늦게가는 길을 생각하고 있었다. 그것에 대한 제안이 필요합니다. 자, 제가 생각한 것은 이것입니다 : 스레드를 몇 개 갖자 (thread_a_gogo 또는 웹 워커 사용). 이제 더 많이 필요할 때 더 많이 만들 수 있습니다. 그러나 생성 과정에는 약간의 제한이있을 것입니다. (시스템에 의해 암시되지는 않지만 오버 헤드 때문일 수 있습니다). 이제 제한을 초과하면 새 노드를 포크하고 그 위에 스레드를 생성 할 수 있습니다. 이렇게하면 제한에 도달 할 때까지 계속 될 수 있습니다 (결국 프로세스에도 큰 오버 헤드가 있음). 이 제한에 도달하면 작업 대기열을 시작합니다. 스레드가 사용 가능해질 때마다 새 작업이 할당됩니다. 이렇게하면 원활하게 진행될 수 있습니다.

그래서 제가 생각했던 것입니다. 이 아이디어가 좋은가요? 저는이 모든 프로세스와 스레드에 대해 약간 익숙하므로 전문 지식이 없습니다. 여러분의 의견을 공유 해주세요.

감사. :)


참고 : 작업자는 자바 스크립트 기능이 아닌 브라우저 사양입니다.
FredTheWebGuy 2013

글쎄요. 내 질문은 node.js에 관한 것이 었습니다-클라이언트 측이 아닌 서버 코드!
Parth Thakkar 2013

설명은-원래 질문은 NodeJs의 Webworkers에 관한 것이 었습니다. 불가능합니다. NodeJs는 "Threads"를 사용합니다. 그러나 NodeJs 런타임 내에서 WebWorker 구문을 허용하는 NodeJS 모듈이 있습니다.
FredTheWebGuy 2013

답변:


331

노드는 완전히 다른 패러다임을 가지고 있으며 올바르게 캡처되면 문제를 해결하는이 다른 방법을 더 쉽게 볼 수 있습니다. 동일한 작업을 수행하는 방법이 다르기 때문에 Node 응용 프로그램 (1)에 여러 스레드가 필요하지 않습니다. 여러 프로세스를 생성합니다. 그러나 예를 들어 Apache Web Server의 Prefork mpm이 수행하는 방식과는 매우 다릅니다.

지금은 CPU 코어가 하나 뿐이고 일부 작업을 수행하는 애플리케이션을 (노드 방식으로) 개발할 것이라고 가정 해 보겠습니다. 우리의 임무는 내용을 바이트 단위로 실행하는 큰 파일을 처리하는 것입니다. 우리 소프트웨어를위한 가장 좋은 방법은 파일의 처음부터 작업을 시작하여 바이트 단위로 끝까지 따르는 것입니다.

-헤이, 하산, 당신은 할아버지 시대의 초보이거나 아주 오래된 학교라고 생각합니다 !!! 스레드를 생성하여 훨씬 빠르게 만드는 것은 어떻습니까?

-아, CPU 코어가 하나뿐입니다.

-그래서 뭐? 스레드를 만들면 더 빨라집니다!

-그렇게 작동하지 않습니다. 스레드를 만들면 속도가 느려집니다. 스레드 간 전환을 위해 시스템에 많은 오버 헤드를 추가하고, 시간을주고, 프로세스 내부에서 이러한 스레드간에 통신을 시도하기 때문입니다. 이 모든 사실 외에도 단일 작업을 병렬로 수행 할 수있는 여러 조각으로 나누는 방법도 생각해야합니다.

-좋아요, 당신이 가난 하군요. 내 컴퓨터를 사용합시다, 그것은 32 개의 코어를 가지고 있습니다!

-와, 당신은 정말 대단해요, 친애하는 친구, 대단히 감사합니다. 감사합니다!

그런 다음 다시 일합니다. 이제 우리는 부자 친구 덕분에 32 개의 CPU 코어를 갖게되었습니다. 우리가 지켜야 할 규칙이 방금 변경되었습니다. 이제 우리는 우리에게 주어진이 모든 부를 활용하고 싶습니다.

다중 코어를 사용하려면 작업을 병렬로 처리 할 수있는 조각으로 나누는 방법을 찾아야합니다. 노드가 아니라면이를 위해 스레드를 사용합니다. CPU 코어 당 하나씩 32 개의 스레드. 그러나 Node가 있으므로 32 개의 Node 프로세스를 생성합니다.

스레드는 노드 프로세스에 대한 좋은 대안이 될 수 있습니다. 그러나 작업이 이미 정의 된 특정 종류의 작업에서만 처리 방법을 완전히 제어 할 수 있습니다. 그 외에는 우리가 통제 할 수없는 방식으로 외부에서 오는 모든 문제에 대해 가능한 한 빨리 대답하고 싶은 Node의 방식은 틀림없이 우수합니다.

-헤이, Hasan, 아직도 싱글 스레드로 작업하고 있습니까? 넌 왜 그래? 나는 당신이 원하는 것을 제공했습니다. 더 이상 변명의 여지가 없습니다. 스레드를 만들고 더 빠르게 실행하십시오.

-작업을 여러 조각으로 나누었고 모든 프로세스가이 조각 중 하나에서 병렬로 작업 할 것입니다.

-스레드를 생성하지 않는 이유는 무엇입니까?

-죄송합니다. 사용할 수없는 것 같습니다. 원하는 경우 컴퓨터를 가져갈 수 있습니까?

-아니 괜찮아, 멋지다, 왜 쓰레드를 사용하지 않는지 이해가 안 돼?

-컴퓨터 주셔서 감사합니다. :) 저는 이미 작업을 여러 조각으로 나누고이 조각들을 병렬로 작업하는 프로세스를 만듭니다. 모든 CPU 코어가 완전히 활용됩니다. 프로세스 대신 스레드로이 작업을 수행 할 수 있습니다. 하지만 Node는 이런 방식을 가지고 있고 제 상사 Parth Thakkar가 Node.js를 사용하기를 원합니다.

-좋아요, 다른 컴퓨터가 필요한지 알려주세요. :피

32 개 대신 33 개의 프로세스를 생성하면 운영 체제의 스케줄러가 스레드를 일시 중지하고, 다른 하나를 시작하고, 일부주기 후에 일시 중지하고, 다른 하나를 다시 시작합니다. 이것은 불필요한 오버 헤드입니다. 나는 그것을 원하지 않는다. 사실, 32 개의 코어가있는 시스템에서는 정확히 32 개의 프로세스를 만들고 싶지도 않을 입니다. 31 개는 더 좋을 수 있습니다 . 이 시스템에서 작동하는 것은 내 응용 프로그램 뿐만이 아니기 때문입니다. 다른 일을 위해 약간의 공간을 남겨 두는 것이 좋을 수 있습니다. 특히 방이 32 개인 경우 더욱 그렇습니다.

나는 우리가 CPU 집약적 인 작업을 위해 프로세서를 완전히 활용하는 것에 대해 같은 페이지에 있다고 믿습니다 .

-흠, 하산, 조금 조롱해서 미안 해요. 이제 당신을 더 잘 이해한다고 믿습니다. 하지만 여전히 설명이 필요한 것이 있습니다. 수백 개의 스레드를 실행하는 것에 대한 소문이 무엇입니까? 나는 스레드가 프로세스를 포크하는 것보다 생성하고 멍청하다는 것을 어디서나 읽었습니까? 스레드 대신 프로세스를 포크하고 Node.js에서 얻을 수있는 최고 수준이라고 생각합니다. 그렇다면 Node는 이런 종류의 작업에 적합하지 않습니까?

-걱정마, 나도 멋지다. 다들 이런 말을하니 익숙한 것 같아요.

-그래서? 노드가 이것에 좋지 않습니까?

-스레드도 좋을 수 있지만 노드는이를 위해 완벽하게 좋습니다. 스레드 / 프로세스 생성 오버 헤드에 관해서는; 당신이 많이 반복하는 것에 대해서는 밀리 초마다 중요합니다. 그러나 저는 32 개의 프로세스 만 생성하고 시간이 조금 걸립니다. 한 번만 발생합니다. 그것은 어떤 차이도 만들지 않을 것입니다.

-언제 수천 개의 스레드를 생성하고 싶습니까?

-수천 개의 스레드를 만들고 싶지 않습니다. 그러나 HTTP 요청을 처리하는 웹 서버와 같이 외부에서 작업을 수행하는 시스템에서는; 각 요청에 대해 스레드를 사용하는 경우 많은 스레드를 생성하게됩니다.

-노드는 다르지만? 권리?

-네, 맞습니다. 이것은 Node가 실제로 빛나는 곳입니다. 스레드가 프로세스보다 훨씬 가벼운 것처럼 함수 호출은 스레드보다 훨씬 가볍습니다. 노드는 스레드를 생성하는 대신 함수를 호출합니다. 웹 서버의 예에서 들어오는 모든 요청은 함수 호출을 발생시킵니다.

-흠, 흥미 롭군요. 그러나 여러 스레드를 사용하지 않는 경우 동시에 하나의 함수 만 실행할 수 있습니다. 많은 요청이 동시에 웹 서버에 도착할 때 어떻게 작동 할 수 있습니까?

-한 번에 하나씩 함수가 실행되는 방식에 대해 완벽하게 맞습니다. 단일 프로세스에서는 한 번에 하나의 코드 범위 만 실행됩니다. OS Scheduler는 프로세스의 다른 스레드가 아닌 다른 프로세스에 시간을 제공하기 위해 프로세스를 일시 중지하지 않는 한이 기능을 일시 중지하고 다른 것으로 전환하지 않습니다. (2)

-그러면 프로세스가 한 번에 2 개의 요청을 어떻게 처리 할 수 ​​있습니까?

-시스템에 충분한 리소스 (RAM, 네트워크 등)가있는 한 프로세스는 한 번에 수만 개의 요청을 처리 할 수 ​​있습니다. 이러한 기능이 실행되는 방식은 주요 차이점입니다.

-흠, 지금 흥분해야하나요?

-어쩌면 :) 노드는 대기열을 통해 루프를 실행합니다. 이 대기열에는 작업, 즉 들어오는 요청을 처리하기 시작한 호출이 있습니다. 여기서 가장 중요한 점은 실행할 함수를 설계하는 방식입니다. 요청을 처리하기 시작하고 호출자가 작업을 마칠 때까지 기다리게하는 대신 허용 가능한 양의 작업을 수행 한 후 신속하게 기능을 종료합니다. 다른 구성 요소가 일부 작업을 수행하고 값을 반환 할 때까지 기다려야하는 시점에 도달하면 기다리지 않고 나머지 작업을 대기열에 추가하기 만하면됩니다.

-너무 복잡하게 들리나요?

-아니요, 복잡하게 들릴 수도 있습니다. 하지만 시스템 자체는 매우 간단하고 완벽합니다.

이제이 두 개발자 간의 대화를 인용하는 것을 중단하고 이러한 기능이 작동하는 방식에 대한 마지막 간단한 예제를 마치고 답을 마무리하겠습니다.

이런 식으로 OS 스케줄러가 일반적으로 수행하는 작업을 수행합니다. 우리는 어떤 시점에서 작업을 일시 중지하고 다시 차례를 얻을 때까지 다른 함수 호출 (다중 스레드 환경의 다른 스레드와 같은)을 실행하도록합니다. 이것은 시스템의 모든 스레드에 시간을 부여하려는 OS 스케줄러에 작업을 맡기는 것보다 훨씬 낫습니다. 우리는 OS 스케줄러보다 훨씬 더 잘하고있는 것을 알고 있으며 중지해야 할 때 중지 할 것으로 예상됩니다.

다음은 파일을 열고 데이터에 대한 작업을 수행하는 간단한 예입니다.

동기 방식 :

Open File
Repeat This:    
    Read Some
    Do the work

비동기 방식 :

Open File and Do this when it is ready: // Our function returns
    Repeat this:
        Read Some and when it is ready: // Returns again
            Do some work

보시다시피, 우리의 함수는 시스템에 파일을 열도록 요청하고 파일이 열릴 때까지 기다리지 않습니다. 파일이 준비된 후 다음 단계를 제공하여 자동으로 완료됩니다. 돌아 오면 Node는 큐에서 다른 함수 호출을 실행합니다. 모든 기능을 실행 한 후 이벤트 루프는 다음 턴으로 이동합니다.

요약하면 Node는 멀티 스레드 개발과는 완전히 다른 패러다임을 가지고 있습니다. 그러나 이것은 그것이 부족하다는 것을 의미하지 않습니다. 동기식 작업 (처리 순서와 방법을 결정할 수 있음)의 경우 다중 스레드 병렬 처리와 마찬가지로 작동합니다. 서버에 대한 요청과 같이 외부에서 오는 작업의 경우 단순히 우수합니다.


(1) C / C ++와 같은 다른 언어로 라이브러리를 빌드하지 않는 한 작업을 분할하기위한 스레드를 생성하지 않습니다. 이러한 종류의 작업을 위해 두 개의 스레드가 있으며 그중 하나는 Node와 계속 통신하고 다른 하나는 실제 작업을 수행합니다.

(2) 사실, 모든 노드 프로세스에는 첫 번째 각주에서 언급 한 것과 같은 이유로 여러 스레드가 있습니다. 그러나 이것은 유사한 작업을 수행하는 1000 개의 스레드와는 다릅니다. 이러한 추가 스레드는 IO 이벤트를 수락하고 프로세스 간 메시징을 처리하기위한 것입니다.

업데이트 (댓글에 좋은 질문에 대한 답변으로)

@Mark, 건설적인 비판에 감사드립니다. Node의 패러다임에서는 대기열의 다른 모든 호출이 차례로 실행되도록 설계되지 않는 한 처리하는 데 너무 오래 걸리는 함수가 있어서는 안됩니다. 계산 비용이 많이 드는 작업의 경우 전체 그림을 보면 "스레드 또는 프로세스를 사용해야합니까?"라는 질문이 아님을 알 수 있습니다. 그러나 "어떻게 이러한 작업을 균형 잡힌 방식으로 하위 작업으로 분할하여 시스템에 여러 CPU 코어를 사용하여 병렬로 실행할 수 있습니까?" 코어가 8 개인 시스템에서 400 개의 비디오 파일을 처리한다고 가정 해 보겠습니다. 한 번에 하나의 파일을 처리하려면 동일한 파일의 다른 부분을 처리하는 시스템이 필요합니다.이 경우 다중 스레드 단일 프로세스 시스템이 더 쉽게 빌드되고 훨씬 더 효율적일 수 있습니다. 상태 공유 / 통신이 필요할 때 여러 프로세스를 실행하고 메시지를 전달하여이를 위해 Node를 계속 사용할 수 있습니다. 앞서 말했듯이 Node의 다중 프로세스 접근 방식은뿐만 아니라 이러한 종류의 작업에서 다중 스레드 접근 방식; 하지만 그 이상은 아닙니다. 다시 말하지만, Node가 빛나는 상황은 여러 소스에서 시스템에 대한 입력으로 이러한 작업이 들어오는 경우입니다. 여러 연결을 동시에 유지하는 것이 연결 당 스레드 또는 연결 당 프로세스에 비해 노드에서 훨씬 가볍기 때문입니다. 체계.

setTimeout(...,0)전화에 관해서는 때로는 시간이 많이 걸리는 작업 중에 휴식을 취하여 대기열의 통화가 처리 점유율을 가질 수 있도록해야 할 수 있습니다. 작업을 여러 방법으로 나누면 이러한 작업에서 벗어날 수 있습니다. 그러나 여전히 이것은 실제로 해킹이 아니며 이벤트 대기열이 작동하는 방식입니다. 또한 process.nextTick이 목적 을 위해 사용 하는 것이 훨씬 낫습니다.를 사용할 setTimeout때 경과 된 시간을 계산하고 확인하는 것이 필요하지만 process.nextTick우리가 진정 원하는 것은 "이봐, 대기열의 끝으로 돌아가십시오. 공유를 사용하셨습니다! "


9
놀랄 만한! 대단해! 이 질문에 답한 방식이 마음에 들었습니다! :)
Parth Thakkar

48
물론 :)이 답변 기사에 반대 투표를하는 극도로 비열한 사람들이 있다는 사실을 믿을 수 없습니다! 질문자는 그것을 "젠장 어메이징!"이라고 부릅니다. 그리고 책 저자는 이것을보고 그의 웹 사이트에 글을 써 주겠다고 제안합니다. 하지만 일부 천재들이 반대표를 던집니다. 당신의 밝은 지적 특성을 공유하고 비열하고 은밀하게 반대 투표하는 대신 그것에 대해 언급하지 않겠습니까? 왜 좋은 일이 당신을 그렇게 방해합니까? 진정으로 혜택을받을 수있는 다른 사람들에게 도움이되는 것을 막으려는 이유는 무엇입니까?
hasanyasin 2012-07-01

9
이것은 완전히 공정한 대답이 아닙니다. 함수 호출을 "빠르게 종료"할 수없는 계산 비용이 많이 드는 작업은 어떻습니까? 나는 어떤 사람들 setTimeout(...,0)이 이것을 위해 약간의 해킹을 사용한다고 생각 하지만,이 시나리오에서 별도의 스레드를 사용하는 것이 확실히 더 좋을까요?
mpen 2013 년

3
@hasanyasin 이것은 내가 지금까지 찾은 노드에 대한 가장 좋은 설명입니다! :)
Venemo

7
@Mark 일반적으로 계산 비용이 많이 드는 경우 트레드 / 프로세스 작업자를위한 옵션 / 모듈이 있습니다. 일반적으로 이러한 유형의 작업에는 Message Queue를 사용하고 작업을 처리하는 작업자 프로세스가 있습니다. 대기열에서 시간을 보내고 해당 작업을 수행하십시오. 또한 여러 서버로 확장 할 수 있습니다. 이 라인을 따라 Substack에는 프로비저닝 및 확장에 관한 많은 모듈이 있습니다.
Tracker1 2013 년

34

(2016 년 업데이트 : 웹 작업자는 Node.js 포크 Node.js v7 인 io.js 로 이동 합니다. 아래 참조)

(2017 업데이트 : 웹 작업자는 Node.js v7 또는 v8로 이동 하지 않습니다 . 아래 참조)

(2018 년 업데이트 : 웹 작업자 Node.js Node v10.5.0으로 이동합니다. 아래 참조)

약간의 설명

위의 답변을 읽은 후 웹 워커에는 일반적으로 JavaScript와 특히 동시성에 관한 Node의 철학에 위배되는 것은 없다는 점을 지적하고 싶습니다. (만약 있다면, WHATWG에서 논의조차하지 않았을 것이며, 브라우저에서 훨씬 덜 구현되었을 것입니다).

웹 작업자는 비동기 적으로 액세스되는 경량 마이크로 서비스로 생각할 수 있습니다. 공유 된 상태가 없습니다. 잠금 문제가 없습니다. 차단이 없습니다. 동기화가 필요하지 않습니다. Node 프로그램에서 RESTful 서비스를 사용할 때와 마찬가지로 RESTful 서비스가 자체 이벤트 루프와 동일한 스레드에 있지 않기 때문에 이제 "다중 스레드"상태가된다고 걱정할 필요가 없습니다. 비동기 적으로 액세스하는 별도의 서비스 일 뿐이며 그게 중요합니다.

웹 워커도 마찬가지입니다. 완전히 별개의 컨텍스트에서 실행되는 코드와 통신하기위한 API 일 뿐이며, 다른 스레드, 다른 프로세스, 다른 cgroup, 영역, 컨테이너 또는 다른 시스템에 있는지 여부는 완전히 비동기식, 비 차단 API로 인해 완전히 관련이 없습니다. 모든 데이터가 값으로 전달됩니다.

사실 웹 워커는 개념적으로 Node에 완벽하게 적합합니다. Node는 많은 사람들이 알지 못합니다. 우연히 스레드를 상당히 많이 사용하고 실제로 "코드를 제외한 모든 것이 병렬로 실행됩니다"-다음을 참조하십시오.

그러나 웹 워커는 스레드를 사용하여 구현할 필요조차 없습니다. 웹 작업자 API를 사용하는 한 클라우드에서 프로세스, 녹색 스레드 또는 RESTful 서비스를 사용할 수 있습니다. 값 시맨틱으로 호출하는 메시지 전달 API의 전체적인 장점은 동시성 모델의 세부 사항이 노출되지 않기 때문에 기본 구현이 거의 관련이 없다는 것입니다.

단일 스레드 이벤트 루프는 I / O 바인딩 작업에 적합합니다. CPU 바운드 작업, 특히 장기 실행 작업에는 잘 작동하지 않습니다. 이를 위해서는 더 많은 프로세스를 생성하거나 스레드를 사용해야합니다. 이식 가능한 방식으로 자식 프로세스 및 프로세스 간 통신을 관리하는 것은 매우 어려울 수 있으며 종종 간단한 작업에 과잉으로 간주되는 반면 스레드를 사용한다는 것은 제대로 수행하기 매우 어려운 잠금 및 동기화 문제를 처리하는 것을 의미합니다.

자주 권장되는 것은 장기 실행 CPU 바운드 작업을 더 작은 작업으로 나누는 것입니다 ( setInterval의 속도 향상에 대한 답변의 "Original answer"섹션에있는 예제와 같은 것임).하지만 항상 실용적이지는 않으며 더 많이 사용하지 않습니다. 하나 이상의 CPU 코어.

나는 기본적으로 웹 워커가 서버가 아닌 브라우저를 위해 만들어 졌다는 주석을 명확히하기 위해 쓰고있다 (JavaScript의 거의 모든 것에 대해 말할 수 있다는 것을 잊어 버림).

노드 모듈

웹 워커를 노드에 추가해야하는 모듈이 몇 가지 있습니다.

나는 그것들 중 어느 것도 사용하지 않았지만 관련 될 수있는 두 가지 빠른 관찰이 있습니다 .2015 년 3 월 현재 node-webworker는 4 년 전에 마지막으로 업데이트되었고 node-webworker-threads는 한 달 전에 마지막으로 업데이트되었습니다. 또한 node-webworker-threads 사용 예제에서 작업자 생성자에 대한 인수로 파일 이름 대신 함수를 사용할 수 있다는 것을 알 수 있습니다. 이는 메모리를 공유하는 스레드를 사용하여 구현하면 미묘한 문제를 일으킬 수 있습니다 ( 함수는 .toString () 메서드에만 사용되며 그렇지 않으면 다른 환경에서 컴파일됩니다.이 경우에는 괜찮을 수 있습니다. 여기에서 관찰 한 내용을 공유하면서 더 자세히 살펴 봐야합니다.

Node에서 Web Worker API를 구현하는 다른 관련 프로젝트가 있다면 댓글을 남겨주세요.

업데이트 1

글을 쓰는 당시에는 아직 몰랐지만 우연히이 답변을 작성하기 하루 전에 Web Workers가 io.js에 추가되었습니다 .

( io.js 는 Node.js의 포크입니다 . 자세한 내용은 Mikeal Rogers와의 InfoWorld 인터뷰 인 io.js가 Node.js를 포크하기로 결정한 이유를 참조하십시오 .)

이는 웹 워커에서 일반적으로 자바 스크립트의 철학과 특히 동시성에 관한 Node의 철학에 위배되는 것이 없다는 점을 증명할뿐만 아니라 웹 워커가 io와 같은 서버 측 자바 스크립트에서 일류 시민이 될 수 있습니다. 모든 최신 브라우저의 클라이언트 측 JavaScript 이미있는 것처럼 Node.js (및 향후 Node.js) .

업데이트 2

업데이트 1과 내 트윗 에서 io.js pull request # 1159 를 언급 했는데, 이제는 7 월 8 일에 닫히고 아직 열려있는 Node PR # 2133으로 대체 된 Node PR # 1159로 리디렉션됩니다 . io.js / Node.js에서 웹 작업자의 상태에 대한 최신 정보를 제공 할 수있는 풀 요청 아래에서 논의가 진행되고 있습니다.

업데이트 3

최신 정보 -댓글에 게시 한 NiCk Newman에게 감사드립니다 : There is the workers : Petka Antonov가 2015 년 9 월 6 일부터이 트리 에서 다운로드하여 사용해 볼 수있는 초기 구현 커밋 입니다 . 자세한 내용 은 NiCk Newman의 의견을 참조 하십시오.

업데이트 4

현재 2016년 5월 정지 개방의 마지막 코멘트를 홍보 # 2133 - 근로자 : 초기 구현은 3 개월이었다. 5 월 30 일 Matheus Moreira는 아래 댓글에이 답변에 대한 업데이트를 게시 할 것을 요청 했으며 PR 댓글 에서이 기능의 현재 상태를 요청했습니다 .

PR 토론의 첫 번째 답변은 회의적 이었지만 나중에 Ben Noordhuis "이것이 어떤 형태 로든 병합되는 것은 v7의 할 일 목록에 있습니다"라고 썼습니다 .

다른 모든 의견은 두 번째로 보였으며 2016 년 7 월 현재 Web Workers는 2016 년 10 월에 출시 될 예정인 Node , 버전 7.0 (반드시이 정확한 PR 형식이 아님)에서 사용할 수 있어야합니다.

댓글에서 지적하고 GitHub에 대한 토론을 되살려 준 Matheus Moreira에게 감사드립니다.

업데이트 5

현재 2016년 7월 관련 모듈, 검색의 전체 목록 - 이전에 사용할 수 없었던 NPM에 몇 가지 모듈이 있습니다 NPM 특히 아무것도하지 않습니다 또는 당신을 위해 일을하지 않는 경우를 게시하시기 바랍니다 근로자, 웹 근로자 등 논평.

업데이트 6

현재 2017년 1월 은 웹 노동자 Node.js.에 병합 얻을 것 같지는 않다

2133 끌어 오기 요청 # 근로자 : 초기 구현 7월 8일에서 Petka 안토 노프로는 2015 년 마침내 한 폐쇄 우리는 "그와"멀티 스레딩 지원이 충분하지 않은 이익을 위해 너무 많은 새로운 고장 모드를 추가 "주석, 2016 년 12 월 11 일에 벤 Noordhuis에 의해 공유 메모리 및보다 효율적인 직렬화와 같은보다 전통적인 수단을 사용하여이를 달성 할 수도 있습니다. "

자세한 내용은 GitHub 의 PR 2133 에 대한 의견을 참조하십시오 .

의견에서 지적 해 주신 Matheus Moreira에게 다시 한 번 감사드립니다.

업데이트 6

며칠 전 2018 년 6 월에 웹 워커가 Node v10.5.0에 --experimental-worker플래그로 활성화 된 실험적 기능으로 나타났음을 발표하게되어 기쁩니다 .

자세한 내용은 다음을 참조하십시오.

🎉🎉🎉 드디어! 나는 웹 작업자를 스레딩하는 것이 Node 철학에 위배되지 않는다고 주장하는 3 년 된 Stack Overflow 답변에 대한 7 번째 업데이트를 만들 수 있습니다. 이번에는 마침내 우리가 그것을 얻었다 고 말했습니다! 😜👍


1
@NiCkNewman 감사합니다. io.js의 원래 풀 요청이 지금 닫히고 다른 것으로 대체 된 것을 확인했습니다. GitHub의 풀 요청 주석에 대한 토론이 있습니다. 아마도 거기에서 몇 가지 정보를 찾을 수있을 것입니다. 참조 : 내 대답의 업데이트 2.
rsp

1
네, 방금 마지막 libuv 문제를 해결 한 것 같습니다. 언제 모듈을 손에 넣을 수 있는지 궁금합니다. 기다릴 수 없어! 계속 업데이트 해주셔서 감사합니다 ~ 편집 : 방금 초기화되었습니다 : github.com/petkaantonov/io.js/commit/… 이제 시작합니다!
NiCk Newman 2015 년

1
네, 라이브입니다. (아직 공식적으로 구현되지 않았습니다)하지만 여기에서 소스를 다운로드 할 수 있습니다 : github.com/petkaantonov/io.js/tree/… 그리고 테스트하고 싶다면 컴파일하세요! 나는 지금하고 있어요 ~
NiCk Newman 2015-09-06

1
@NiCkNewman 새로운 정보에 감사드립니다-나는 그것을 대답에 추가했습니다.
rsp

1
Node.js workers구현 상태에 대해 업데이트 해 주 시겠습니까? PR # 2133의 최신 댓글 은 2 월입니다. 개발자는 분명히 문제에 부딪 쳤고 문제가 해결되었음을 나타내는 의견이 없습니다.
Matheus Moreira

8

저는 우리가 소프트웨어를 빠르게 만들기 위해 멀티 스레딩을 사용했던 오래된 학교에서 왔습니다. 지난 3 년 동안 저는 Node.js를 사용해 왔으며 이에 대한 큰 지지자입니다. hasanyasin이 노드 작동 방식과 비동기 기능의 개념을 자세히 설명했듯이. 그러나 여기에 몇 가지를 추가하겠습니다.

예전에는 단일 코어와 낮은 클럭 속도로 소프트웨어가 빠르고 병렬로 작동하도록 다양한 방법을 시도했습니다. DOS 시대에는 한 번에 하나의 프로그램을 실행하는 데 사용합니다. Windows에서보다 여러 응용 프로그램 (프로세스)을 함께 실행하기 시작했습니다. 테스트 된 경우 선점 및 비 선점 (또는 협력)과 같은 개념. 이제 선점 형이 단일 코어 컴퓨터에서 더 나은 다중 처리 작업에 대한 해답이라는 것을 알고 있습니다. 이와 함께 프로세스 / 작업 및 컨텍스트 전환의 개념이 등장했습니다. 스레드의 개념보다 프로세스 컨텍스트 전환의 부담을 더욱 줄일 수 있습니다. 새로운 프로세스 생성에 대한 경량 대안으로 만들어진 스레드.

따라서 신호 스레드가 좋든 싫든 멀티 코어 또는 단일 코어가 아니든 프로세스는 OS에 의해 선점되고 시간 분할됩니다.

Nodejs는 단일 프로세스이며 비동기 메커니즘을 제공합니다. 여기서 작업은 작업이 완료 될 때까지 이벤트 루프에서 기다리는 동안 작업을 수행하기 위해 하위 OS로 발송됩니다. OS에서 녹색 신호를 받으면 우리가해야 할 일을 수행합니다. 이제 어떤면에서 이것은 협력 적 / 비선 점적 멀티 태스킹이므로 이벤트 루프를 아주 오랜 시간 동안 차단해서는 안됩니다. 그렇지 않으면 애플리케이션을 매우 빠르게 저하시킬 것입니다.
따라서 자연적으로 차단되거나 시간이 많이 걸리는 작업이있는 경우 OS 및 스레드의 선점 형 세계로 분기해야합니다. 이에 대한 좋은 예가 libuv 문서에 있습니다. 또한 문서를 더 읽으면 FileI / O가 node.js의 스레드에서 처리 된다는 것을 알 수 있습니다.

먼저 소프트웨어 설계에 있습니다. 둘째, 컨텍스트 전환은 그들이 당신에게 무엇을 말하든 항상 발생합니다. 스레드는 거기에 있고 여전히 거기에 이유가 있습니다. 그 이유는 프로세스간에 전환하는 것이 더 빠르기 때문입니다.

node.js의 후드에서 모든 C ++ 및 스레드. 그리고 노드는 C ++ 방식을 제공하여 기능을 확장하고 스레드를 사용하여 속도를 더 높일 수 있습니다. 즉, 소스에서 소스로 읽기, 대용량 데이터 분석 등과 같은 작업을 차단합니다.

나는 hasanyasin 대답이 받아 들여지는 것을 알고 있지만 당신이 말하거나 스크립트 뒤에 숨기는 방법에 관계없이 스레드가 존재할 것입니다. 그리고 스레드는 Node.js의 백본에 있으므로 완전히 배싱하기 전에 멀티 스레딩이 정확합니다. 또한 스레드는 프로세스와 다르며 코어 당 노드 프로세스를 갖는 제한은 스레드 수에 정확히 적용되지 않으며 스레드는 프로세스의 하위 작업과 같습니다. 실제로 스레드는 Windows 작업 관리자 또는 Linux top 명령에 표시되지 않습니다. 다시 한번 그들은 더 작은 무게가 처리됩니다


비동기 코드는 큰 혁신이 아니며 (사실 우리는 수십 년 동안 해왔 던) 멀티 스레딩은 대체 할 더 이상 사용되지 않는 기술이 아닙니다. 그것들은 서로 다른 장단점을 가진 서로 다른 도구이며 실제로 잘 결합 될 수도 있습니다. 노드 클러스터를 실행할 때마다 실제로 여러 "스레드"를 실행합니다 (이 경우 프로세스이지만 스레드를 사용하여 동일한 작업을 수행 할 수 있으며 훨씬 더 가볍습니다). 아니면 ... 녹색 수천 개의 스레드를 실행할 수있는, 얼랑 또는 이동을
Hejazzman

우리가 놓치고있는 주요 요점은 OS 하의 프로세스가 공정성을 제공하기 위해 항상 선제 적으로 수행된다는 것입니다. 또한 다중 프로세서를 사용하면 실제 병렬 코드 실행이 가능하지만 선점도 가능합니다. 비동기 작업은 프로세스의 일부에서 OS에 의해 수행됩니다.
limplash

4

이 경우 웹 워커가 관련성이 있는지 확실하지 않습니다. 클라이언트 측 기술 (브라우저에서 실행)이고 node.js는 서버에서 실행됩니다. 내가 이해하는 한 Fibers도 차단됩니다. 즉, 자발적인 멀티 태스킹이므로 사용할 수 있지만을 통해 컨텍스트 스위치를 직접 관리해야합니다 yield. 스레드는 실제로 필요한 것일 수 있지만 node.js에서 스레드가 얼마나 성숙한 지 모르겠습니다.


3
귀하의 정보를 위해 웹 워커는 node.js에서 (부분적으로) 조정되었습니다. 그리고 node-workers패키지 로 제공됩니다 . 이것 좀보세요 : github.com/cramforce/node-worker
Parth Thakkar

알아서 감사합니다. 문서는 매우 드물지만 별도의 스레드에서 실행되는지, 프로세스에서 실행되는지 아니면 단순히 동일한 프로세스에서 실행되는지 알 수 없으며 코드를 파헤칠 시간이 없어서 그렇게 될지 모르겠습니다. 귀하의 사건을 위해 일하십시오.
lanzz

@ParthThakkar : 해당 프로젝트는 3 년 동안 (게시 당시 2) 건드리지 않았고 0.0.1을 넘지 않았습니다.
mpen 2013 년

@Mark : 제가 무지한 이유는 제가 아직 전문 프로그래머가 아니기 때문입니다. 도대체 저는 대학에 다니지도 않습니다. 나는 여전히 고등학교 펠로우로, 학교 과제를 관리하는 것 외에도 프로그래밍에 대해 계속 읽고 있습니다. 따라서 그러한 모든 문제에 대한 지식을 갖는 것은 원격으로 불가능합니다. 난 그냥 ... 내가 알고있는 것을 게시
Parth Thakkar에게

@Mark : 프로젝트의 역사에 대해 지적 해주셔서 좋았습니다. 이런 것들은 앞으로의 답변에서 처리하겠습니다 !! :)
Parth Thakkar 2013 년

3

worker_threads에서 플래그 뒤에 구현 및 배송되었습니다 node@10.5.0. 여전히 초기 구현이며 향후 릴리스에서 더 효율적으로 만들기 위해 더 많은 노력이 필요합니다. 최신 버전에서 시도해 볼 가치가 있습니다 node.


2

많은 Node 개발자의 의견에서 Node의 가장 좋은 부분 중 하나는 실제로 단일 스레드 특성입니다. 스레드는 노드가 비 차단 IO 만 수행함으로써 완전히 피할 수있는 공유 리소스에 대해 많은 어려움을 야기합니다.

Node가 단일 스레드로 제한 된다는 것은 아닙니다 . 스레드 동시성을 얻는 방법이 찾고있는 방법과 다릅니다. 스레드를 처리하는 표준 방법은 Node 자체에 표준으로 제공 되는 클러스터 모듈을 사용하는 것입니다. 코드에서 스레드를 수동으로 처리하는 것보다 스레드에 대한 더 간단한 접근 방식입니다.

코드에서 비동기 프로그래밍을 처리하려면 (예 : 중첩 된 콜백 피라미드 방지) Fibers 라이브러리 의 [Future] 구성 요소 가 적절한 선택입니다. 또한 Fibers를 기반으로 하는 Asyncblock 을 확인하는 것이 좋습니다 . Fibers는 스택을 복제 한 다음 필요에 따라 단일 스레드에서 스택 사이를 점프하여 콜백을 숨길 수 있기 때문에 좋습니다. 이점을 제공하면서 실제 스레드의 번거 로움을 덜어줍니다. 단점은 파이버를 사용할 때 스택 트레이스가 약간 이상해질 수 있지만 그렇게 나쁘지는 않다는 것입니다.

비동기 작업에 대해 걱정할 필요가없고 차단없이 많은 처리를 수행하는 데 더 관심이있는 경우, 때때로 process.nextTick (callback)에 대한 간단한 호출 만 있으면됩니다.


글쎄, 당신의 제안-클러스터에 대한-내가 처음에 생각했던 것입니다. 하지만 문제는 오버 헤드입니다. 새 프로세스가 포크 될 때마다 v8의 새 인스턴스를 초기화해야합니다 (~ 30ms, 10MB). 그래서 당신은 그것들을 많이 만들 수 없습니다. 이것은 노드 문서에서 직접 가져온 것입니다. 이 자식 노드 (child_processes에 대한) 는 여전히 V8의 완전히 새로운 인스턴스입니다. 각 새 노드에 대해 최소 30ms 시작 및 10mb 메모리를 가정합니다. 즉, 수천 개를 만들 수 없습니다.
Parth Thakkar

1
이것이 바로 클러스터의 아이디어입니다. CPU 코어 당 하나의 작업자를 실행합니다. 더 이상 필요하지 않습니다. CPU 집약적 인 작업조차도 비동기식 스타일로 잘 작동합니다. 그러나 실제로 완전한 스레드가 필요한 경우 다른 서버 백엔드로 완전히 이동하는 것을 고려해야합니다.
genericdave

1

수행중인 작업에 대한 추가 정보가 도움이 될 수 있습니다. 왜 (genericdave의 답변에 대한 귀하의 의견에서 언급했듯이) 수천 개를 만들어야합니까? Node에서 이런 종류의 작업을 수행하는 일반적인 방법은 항상 실행되고 메시지를 사용하여 통신 할 수있는 작업자 프로세스를 시작하는 것입니다 (포크 또는 다른 방법 사용). 즉, 수행중인 작업을 수행해야 할 때마다 새 작업자를 시작하지 말고 이미 실행중인 작업자에게 메시지를 보내고 완료되면 응답을받습니다. 솔직히, 수천 개의 실제 스레드 를 시작하는 것이 매우 효율적 이라는 것을 알 수 없으며 여전히 CPU에 의해 제한됩니다.

이 모든 것을 말한 후, 최근 에 Hook.io 로 많은 작업을 해왔 는데, 이는 이러한 종류의 작업을 다른 프로세스로 오프로드하는 데 매우 잘 작동하는 것 같습니다. 아마도 필요한 것을 달성 할 수있을 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.