https://issues.apache.org/bugzilla/show_bug.cgi?id=56798

            Bug ID: 56798
           Summary: Idle eviction strategy could perform better (and is
                    sometimes suboptimal)
           Product: Tomcat Modules
           Version: unspecified
          Hardware: PC
                OS: Mac OS X 10.4
            Status: NEW
          Severity: normal
          Priority: P2
         Component: jdbc-pool
          Assignee: dev@tomcat.apache.org
          Reporter: brenu...@gmail.com

Connections are taken out of the idle pool when available or a new one is
created if the pool limits are yet not reached.
The idle pool is implemented using an ArrayBlockingQueue where:
- returned connections are put back at the TAIL of the queue
- borrowed connections are taken out of the HEAD of the queue
The handling of idle connections follows therefore a FIFO strategy.

The PoolCleaner thread wakes up every timeBetweenEvictionRunsMillis and
attempts to enforce the minIdle limit by removing connections sitting in the
idle pool for more than minEvictableIdleTimeMillis. Unfortunately, this
strategy combined with the FIFO queue handling may lead to less optimal
situation where unnecessary connections are kept alive in the pool although
they could have been removed.

Consider the following scenario:
- PoolCleaner configured to wakeup every 1 second
(timeBetweenEvictionRunsMillis=1000)
- Connection must be idle for at least 500ms before being eligible for eviction
(minEvictableIdleTimeMillis=500)
- minIdle is set to 2
- The pool starts with 5 connections (either because of past activity or
because of initialSize=5)
Suppose the application requests a connection from the pool every 100ms, use it
and releases it almost immediately. Since only one connection is used at a
time, one would expect the pool to shrink to minIdle (i.e. 2 in this example)
after one (or a few) runs of the PoolCleaner thread. But because of FIFO
strategy, none of the 5 connections is eligible for eviction: they all have
been used every 500ms… The entire pool is “hot”.

The higher you set the minEvictableIdleTimeMillis, the higher are the chances
to be hit by this phenomena.

A better strategy seems to use a LIFO queue for the idle connections. This way,
the pool attempts to maximise the use of the “latest” connection and therefore
reduce the amount of “hot” connections. In the previous example, the same
connection would always be reused by the application, letting the other "cool
down" until they become eligible for eviction. 

This would also reduce the chance to get a “stale” connection from the pool
when not configured to validate on borrow. The chance to get a bad connection
from the pool increases with the time the connection stays idle in the pool
(chances are higher they are closed by the db server). With a LIFO strategy,
the pool always gives hot connections that have been used the more recently:
those that are less likely to be closed.


What do you think?

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to