10

다음과 같습니까? 각 엔트리 (동작 또는 주석 IO)는 여러 가지 방법으로 처리 할 수있는 경우는 해당 경쟁없이 다수의 소비자가 이용 병렬화 할 수 있으므로Disruptor 패턴을 사용하는 경우와 작업을 도용하면서 로컬 스토리지를 사용할 때?

  • disruptor pattern 더 나은 병렬 성능 확장 성을 갖는다.
  • 반대로, 항목을 국지적으로 저장하고 다른 스레드로부터 항목을 도용하는 경우, 항목을 단일 방식으로 만 처리해야하는 경우 병렬 성능과 확장 성이 향상됩니다 (항목을 disruptoint에서 다중 스레드로 분리하여 분배해야하기 때문입니다). 패턴은 경합을 일으킨다.


내 (그리고는 여전히 훨씬 더 빨리 다른 잠금없는 멀티 생산자 다중 소비자 큐 이상 (예를 들어 from boost) 여러 생산자 (즉이 CAS operations)가 참여?를 교란 패턴입니다) 자세히 상황 :

항목을 처리하면 결국 여러 가지 새로운 항목이 생성 될 수 있습니다. 성능은 FIFO 우선 순위로 처리되는 항목의 우선 순위가 가장 높습니다.

현재 구현에서 각 스레드는 로컬 FIFO를 사용하여 새로운 항목을 추가합니다. 유휴 스레드는 다른 스레드의 로컬 FIFO에서 작업을 도용합니다. 스레드의 처리 사이의 종속성은 잠금이없는 mechanically sympathetic 해시 테이블 (버킷 입도로 작성시 CAS)을 사용하여 해결됩니다. 이는 경쟁률이 매우 낮지 만 FIFO 순서가 깨지는 경우가 있습니다.

Disruptor 패턴을 사용하면 FIFO 순서가 보장됩니다. 그러나 엔트리를 쓰레드에 분산시키지 않으면 작업 도용 (예 : 각 쓰레드의 처리량이 거의 같음)이있는 로컬 FIFO보다 훨씬 더 높은 경쟁 (예 : 읽기 커서에서 CAS)이 발생합니까?


참조 나는 해체 작업 분포를 포함하지 않는 the standard technical paper on the disruptor (장 + 6 5)에

성능 테스트를 발견했습니다.

https://groups.google.com/forum/?fromgroups=#!topic/lmax-disruptor/tt3wQthBYd0은 disruptor + work stealing에서 찾은 유일한 참고 자료입니다. 공유 상태가있는 경우 스레드 당 대기열이 매우 느려지지만 세부 사항을 설명하거나 이유를 설명하지 않습니다. 나는이 문장이 내 상황에 적용되는 것을 의심한다.

  • 공유 상태가 잠금없는 해시 테이블로 해결되었다.
  • 소비자 사이에 항목을 분리하여 배포해야하는 경우.
  • 업무용을 제외하고 각 스레드는 로컬 큐에서만 읽고 씁니다.

답변

12

업데이트 - 성능 극대화를위한 최전선 : 혼란과 작업 도용에 대한 관용구 구문과 벤치 마크를 모두 작성해야합니다.

제 생각에는이 차이점은 주로 메시지와 태스크 포커스 사이의 분리라고 생각합니다. 따라서 문제를 생각하는 방식으로 생각합니다. 당신의 문제를 해결하려고 노력하고 그것이 업무 중심적이라면 Disruptor가 적합합니다. 문제가 메시지에 중점을두면 작업 도용과 같은 다른 기술에 더 적합 할 수 있습니다. 구현이 메시지 때을 훔치는

  • 사용 작업을 집중했다. 각 스레드는 메시지를 선택하여 완료까지 실행할 수 있습니다. HTTP 서버 예제 - 각 인바운드 http 요청에는 스레드가 할당됩니다. 구현이 경우 장애 물질이 작업이 집중 사용 연결

  • 을 요청 로깅, 보안 컨트롤을 확인, 가상 호스트 조회를 수행, 파일을 가져 오는, 응답을 전송하고, 폐쇄 - 그 스레드가 마무리에 요청 시작을 처리에 초점을 맞추고 . 각 스레드는 처리의 특정 단계에서 작동 할 수 있습니다. 다른 예 : 작업 포커스의 경우 처리가 단계적으로 분할되므로 로깅을 수행하는 스레드, 보안 제어를위한 스레드, 가상 호스트 조회를위한 스레드 등이 있습니다. 각 스레드는 해당 작업에 초점을 맞추고 요청을 파이프 라인의 다음 스레드로 전달합니다. 스테이지는 병렬화 될 수 있지만 전체 구조는 특정 작업에 초점을 맞춘 스레드이며 스레드간에 메시지를 전달합니다.

물론 각 방법에 맞게 구현을 변경할 수 있습니다.

Disruptor를 사용하려면 문제를 다르게 구조화해야합니다. 일반적으로 단일 스레드가 상태를 소유하고 공유 작업을 통해 모든 작업을 전달함으로써 공유 상태를 제거합니다. 이와 같은 다이어그램이 많은 SEDA를 찾으십시오. 이것은 많은 이점을 가질 수 있지만, 다시 말하면 당신의 구현에 달려 있습니다.

좀 더 상세 :

  • 스럽 - 매우 유용한 모든 작업이 일관된 길이 등의 없을 경우 단계의 엄격한 순서는 추가 혜택을 필요한 경우 : 외부 시스템에 대한 차단 및 처리의 매우 비슷한 양 작업 당. 이 시나리오에서는 모든 스레드가 시스템에서 균등하게 작동하므로 N 개의 스레드를 배열하여 N 개의 메시지를 처리합니다. 나는 쓰레드가 스테이지를 처리하는 곳에서 SEDA와 유사한 시스템을 구현하는 효율적인 방법으로 Disruptor를 생각하고 싶다. 당연히 당신은 하나의 스테이지와 여러 개의 병렬 유닛을 가진 어플리케이션을 각 스테이지에서 동일한 작업을 수행 할 수 있습니다. 그러나 이것은 제 관점에서 볼 때 중요한 것은 아닙니다. 이것은 공유 된 상태의 비용을 완전히 피할 수 있습니다.
  • 작업 도용 - 작업이 가변적이며 메시지 처리 순서가 중요하지 않은 경우이 옵션을 사용하십시오. 이렇게하면 빈 스레드이며 이미 메시지를 소비 한 스레드가 다른 작업 큐에서 계속 진행할 수 있습니다. 이 방법으로 예를 들어 10 개의 스레드가 있고 1이 IO에서 차단 된 경우 나머지는 여전히 처리를 완료합니다.
+0

답장을 보내 주셔서 감사합니다. 불행히도 메시지 초점과 업무 초점의 차이점을 알 수없는 패러다임 사운드를 기반으로 구별을하십시오. – DaveFar

+0

나는 혼란에 대한 나의 문제에 대한 해결책을 설계했다. 한 소비자는 해쉬 값으로 (여러) 방해 요소에 엔트리를 주석 처리하고 다른 소비자는 로컬 해시 테이블에 넣고 엔트리에 플래그가 있는지 주석을 붙인다. 벌써 해시 테이블. 이 솔루션은 빠를 수 있지만 잠금없는 해시 테이블처럼 스레드 수에 따라 선형 적으로 확장되지 않습니다.새로 생성 된 모든 항목에 대해 FIFO를 구현하는 또 다른 장애 요인은 여러 생산자가 있으므로 중재자가 구현의이 부분을 개선할지 여부는 확실하지 않습니다. – DaveFar

+0

Btw, 내 작업은 분명히 다양한 기간이지만 메시지 처리 순서는 다소 중요합니다 ... – DaveFar