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: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]