Re: [Dbbalancer-users] Re: about DBbalancer
Status: Alpha
Brought to you by:
xperience
From: Andrew M. <an...@ca...> - 2002-02-08 21:11:26
|
On Thu, 2002-02-07 at 13:46, Daniel Varela Santoalla wrote: > > The main difference that I see between this and the current strategy is about > the "synchronicity" of making new connections. In your proposal, is the > request thread who creates new connections when needed, depending on how long > its current wait is. This would be "synchronous" to the requests. So far, > this operation is done by a general thread, who grows or shrinks depending on > the average queue size, "asynchronously" to the requests. Well not _necessarily_ synchronous. The point is that like Apache we want a pre-forked pool of connections! The (a) choice of my earlier e-mail, where we use an existing pre-forked connection _is_ essential, and having a <configurable> nunmber of these ready to handle demand is critical. It's also current behaviour. What this proposal is talking about are those (hopefully fairly infrequent) situations where that isn't enough. Slashdot links to us and suddenly we are dead meat, but _how_ did we die? We should try and handle this unpredictable load as far as is possible. In the real world when these situations happen we _do_ have spare capacity to cope with peaks - just not enough for Everest. So we want to do our best to support the extra users, but we don't want to overdo it and end up serving nobody... > For implementing your proposal, further changes would be needed. I'll explain: > Currently, the daemon always has (SHOULD HAVE) the same number of threads > than of connections. This way, we are sure that every thread has an available > connection whenever they ask for one. If the connection pool grows, also does > the thread pool, and the same for shrinks. So it should be imposible to reach > a situation in which a request being processed (and hence assigned to a > thread) couldn't find its correspondent connection to use. A possible case > would be when a host of a balancing pool failed, but not in "normal" use. > Anyway, for this case it could be useful to introduce "growing" delays, as > you proposed, between the different runs of tests for a connection, saving > the case when threads temporaryly outnumber the "valid" connections available. I see. So for incoming connections which are in a 'pending' state we will need a thread available? Why? I had assumed that it would be handled within the connection setup, before we have decided whether or not we can actually service the request. I see this point as being a queue, rather than a parallel set of threads. The connection threads would be what we would hand the connection off to, once we had made sure one was available. Obviously this complicates the connection startup code, but it doesn't have to get in the way too much. > With this pattern a "processing" request never has to wait, and hence would > never have an opportunity to create a new connection. So, where do "excess" > request go? Well, they are kept in the thread pool queue, not being > "processed" till they not have a thread (and a connection) free for them. > That's why the growing and shrinking is done "asynchronously" by a "manager" > thread, checking the queue size. It's important to note that growing the > connection number WITHOUT growing the thread number is no use, as the new > connections will never be assigned concurrently. This adaptive behaviour is > driven by the queue size, which depends on the number of threads, not on the > number of connections. Yes, the inbound/outbound connection numbers should always be the same, although the configuration file lets you specify separate counts (probably needs to be fixed :-) Could we implement what I am proposing within the current architecture by adding a function to your manager thread that will get it to create a new connection in the pool on request. An incoming connection could then queue, if no connections are available then the thread requests a connection and enters a queue. When the connection is started in due course we can hand it over to the connection request which can then commence work. > I think that a way to proceed is to define a Plan. First, defining goals, > then defining ways to test them, and finally a strategy to get the goals. As > you already pointed, the goals could be (I copy from your Rationale): > > Rationale > > ========= > > > > Firstly, we want to try as hard as possible to give a requesting process > > a connection, rather than a failure. > > Never fail, OK > > > > > Secondly, starting a new connection is a reasonably high-overhead > > process so if one is demanded we should try and put it off slightly as a > > heuristic. This situation will only happen when we are experiencing a > > sudden load growth, so we want to be cautious about over-responding. > > Be cautious with grows, OK > > > > > Finally, when the load drops away from a peak we want to leave the > > machine more available for other maintenance tasks that might occur > > during the quieter periods. We still want to be ready to climb back > > into it if needed though. > > > > And be sure to free resources when no needed, OK. > > I plan to create a test script wich does some connections, then many > concurrent connections, then some serialized connections, then concurrent > again, etc, so that we could: > a) Test correct handling > b) Test performance. > > And the strategy could be the current, modified, or any other. But take in > consideration that while Apache only pools one kind of resource (processes), > we pool two different (threads and connections). Sounds good. Can you not encapsulate the thread / db connection pair? Are they not inseparable? Cheers, Andrew. -- -------------------------------------------------------------------- Andrew @ Catalyst .Net.NZ Ltd, PO Box 11-053, Manners St, Wellington WEB: http://catalyst.net.nz/ PHYS: Level 2, 150-154 Willis St DDI: +64(4)916-7201 MOB: +64(21)635-694 OFFICE: +64(4)499-2267 Are you enrolled at http://schoolreunions.co.nz/ yet? |