본문 바로가기

Database/MongoDB

MongoDB Task Executor Pool

TaskExecutorPool의 구조

What is Task Executor? 

  • TaskExecutor란 MongoDB의 작업 단위를 처리하는 기본 컴포넌트이다. 
  • https://github.com/mongodb/mongo/blob/master/src/mongo/executor/README.md#taskexecutor
  • MongoDB 소스코드 내부에서 event와 callback의 개념을 갖고 다음과 같은 기능을 제공한다. 
    • 원하는 경우 취소하거나 나중에 예약할 수 있는 기능이 포함된 작업 예약.
    • 이벤트를 만들고, 스레드가 이벤트를 구독하도록 하고, 원하는 경우 구독된 스레드에 알림 전송
    • 단일 또는 여러 원격 호스트에서 원격 및 종료 명령을 예약

What is Task Executor Pool? 

  • mongos는 Client로 부터 받은 쿼리 요청을 처리하기 위해서 내부적으로 Task Executor를 사용한다. 
  • 이때, mongos는 Task Executor Pool을 생성해놓고 요청이 들어오면 Task Executor Pool 내의 하나의 Task Executor를 선택하여 작업을 할당한다. 
  • 각 Pool은 mongod와 연결정보를 가지는 connection pool을 하나씩 가지고, connection pool은 커넥션들을 보유하고 있다.  
  • taskExecutorPoolSize를 통해서 Pool Size를 조절할 수 있다.
  • 다음과 같은 Parameter를 통해 설정할 수 있다. 
Parameter Detail Default
taskExecutorPoolSize The number of Task Executor connection pools to use for a given mongos.
If the parameter value is 0 or less, the number of Task Executor connection pools is the number of cores with the following exceptions:
  • If the number of cores is less than 4, the number of Task Executor connection pools is 4.
  • If the number of cores is greater than 64, the number of Task Executor connection pools is 64.
When running MongoDB 6.2 or newer on Linux, you cannot modify the taskExecutorPoolSize from the default value of 1. You may modify this parameter when running MongoDB on Windows or macOS.
1
ShardingTaskExecutorPoolHostTimeoutMs Maximum time that mongos goes without communication to a host before mongos drops all connections to the host.
If set, ShardingTaskExecutorPoolHostTimeoutMS should be greater than the sum of ShardingTaskExecutorPoolRefreshRequirementMS and ShardingTaskExecutorPoolRefreshTimeoutMS. Otherwise, mongos adjusts the value of ShardingTaskExecutorPoolHostTimeoutMS to be greater than the sum.
300000
( 5 minutes ) 
ShardingTaskExecutorPoolMaxSize Maximum number of outbound connections each TaskExecutor connection pool can open to any given mongod instance. The maximum possible connections to any given host across all TaskExecutor pools is:
Sharding TaskExecutorPoolMaxSize * taskExecutorPoolSize
2^64 - 1 
ShardingTaskExecutorPoolMinSize Minimum number of outbound connections each TaskExecutor connection pool can open to any given mongod instance.
ShardingTaskExecutorPoolMinSize connections are created the first time a connection to a new host is requested from the pool. While the pool is idle, the pool maintains this number of connections until ShardingTaskExecutorPoolHostTimeoutMS milliseconds pass without any application using that pool.
For a mongos using the warmMinConnectionsInShardingTaskExecutorPoolOnStartup parameter, the ShardingTaskExecutorPoolMinSize parameter also controls how many connections to each shard host are established on startup of the mongos instance before it begins accepting incoming client connections.
1

 

Why connection of mongod increased dramatically?

  • 특정 Sharded Cluster의 mongos 파라미터를 수정하면서 mongod의 connection이 급격하게 상승했다. 
  • Sharded Cluster에서 mongod가 최소로 가질 수 있는 connection의 갯수는 다음과 같다.
  • 파라미터는 다음과 같이 수정했다. 
setParameter:
   taskExecutorPoolSize : 0
   ShardingTaskExecutorPoolHostTimeoutMS : 3600000
   ShardingTaskExecutorPoolMaxSize : 100
   ShardingTaskExecutorPoolMinSize : 25

 

  • Sharded Cluster에서 mongod가 최소로 가질 수 있는 connection은 다음과 같다. 
mongos count * taskExecutorPoolSize * taskExecutorPoolMinSize

 

  • mongos 파라미터를 수정하자 기본 connection이 2 -> 2,500 으로 급격하게 증가한다. 
AS-IS TO-BE
mongos count : 5
taskExecutorPoolSize: 1 ( default ) 
taskExecutorPoolMinSize: 1
mongod connection count : 5 * 1 *  1 = 5
mongos count : 5
taskExecutorPoolSize: 20 ( cpu core count ) 
taskExecutorPoolMinSize: 25
mongod connection count : 5 * 20 * 25 = 2,500 

 

Compare to another Sharded Cluster 

다른 Sharded Cluster와 비교했을 때 확실히 mongod의 connection 수가 많은 것을 볼 수 있었다. 

 

Result 

이론상으로는 TaskExecutorPoolSize를 적절하게 조절하는게 중요해보인다. 
너무 많은 Pool Size를 갖는 경우 불필요한 Memory를 점유하고 있을 수 있다.
너무 적은 Pool Size를 갖는 경우 Connection의 생성과 삭제에 오버헤드가 발생할 수 있다.
추후 TaskExecutorPoolSize가 실제 부하 상황에서 MongoDB의 성능에 영향을 주는지 테스트해보면 좋을 것 같다.

즉, 잘못된 TaskExecutorPoolSize를 선정하는 경우 mongos ↔ mongod의 오버헤드로 인해서 병목이 되는지 확인하거나
Application Server가 많아 connection 생성 및 삭제에 부하가 높은 Sharded Cluster의 경우 Pool Size를 증가시키면 CPU 사용량이 개선되는지 확인해보면 좋을 것 같다.