[ 
https://issues.apache.org/jira/browse/AMBARI-14671?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15098599#comment-15098599
 ] 

Jayush Luniya commented on AMBARI-14671:
----------------------------------------

I recently noticed this behavior and after giving this a bit of a thought, and 
came up with a way to dynamically scale up the pool size. Attached is the 
prototype for DynamicScaleThreadPoolExecutor. Essentially the idea is to write 
a custom blocking queue DynamicScaleBlockingQueue which takes scaleThreshold 
and scaleUpPercentage as additional parameters to set thresholds on when to 
scale up and by what amount and then implement the _offer() _method to use 
these scaling parameters to decide when to scale up. Further a requeue 
rejection policy can be use to requeue a rejected request assuming the queue is 
unbounded.


> Reevaluate the use of threadpools in Ambari code base
> -----------------------------------------------------
>
>                 Key: AMBARI-14671
>                 URL: https://issues.apache.org/jira/browse/AMBARI-14671
>             Project: Ambari
>          Issue Type: Bug
>          Components: ambari-server
>    Affects Versions: 2.2.0
>            Reporter: Jayush Luniya
>            Assignee: Jayush Luniya
>             Fix For: 2.4.0
>
>         Attachments: DynamicScaling.tgz
>
>
> As part of investigation for BUG-43981, noticed that in many places in the 
> Ambari code base, the way we use the threadpool is not quite correct.  We 
> will never scale up the number of threads on high load when we use unbounded 
> queues. This could lead to performance bottlenecks especially if we are 
> configure ThreadPoolExecutor with corePoolSize=0 and maxPoolSize=10, only one 
> thread will ever be spawned. See observations below
> Observations: 
> 1. When a ThreadPoolExecutor object is created, the pool size is 0 (i.e. no 
> new threads are created then) unless prestartAllCoreThreads() is called. Also 
> if we set allowCoreThreadTimeOut(true), idle core threads will also be 
> reclaimed.
> 2. In our code base, I observed that we create a threadpool using unlimited 
> queue. However the pool will never scale up from coreThreads -> maxThreads as 
> the request will always get queued. 
> {code:java}
> LinkedBlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>(); // 
> unlimited Queue
> ThreadPoolExecutor threadPoolExecutor =
>     new ThreadPoolExecutor(
>         THREAD_POOL_CORE_SIZE,
>         THREAD_POOL_MAX_SIZE,
>         THREAD_POOL_TIMEOUT_MILLIS,
>         TimeUnit.MILLISECONDS,
>         queue);
> {code}
> http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html
> {quote}
> Unbounded queues. Using an unbounded queue (for example a LinkedBlockingQueue 
> without a predefined capacity) will cause new tasks to wait in the queue when 
> all corePoolSize threads are busy. Thus, no more than corePoolSize threads 
> will ever be created. (And the value of the maximumPoolSize therefore doesn't 
> have any effect.) This may be appropriate when each task is completely 
> independent of others, so tasks cannot affect each others execution; for 
> example, in a web page server. While this style of queuing can be useful in 
> smoothing out transient bursts of requests, it admits the possibility of 
> unbounded work queue growth when commands continue to arrive on average 
> faster than they can be processed.
> {quote}



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to