commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Christoph Kutzinski <ku...@gmx.de>
Subject Re: [POOL] Offer of help for a 1.4 release
Date Sat, 05 Jan 2008 16:45:37 GMT
Phil Steitz wrote:

>>>> If you are really worried about the cost of object creation then you can
>>>> configure the pool to create all the objects at start-up and block until
a
>>>> free object is available.
>>
>> That is unfortunately not possible under our current configuration as we
>> have set up our application servers to use all connections our database
>> server can handle when their pools have reached their maximum size.
>> For example: we have 40 application servers with a pool max-size of 40.
>> Our database server can just handle (because of its memory
>> configuration) 1600 connections.
>> If we would configure the pools to fetch all connections at startup, we
>> would lose the ability to do updates to our application-software (we
>> have a 2-stage approach to doing updates: we startup the 2nd stage with
>> the new software then configure the load balancer to use the 2nd stage
>> and only afterwards stop the 1st stage) without major hassle.
>>
> So I guess you use the idle object evictor to trim back the
> connections in use by the pools and do the maintenance under low load
> conditions where you can count on only about 50% max connection
> utilization?  Am I following this correctly?  I am not sure I follow
> what you are doing here.

Yes, we use minIdle and softMinEvictableIdleTimeMillis (which should be 
the default IMHO, since I don't see any sensible use for 
minEvictableIdleTimeMillis. But that's a different story) to trim down 
the pool to 10 connections, which is enough under normal load 
conditions. So we have now problems to do updates at that moment.

When we are getting into high load conditions the pool size is ramping 
up over several hours until it reaches 40.

>> I still think that serial connection creation is a good thing as it will
>> help to keep unnecessary load from the database server:
>> As connections borrowed from the pool are held only for a comparably
>> short time (at least in our case), the probability that a connection was
>> returned to pool by a different thread in the near future is quite high.
>>
>> So, by serializing connection creation and rechecking, if a connection
>> is available, before starting to create a new one, you won't burden the
>> db-server with unnecessary load.
>>
> 
> The 1.2 / 1.4-RC1 code does "recheck" before initiating additional
> makes - i.e., it will not initiate a makeObject if an idle object has
> been returned to the pool or if maxActive has been reached.  I think I
> understand your point though, but again it doesn't seem natural to use
> client thread synchronization in the connection pool as a load
> dampening mechanism for the database.


Where is this recheck? I can't see it - all I see is an initial check, 
but no re-check. I doubt that there can be one in 1.4 RC1 as (as far as 
I see), makeObjects are fully parallel.
I see your point however that I'm trying to use the conn-pool as a load 
throttling mechanism for the db, which I cannot deny. I agree that it is 
questionable if this is a job, which a connection pool should do.


> 
>> Another thing to consider: If the db-server is under high load, creating
>> connections in parallel probably won't give you any time benefits. While
>> in idle mode it may be true that:
>> When I get 1 connection in 100 ms, I also get n (say 4) connections in
>> ~100ms
>> under high load situations it is much different as all processors on the
>> db-server are busy with other jobs. So it will probably look much more
>> like this:
>> 1 connection in 2 seconds
>> 2 connections in 4 seconds
>> ...
> 
> I would be interested to see real data on this and also impacts of
> connection request load spikes on various engines (i.e., how well they
> handle bursts of "simultaneous" connection requests).

I'll see if I can generate a test scenario with our JMeter load tests to 
get at least some data for our environment.

 > The engines are
 > going to end up queueing them anyway and it may be better to leave
 > that concern to them.

That's a very good point (though I think that's just a speculation that 
the engines are queueing them anyway). However I would be still 
concerned in that case that connections, which are not needed anymore, 
are created. Consider this:

Threads A and B are requesting new connection creations. The requests 
are queued up (by the db engine). When the connection for Thread A is 
created, Thread C has already returned his connection to the pool, so B 
could use that one. But since the request for a new connection was 
already issued to the db engine, it will be created now anyway.



Another thing we should consider, is the question what you are trying to 
achieve by using a pool. I can see 2 main points:

I) providing 'objects' fast when they are requested
II) avoiding (unnecessary) load on the engine providing the objects 
(e.g. the DB server)

To some degree both points are important, but different use cases might 
have different priorities:
a) if load on the db server is not the main problem (it has enough power 
to handle even the highest peak with ease), providing connections as 
fast as possible might be the priority. So the pool should create as 
many connections in parallel as are requested.
b) if load on the db matters much and the speed by which connections are 
returned from the pool are not the main problem, you probably want to 
serialize connection creation

In our use case, we are focussed on II and b, since we are trying to 
keep our db server responsive for as long as possible under peak loads.

Different applications may be more focussed on I and a, so my proposed 
changes might be contraproductive for them.


Christoph

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Mime
View raw message