2016-08-12 5 views
1

mongoDB에 4 천만 데이터가 있습니다. 그 데이터를 컬렉션에서 병렬로 읽고, 처리하고 다른 컬렉션으로 덤핑합니다.Java 멀티 스레딩 성능이 스레드 풀 크기가 증가함에 따라 최악입니다.

작업 초기화를위한 샘플 코드. 2 CPU 1 개 코어 각각 :

ExecutorService executor = Executors.newFixedThreadPool(10); 
int count = total_number_of_records in reading collection 
int pageSize = 5000; 
int counter = (int) ((count%pageSize==0)?(count/pageSize):(count/pageSize+1)); 
for (int i = 1; i <= counter; i++) { 
     Runnable worker = new FinalParallelDataProcessingStrategyOperator(mongoDatabase,vendor,version,importDate,vendorId,i,securitiesId); 
     executor.execute(worker); 
    } 

각 스레드는 데이터로드가 다음 쿼리

mongoDB.getCollection("reading_collection").find(whereClause). 
      .skip(pagesize*(n-1)).limit(pagesize).batchSize(1000).iterator(); 

pagination code reference

기계 구성을 사용하여 페이지 매김

public void run() { 
    try { 
     List<SecurityTemp> temps = loadDataInBatch(); 
     populateToNewCollection(temps); 
     populateToAnotherCollection(temps); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

다음과 같은 일을하고

병렬 구현은 순차와 거의 동일한 성능을 제공합니다. 데이터의 부분 집합에 통계 (319,568 기록)

No. of Threads Execution Time(minutes) 

    1     16 
    3     15 
    8     17 
    10    17 
    15    16 
    20    12 
    50    30 

방법이 응용 프로그램의 성능을 향상시키기 위해?

+0

스레드 수를 늘리면 자동으로 성능이 향상되지 않으며 너무 많은 스레드로 인해 오버 헤드 문제가 발생할 수 있습니다. 왜 당신은 1 - 10 Threads에 대해 동일한 성능을 가지고 있다고 말하기가 힘들겠습니까? 병목 현상은 db입니까? 로컬 DB입니까? – JohnnyAW

+1

JVM 구성 일 수도 있습니다. 하나의 코어에만 액세스 할 수있는 격리 된 환경에서 실행되는 경우 많은 개선이 이루어지지 않을 수도 있습니다. – Gimby

+0

예 로컬 db입니다. – omkar1707

답변

4

(응용 프로그램의 관점에서 보면) 입출력 데이터가 단일 소스에서 읽히기 때문에 병렬로 실행하면 많은 이점을 얻을 수 없습니다. 그 반대 - 나는 여러 스레드에서 parrallel 비슷한 쿼리 (그냥 다른 페이지 생성)를 실행하면 성능에 부정적인 영향을 미칠 것이라고 생각합니다 : 동일한 작업이 DB에서 여러 번 수행되어야하며 병렬 쿼리가 서로에 들어갈 수도 있습니다 방법.

또 다른 질문은 처리 부분이 입력을 읽는 것과 비교하여 상당한 시간이 걸릴지 여부입니다. 병렬 처리를 사용하지 않는다면 속도를 높이는 데별로 도움이되지 않습니다.

  • 이 결과-설정하거나 중간 큐에서 데이터 항목을 취득하고이를 처리하는 여러 작업자 스레드를 가지고 단일 쿼리를 사용하여 DB에서 데이터를 가져 오기 : 만약 그렇다면 나는 다음과 같은 제안 . 고정 배치를 사용할 필요가 없으며, 각 작업자는 이전 배치를 처리하고 나면 다음으로 사용 가능한 항목을 가져옵니다.

스레드 수 : 최소 처리 시간의 "스위트 스폿"은 처리 종류에 따라 다릅니다. 많은 IO 처리가없는 CPU 집약적 인 작업의 경우 사용 가능한 코어의 수와 거의 비슷합니다. -

1

다중 스레드는 스레드 수가 증가하면 성능이 향상되지 않습니다.

IO 바운드 응용 프로그램은 멀티 스레딩을 많이 사용하지 않습니다.

많은 요인에 따라 다릅니다. 이 관련 SE 질문을 참조하십시오 :

Is multithreading faster than single thread?

더 적은 IO 바인딩, CPU 집약적 인 애플리케이션을위한 성능 향상을 위해 스레드의 큰 숫자를 구성하지 마십시오.당신은 당신의 코드를 변경할 수

등 :

ExecutorService executor = Executors.newFixedThreadPool(
Runtime.getRuntime().availableProcessors()); 

또는 (온 병동 ForkJoinPool는 JDK에서 작동합니다 [아래로 1.8 릴리스)

ExecutorService executor = Executors.newWorkStealingPool() 

Executors API :

public static ExecutorService newWorkStealingPool() 

알을 사용하여 작업 도용 스레드 풀을 만듭니다. 사용 가능한 프로세서를 대상 병렬 처리 표로 사용