dbbalancer-users Mailing List for DBBalancer (Page 2)
Status: Alpha
Brought to you by:
xperience
You can subscribe to this list here.
2001 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(25) |
Dec
(6) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2002 |
Jan
|
Feb
(7) |
Mar
|
Apr
|
May
|
Jun
|
Jul
(4) |
Aug
|
Sep
|
Oct
(1) |
Nov
(6) |
Dec
(2) |
2003 |
Jan
|
Feb
|
Mar
(2) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(4) |
2004 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(4) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2009 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(6) |
Jun
|
Jul
(1) |
Aug
(1) |
Sep
(1) |
Oct
|
Nov
|
Dec
|
From: Daniel V. S. <dv...@ar...> - 2002-02-07 00:45:45
|
Hello Andrew 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. 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. 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. 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). Please tell me what you think about all this. Best Regards Daniel. > ---------------------------------- Regards from Spain. Daniel Varela ---------------------------------- If you think education is expensive, try ignorance. -Derek Bok (Former Harvard President) |
From: Andrew M. <an...@ca...> - 2002-02-06 11:52:14
|
On Wed, 2002-02-06 at 21:06, Daniel Varela Santoalla wrote: > Yes please. Tell me how you see that facility, in the full detail you have > thought it. This would definitely make DBBalancer more responsive to variable > load peaks.... OK, here is my thinking on this subject. Obviously all up for discussion and dissection. Does anyone else have any ideas along these lines? On Connection ============= DBBalancer would respond to a connection attempt by: (a) looking in the pool for a currently inactive connection (as current). (b) waiting a short time in case a new connection becomes active. (c) starting a new connection to the database. The point behind stage (b) is that when we get a storm of connection requests we back off in a structured manner. The time delay here would start at (say) 10mS, and would (say) double if we have started a new connection in the last (say) 500mS. In the initial implementation I would expect these three parameters to be configurable to enable us to come up with appropriate defaults. A further few parameters would be needed to control the initial pool size, the maximum pool size and the maximum wait. Even when the pool is at maximum size DBBalancer should still wait up to the maximum wait before returning a connection failure. Apache also tracks load to some extent by starting new back ends to be ready for incoming connections. This is specified with a 'minimum spare servers' parameter and I think that DBBalancer would benefit from this approach also. Connection Reaping ================== Periodically DBBalancer should reap some inactive connections. This serves two purposes: (a) Reduce the memory load when we are not serving a peak. (b) Reduce exposure to memory leak problems in database client processes. Apache uses a given client for a <configurable> number of times, and this seems a good strategy to emulate. I would also add some sort of parameter which specified the maximum duration that a connection should be active for. When a connection has serviced more than <n> requests, or been in the pool for longer than <m> seconds (and is inactive, of course) it would be reaped. Similarly to the 'minimum spare servers', Apache implements a 'maximum spare servers' and will reap the longest running servers when demand falls so that there is more than this number of unused connections in the pool. I think DBBalancer should look to having this available as well. Measurement of the 'use' or otherwise of a connection would be over a period of time, such as the last 60 seconds, possibly also configurable in earlier releases. Rationale ========= Firstly, we want to try as hard as possible to give a requesting process a connection, rather than a failure. 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. 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. Regards, 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? |
From: Daniel V. S. <dv...@ar...> - 2002-02-06 08:04:23
|
Yes please. Tell me how you see that facility, in the full detail you have thought it. This would definitely make DBBalancer more responsive to variable load peaks.... Regards Daniel On Wed 06 Feb 2002 04:53, you wrote: > On Wed, 2002-02-06 at 02:09, dvs wrote: > > Ok, I'm open to every contribution. > > Currently I'm focusing in the last new features before trying to pass > > it to BETA status (0.5.0 version). They are basically a "proper" > > shutdown procedure, triggered by SIGTERM, and a few little code reorgs. > > > > Please tell me about what you think it could be useful and we'll > > discuss it in the mailing list. You could file the bugs in the > > SourceForge interface, or comment them here. > > Hi Daniel, > > I have released dbbalancer 0.4.1 into Debian now - it should go in > sometime in the coming week. > > What I would like to see at 0.5.0 is the ability for DBBalancer to > dynamically start a new connection for the pool if all existing ones are > in use. > > I can quote chapter and verse on how I would see such a facility > operate, if you wish. My ideas on this sort of behaviour are roughly in > line with how recent Apache handles load. > > Regards, > Andrew. -- ---------------------------------- Regards from Spain. Daniel Varela ---------------------------------- If you think education is expensive, try ignorance. -Derek Bok (Former Harvard President) |
From: Andrew M. <an...@ca...> - 2002-02-06 03:54:18
|
On Wed, 2002-02-06 at 02:09, dvs wrote: > Ok, I'm open to every contribution. > Currently I'm focusing in the last new features before trying to pass > it to BETA status (0.5.0 version). They are basically a "proper" > shutdown procedure, triggered by SIGTERM, and a few little code reorgs. > > Please tell me about what you think it could be useful and we'll > discuss it in the mailing list. You could file the bugs in the > SourceForge interface, or comment them here. Hi Daniel, I have released dbbalancer 0.4.1 into Debian now - it should go in sometime in the coming week. What I would like to see at 0.5.0 is the ability for DBBalancer to dynamically start a new connection for the pool if all existing ones are in use. I can quote chapter and verse on how I would see such a facility operate, if you wish. My ideas on this sort of behaviour are roughly in line with how recent Apache handles load. Regards, 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? |
From: dvs <dv...@ar...> - 2002-02-05 13:12:31
|
Ok, I'm open to every contribution. Currently I'm focusing in the last new features before trying to pass it to BETA status (0.5.0 version). They are basically a "proper" shutdown procedure, triggered by SIGTERM, and a few little code reorgs. Please tell me about what you think it could be useful and we'll discuss it in the mailing list. You could file the bugs in the SourceForge interface, or comment them here. Best regards Daniel ----- Mensaje Original ----- Remitente: Sergey Puschin <fl...@li...> Fecha: Martes, Febrero 5, 2002 4:41 pm Asunto: about DBbalancer > Hi. > My name is Sergey and I want to take part in this project. > I've found some bugs in DBbalancer. > And also I want to discuss things that I'd like to add to DBbalancer. > > Bye. > //Puschin Sergey > > > |
From: Daniel V. S. <dv...@ar...> - 2001-12-27 22:59:45
|
---------- Forwarded Message ---------- Subject: Re: [Dbbalancer-users] Can't make 'static' Date: Thu, 27 Dec 2001 23:59:23 +0100 From: Daniel Varela Santoalla <dv...@ar...> To: Andrew McMillan <an...@ca...> Hello Andrew. I've been out on holidays so I couldn't answer earlier. I'm sorry. Well, this looks like your libACE.a lacks some symbol definitions. This, in my opinion could come from two facts: - Your libACE.a is miscompiled... or - Your libACE.a wasn't compiled with the same compiler version as dbbalancer is being compiled with. Latest gcc versions changed several times the C++ ABI. If this is not the case please send me a "nm" output from your libACE.a, and I'll try to work out what happens. BTW, I've not tried a static build recently as I've not compiled ACE 5.2 static yet, but it should work. Best Regards Daniel On Sat 22 Dec 2001 21:32, you wrote: > Attempting to build the latest DBBalancer I can't seem to build the > statically linked version. > > c++ -I/usr/local/include -D_REENTRANT -pthread -static -o > dbbalancerd.static DBBalancer.o DBBalancerDaemon.o > config/DBBalancerTxtConfig.o postgres/DBPostgresPooledConnection.o > postgres/DBPostgresWriterConnection.o postgres/DBPostgresBackend.o > postgres/DBPostgresFrontend.o conn_pool/DBPool.o > conn_pool/DBPoolContainer.o conn_pool/DBPooledConnection.o > thread_pool/DBThreadPool.o thread_pool/DBThreadCtlMO.o > method_objects/DBDoConnectionMO.o method_objects/DBManagementMO.o -lACE > -ldl -lrt > /usr/lib/libACE.a(OS.o): In function `ACE_OS::thr_create(void *(*)(void > *), void *, long, unsigned long *, unsigned long *, long, void *, > unsigned int, ACE_Thread_Adapter *)': > OS.o(.text+0xe91): the use of `pthread_attr_setstackaddr' is deprecated, > use `pthread_attr_setstack' > /usr/lib/libACE.a(Malloc.o): In function > `ACE_Based_Pointer_Basic<char>::ACE_Based_Pointer_Basic(void)': > Malloc.o(.ACE_Based_Pointer_Basic<char>::gnu.linkonce.t.(void)+0x27): > undefined reference to `ACE_Singleton<ACE_Based_Pointer_Repository, > ACE_RW_Thread_Mutex>::instance(void)' > /usr/lib/libACE.a(Malloc.o): In function > `ACE_Based_Pointer_Basic<ACE_PI_Control_Block::ACE_Name_Node>::ACE_Based_Po >inter_Basic(void)': > Malloc.o(.ACE_Based_Pointer_Basic<ACE_PI_Control_Block::ACE_Name_Node>::gnu >.linkonce.t.(void) +0x27): undefined reference to > `ACE_Singleton<ACE_Based_Pointer_Repository, > ACE_RW_Thread_Mutex>::instance(void)' /usr/lib/libACE.a(Malloc.o): In > function > `ACE_Based_Pointer<ACE_PI_Control_Block::ACE_Name_Node>::ACE_Based_Pointer( >void)': > Malloc.o(.ACE_Based_Pointer<ACE_PI_Control_Block::ACE_Name_Node>::gnu.linko >nce.t.(void) +0x27): undefined reference to > `ACE_Singleton<ACE_Based_Pointer_Repository, > ACE_RW_Thread_Mutex>::instance(void)' /usr/lib/libACE.a(Malloc.o): In > function > `ACE_Based_Pointer_Basic<char>::ACE_Based_Pointer_Basic(char *)': > Malloc.o(.ACE_Based_Pointer_Basic<char>::gnu.linkonce.t.(char *)+0x37): > undefined reference to `ACE_Singleton<ACE_Based_Pointer_Repository, > ACE_RW_Thread_Mutex>::instance(void)' > /usr/lib/libACE.a(Malloc.o): In function > `ACE_Based_Pointer_Basic<ACE_PI_Control_Block::ACE_Name_Node>::ACE_Based_Po >inter_Basic(ACE_PI_Control_Block::ACE_Name_Node *)': > Malloc.o(.ACE_Based_Pointer_Basic<ACE_PI_Control_Block::ACE_Name_Node>::gnu >.linkonce.t.(ACE_PI_Control_Block::ACE_Name_Node *) +0x37): undefined > reference to `ACE_Singleton<ACE_Based_Pointer_Repository, > ACE_RW_Thread_Mutex>::instance(void)' > /usr/lib/libACE.a(Malloc.o)(.ACE_Based_Pointer<ACE_PI_Control_Block::ACE_Na >me_Node>::gnu.linkonce.t.(ACE_PI_Control_Block::ACE_Name_Node *) > +0x37): more undefined references to > `ACE_Singleton<ACE_Based_Pointer_Repository, > ACE_RW_Thread_Mutex>::instance(void)' follow /usr/lib/libACE.a(Dynamic.o): > In function > `ACE_TSS_Singleton<ACE_Dynamic, ACE_Null_Mutex>::instance(void)': > Dynamic.o(.ACE_TSS_Singleton<ACE_Dynamic, > ACE_Null_Mutex>::gnu.linkonce.t.instance(void)+0x4f): undefined > reference to `ACE_TSS<ACE_Dynamic>::ACE_TSS(ACE_Dynamic *)' > Dynamic.o(.ACE_TSS_Singleton<ACE_Dynamic, > ACE_Null_Mutex>::gnu.linkonce.t.instance(void)+0xec): undefined > reference to `ACE_TSS<ACE_Dynamic>::ACE_TSS(ACE_Dynamic *)' > Dynamic.o(.ACE_TSS_Singleton<ACE_Dynamic, > ACE_Null_Mutex>::gnu.linkonce.t.instance(void)+0x166): undefined > reference to `ACE_TSS<ACE_Dynamic>::operator ACE_Dynamic *(void) const' > /usr/lib/libACE.a(Dynamic.o): In function > `ACE_TSS_Singleton<ACE_Dynamic, > ACE_Null_Mutex>::ACE_TSS_Singleton(void)': > Dynamic.o(.ACE_TSS_Singleton<ACE_Dynamic, > ACE_Null_Mutex>::gnu.linkonce.t.(void)+0x1a): undefined reference to > `ACE_TSS<ACE_Dynamic>::ACE_TSS(ACE_Dynamic *)' > /usr/lib/libACE.a(Memory_Pool.o): In function > `ACE_MMAP_Memory_Pool::map_file(long)': > Memory_Pool.o(.text+0x692): undefined reference to > `ACE_Singleton<ACE_Based_Pointer_Repository, > ACE_RW_Thread_Mutex>::instance(void)' > /usr/lib/libACE.a(Memory_Pool.o): In function > `ACE_MMAP_Memory_Pool::release(void)': > Memory_Pool.o(.text+0x1958): undefined reference to > `ACE_Singleton<ACE_Based_Pointer_Repository, > ACE_RW_Thread_Mutex>::instance(void)' > /usr/lib/libACE.a(Reactor.o): In function > `ACE_Reactor::ACE_Reactor(ACE_Reactor_Impl *, int)': > Reactor.o(.text+0x44): undefined reference to > `ACE_Select_Reactor_T<ACE_Select_Reactor_Token_T<ACE_Token> > > >::ACE_Select_Reactor_T(ACE_Sig_Handler *, > > ACE_Timer_Queue_T<ACE_Event_Handler *, > ACE_Event_Handler_Handle_Timeout_Upcall<ACE_Recursive_Thread_Mutex>, > ACE_Recursive_Thread_Mutex> *, int, ACE_Reactor_Notify *, int)' > collect2: ld returned 1 exit status > make: *** [static] Error 1 -- ---------------------------------- Regards from Spain. Daniel Varela ---------------------------------- If you think education is expensive, try ignorance. -Derek Bok (Former Harvard President) ------------------------------------------------------- -- ---------------------------------- Regards from Spain. Daniel Varela ---------------------------------- If you think education is expensive, try ignorance. -Derek Bok (Former Harvard President) |
From: Andrew M. <an...@ca...> - 2001-12-24 23:12:06
|
On Tue, 2001-12-25 at 01:12, shi wrote: > Hello everybody; > I am just trying to install dbbalancer-0.4.1.tar.gz on Redhat7.2. > > I had installed ACE-5.2 on /usr/local/ace. And after I finished complied > ACE,it seems that there is no "/usr/local/ace/lib" directory(the > libACE.so is in /usr/local/ace/ace/). > > When I tried to install DBBalancer-0.4.1.tar .gz using ./configure > command, I got the following error: > > /configure --with-ACE=/usr/local/ace > > Error: libACE.so wasn't found. If it's installed in your system please > use --with-ACE parameter to specify the base directory of the > installation. Compilation will likely to fail in any other case. > > Can you tell me how to do it? Thank you very much!! You could try doing a symlink in your /usr/local/ace directory: ln -s ace lib 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? |
From: shi <sh...@qr...> - 2001-12-24 12:08:58
|
Hello everybody; I am just trying to install dbbalancer-0.4.1.tar.gz on Redhat7.2. =20 I had installed ACE-5.2 on /usr/local/ace. And after I finished complied ACE,it seems that there is no "/usr/local/ace/lib" directory(the libACE.so is in /usr/local/ace/ace/). When I tried to install DBBalancer-0.4.1.tar .gz using ./configure command, I got the following error:=20 =2E/configure --with-ACE=3D/usr/local/ace=20 Error: libACE.so wasn't found. If it's installed in your system please=20 use --with-ACE parameter to specify the base directory of the=20 installation. Compilation will likely to fail in any other case.=20 Can you tell me how to do it? Thank you very much!! Regards=20 Merry Christmas and Happy New Year! ------=20 Shi Jiangang sh...@qr... |
From: Andrew M. <an...@ca...> - 2001-12-22 20:33:06
|
Attempting to build the latest DBBalancer I can't seem to build the statically linked version. c++ -I/usr/local/include -D_REENTRANT -pthread -static -o dbbalancerd.static DBBalancer.o DBBalancerDaemon.o config/DBBalancerTxtConfig.o postgres/DBPostgresPooledConnection.o postgres/DBPostgresWriterConnection.o postgres/DBPostgresBackend.o postgres/DBPostgresFrontend.o conn_pool/DBPool.o conn_pool/DBPoolContainer.o conn_pool/DBPooledConnection.o thread_pool/DBThreadPool.o thread_pool/DBThreadCtlMO.o method_objects/DBDoConnectionMO.o method_objects/DBManagementMO.o -lACE -ldl -lrt /usr/lib/libACE.a(OS.o): In function `ACE_OS::thr_create(void *(*)(void *), void *, long, unsigned long *, unsigned long *, long, void *, unsigned int, ACE_Thread_Adapter *)': OS.o(.text+0xe91): the use of `pthread_attr_setstackaddr' is deprecated, use `pthread_attr_setstack' /usr/lib/libACE.a(Malloc.o): In function `ACE_Based_Pointer_Basic<char>::ACE_Based_Pointer_Basic(void)': Malloc.o(.ACE_Based_Pointer_Basic<char>::gnu.linkonce.t.(void)+0x27): undefined reference to `ACE_Singleton<ACE_Based_Pointer_Repository, ACE_RW_Thread_Mutex>::instance(void)' /usr/lib/libACE.a(Malloc.o): In function `ACE_Based_Pointer_Basic<ACE_PI_Control_Block::ACE_Name_Node>::ACE_Based_Pointer_Basic(void)': Malloc.o(.ACE_Based_Pointer_Basic<ACE_PI_Control_Block::ACE_Name_Node>::gnu.linkonce.t.(void) +0x27): undefined reference to `ACE_Singleton<ACE_Based_Pointer_Repository, ACE_RW_Thread_Mutex>::instance(void)' /usr/lib/libACE.a(Malloc.o): In function `ACE_Based_Pointer<ACE_PI_Control_Block::ACE_Name_Node>::ACE_Based_Pointer(void)': Malloc.o(.ACE_Based_Pointer<ACE_PI_Control_Block::ACE_Name_Node>::gnu.linkonce.t.(void) +0x27): undefined reference to `ACE_Singleton<ACE_Based_Pointer_Repository, ACE_RW_Thread_Mutex>::instance(void)' /usr/lib/libACE.a(Malloc.o): In function `ACE_Based_Pointer_Basic<char>::ACE_Based_Pointer_Basic(char *)': Malloc.o(.ACE_Based_Pointer_Basic<char>::gnu.linkonce.t.(char *)+0x37): undefined reference to `ACE_Singleton<ACE_Based_Pointer_Repository, ACE_RW_Thread_Mutex>::instance(void)' /usr/lib/libACE.a(Malloc.o): In function `ACE_Based_Pointer_Basic<ACE_PI_Control_Block::ACE_Name_Node>::ACE_Based_Pointer_Basic(ACE_PI_Control_Block::ACE_Name_Node *)': Malloc.o(.ACE_Based_Pointer_Basic<ACE_PI_Control_Block::ACE_Name_Node>::gnu.linkonce.t.(ACE_PI_Control_Block::ACE_Name_Node *) +0x37): undefined reference to `ACE_Singleton<ACE_Based_Pointer_Repository, ACE_RW_Thread_Mutex>::instance(void)' /usr/lib/libACE.a(Malloc.o)(.ACE_Based_Pointer<ACE_PI_Control_Block::ACE_Name_Node>::gnu.linkonce.t.(ACE_PI_Control_Block::ACE_Name_Node *) +0x37): more undefined references to `ACE_Singleton<ACE_Based_Pointer_Repository, ACE_RW_Thread_Mutex>::instance(void)' follow /usr/lib/libACE.a(Dynamic.o): In function `ACE_TSS_Singleton<ACE_Dynamic, ACE_Null_Mutex>::instance(void)': Dynamic.o(.ACE_TSS_Singleton<ACE_Dynamic, ACE_Null_Mutex>::gnu.linkonce.t.instance(void)+0x4f): undefined reference to `ACE_TSS<ACE_Dynamic>::ACE_TSS(ACE_Dynamic *)' Dynamic.o(.ACE_TSS_Singleton<ACE_Dynamic, ACE_Null_Mutex>::gnu.linkonce.t.instance(void)+0xec): undefined reference to `ACE_TSS<ACE_Dynamic>::ACE_TSS(ACE_Dynamic *)' Dynamic.o(.ACE_TSS_Singleton<ACE_Dynamic, ACE_Null_Mutex>::gnu.linkonce.t.instance(void)+0x166): undefined reference to `ACE_TSS<ACE_Dynamic>::operator ACE_Dynamic *(void) const' /usr/lib/libACE.a(Dynamic.o): In function `ACE_TSS_Singleton<ACE_Dynamic, ACE_Null_Mutex>::ACE_TSS_Singleton(void)': Dynamic.o(.ACE_TSS_Singleton<ACE_Dynamic, ACE_Null_Mutex>::gnu.linkonce.t.(void)+0x1a): undefined reference to `ACE_TSS<ACE_Dynamic>::ACE_TSS(ACE_Dynamic *)' /usr/lib/libACE.a(Memory_Pool.o): In function `ACE_MMAP_Memory_Pool::map_file(long)': Memory_Pool.o(.text+0x692): undefined reference to `ACE_Singleton<ACE_Based_Pointer_Repository, ACE_RW_Thread_Mutex>::instance(void)' /usr/lib/libACE.a(Memory_Pool.o): In function `ACE_MMAP_Memory_Pool::release(void)': Memory_Pool.o(.text+0x1958): undefined reference to `ACE_Singleton<ACE_Based_Pointer_Repository, ACE_RW_Thread_Mutex>::instance(void)' /usr/lib/libACE.a(Reactor.o): In function `ACE_Reactor::ACE_Reactor(ACE_Reactor_Impl *, int)': Reactor.o(.text+0x44): undefined reference to `ACE_Select_Reactor_T<ACE_Select_Reactor_Token_T<ACE_Token> >::ACE_Select_Reactor_T(ACE_Sig_Handler *, ACE_Timer_Queue_T<ACE_Event_Handler *, ACE_Event_Handler_Handle_Timeout_Upcall<ACE_Recursive_Thread_Mutex>, ACE_Recursive_Thread_Mutex> *, int, ACE_Reactor_Notify *, int)' collect2: ld returned 1 exit status make: *** [static] Error 1 -- -------------------------------------------------------------------- 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? |
From: Daniel V. S. <dv...@ar...> - 2001-12-20 23:13:08
|
Hello everybody. Here we've got a new release of dbbalancer. It has some improvements that will hopefully lead it to a little more acceptance. Anyway, I'm willing to hear your impressions. 0.4.1: - Solved lipq++ test autoconf issue. - Change permission to 777 for UNIX server socket. - Solved (tried to) some problems with static builds and librt - Solved issue when receiving a SSL connection request (patch by Andrew McMillan <an...@ca...>). - Solved bug in DBThreadPool. DBManagementMO consumed one thread, avoiding any request processing where only one thread is configured. - Now the daemon acts like it should: It detaches from the terminal when not in debug mode. - Log messages rationalize. This means reducing a lot when not in debug mode. - Remove the check for the ".conf" extension in the config file. - The UNIX sockets path is configurable (-k). - A pid file is written when the daemon starts. Its path is configurable (-p). - Some code reorganization to ease a little the adding of new parameters. - New logging options (in config file) syslog|file|stderr|stdout - "configure" script improving. -- ---------------------------------- Regards from Spain. Daniel Varela ---------------------------------- If you think education is expensive, try ignorance. -Derek Bok (Former Harvard President) |
From: Daniel V. S. <dv...@ar...> - 2001-11-18 23:29:36
|
On Thu 08 Nov 2001 01:36, you wrote: > > libace is installed as a Debian package, so should be in /usr/lib - I > doubt if that is it, especially as a "ps ax" showed DBBalancer was > _running_ and _appeared_ to have opened connections to the database. Yes, of course... :-) > > I didn't think of it then, but thinking now it was probably the > permissions on the unix socket. Too late to check now, of course :-) > > My init script waits 1 second and then sets the permissions on the > socket, but I found this to be time sensitive before, hence the crude 1 > second delay already... > > Any idea on when you'll be able to fix that wee bug? > I've just uploaded to CVS the last days changes, that should help with a lot of the problems, including that. I'm just waiting to solve the UNIX socket path configuration problem to release 0.4.1. Any idea on how to resolve this:? - Configuration parameter - Runtime parameter. - "configure" "--with" parameter on compiling. I've just taking a look on how does Postgres resolve this, but didn't find still a conclusive response.... Regards -- ---------------------------------- Regards from Spain. Daniel Varela ---------------------------------- If you think education is expensive, try ignorance. -Derek Bok (Former Harvard President) |
From: Daniel V. S. <dv...@ar...> - 2001-11-18 23:29:17
|
On Sat 10 Nov 2001 23:52, Andrew McMillan wrote: I see a problem with this solution: It would force people to have postgres installed in the same machine in which you are compiling. This is not currently required (only if you want to build tests). What I could do is to copy that value as default IF a postgres install is present. So the order could be: - A "-k" flag, just like postmaster, or - a configuration parameter or - a default value, the one taken from postgres or "/tmp" if postgres is not present.. > > Way to go. > > What I did in my setup here was to use the DEFAULT_PGSOCKET_DIR setting > defined in the PostgreSQL header "config.h". Like this: > > #include <postgresql/config.h> > > snprintf(sock_addr.sun_path,sizeof(sock_addr.sun_path), > DEFAULT_PGSOCKET_DIR "/.s.PGSQL.%d",port); > > > I did that in DBPostgresBackend.cc and similarly in DBBalancerDaemon.cc. > > Cheers, > Andrew. -- ---------------------------------- Regards from Spain. Daniel Varela ---------------------------------- If you think education is expensive, try ignorance. -Derek Bok (Former Harvard President) |
From: Andrew M. <an...@ca...> - 2001-11-10 22:53:07
|
On Sat, 2001-11-10 at 00:27, Daniel Varela Santoalla wrote: > > I've just uploaded to CVS the last days changes, that should help with a lot > of the problems, including that. I'm just waiting to solve the UNIX socket > path configuration problem to release 0.4.1. Any idea on how to resolve this:? > > - Configuration parameter > - Runtime parameter. > - "configure" "--with" parameter on compiling. > > I've just taking a look on how does Postgres resolve this, but didn't find > still a conclusive response.... Way to go. What I did in my setup here was to use the DEFAULT_PGSOCKET_DIR setting defined in the PostgreSQL header "config.h". Like this: #include <postgresql/config.h> snprintf(sock_addr.sun_path,sizeof(sock_addr.sun_path), DEFAULT_PGSOCKET_DIR "/.s.PGSQL.%d",port); I did that in DBPostgresBackend.cc and similarly in DBBalancerDaemon.cc. 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 |
From: Daniel V. S. <dv...@ar...> - 2001-11-07 22:39:19
|
On Wed 07 Nov 2001 15:04, you wrote: > HI, > > I have used dbblancer with replication mode on 3 servers succesfully. > > But if i put one of the server off or i stop the postgresql service on one > of them, I can connect to the writer port of the daemon server. > You mean you CAN'T, don't you? > The load balanlcer works very well. > > Could you tell me how to do ? or explain me the running process of the > write mode?? > > Well. First I would like to say that the replication functionality of DBBalancer starts from two premises that somewhat limit its features: a) It had to be a solution external to PostgreSQL, meaning no patches and no fiddling with your existent db's b) It had to be a simple solution, not pretending to cover every situation, much less general than the cases pretended to be covered with DBBalancer's connection pooling or load balancing. That resulted in some limitations. One of them is that if ANY of the replicated DB's fails, there's no way for dbbalancer to put it in sync again, so to avoid bigger problems (like db's getting permanently out of sync) all the daemon's connections are invalidated till that db starts again and the connections are recovered. This could (and should to) be improved, but currently I'm more focused on getting a good connection pool and load balancer. Anyway, all ideas to get this better are of course welcome. Best regards. Daniel -- ---------------------------------- Regards from Spain. Daniel Varela ---------------------------------- If you think education is expensive, try ignorance. -Derek Bok (Former Harvard President) |
From: Andrew M. <an...@ca...> - 2001-11-07 22:11:08
|
We rebooted most of our servers last night (upgrade kernels to 2.2.20) and DBBalancer didn't start properly on boot. I have my init script starting postgres at S20 and DBBalancer at S21, and although DBBalancer was _started_ and _appeared_ to have connections to the database, all database queries were failing since that reboot. Once I stopped and restarted the process it all worked again. Any ideas why this might be? I think the PostgreSQL startup script in Debian stable might exit before the database is fully started, but I thought DBBalancer tried to handle this sort of situation. 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 |
From: Andrew M. <an...@ca...> - 2001-11-07 18:38:10
|
On Wed, 2001-11-07 at 11:48, Daniel Varela Santoalla wrote: > On Tue 06 Nov 2001 01:02, you wrote: > > > Good point. Would it be possible to add a parameter into the > > configuration file which overrode the default, but was in turn > > overridden by the command line? > > But we also would have to keep redundant configuration files... A pair of > reader & writer always share a config file. Well, the sysadmin could do it with a symbolic link... > a) Keeping a config file for each process. This way is easy to know how many > process to spawn from the number of config files. The config file should have > to somewhat say if the process is a reader or a writer with a new parameter. > > b) Keeping a config file for each "source". This would mean that a config > file could spawn a "reader", a "writer" or both, which also would requiere > new parameter, with three possible values. In the case of reader & writer > process the same invocation could fork two times, so that the startup script > didn't have to know about config settings... I think this would be cooler :-) > This is a remain from when XML or TXT files could be used for config. The > check avoided that a XML file was feeded to the TXT module or the opposite. > It's no longer necesary and I'll remove it. OK, great. 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 |
From: Daniel V. S. <dv...@ar...> - 2001-11-07 17:39:39
|
On Tue 06 Nov 2001 01:02, you wrote: > Good point. Would it be possible to add a parameter into the > configuration file which overrode the default, but was in turn > overridden by the command line? But we also would have to keep redundant configuration files... A pair of reader & writer always share a config file. Here I can think of two approaches: a) Keeping a config file for each process. This way is easy to know how many process to spawn from the number of config files. The config file should have to somewhat say if the process is a reader or a writer with a new parameter. b) Keeping a config file for each "source". This would mean that a config file could spawn a "reader", a "writer" or both, which also would requiere new parameter, with three possible values. In the case of reader & writer process the same invocation could fork two times, so that the startup script didn't have to know about config settings... I'd like to know what you think about these two approaches... > One gotcha I found writing my script is that DBBalancer checks that it's > configuration file ends in ".conf" - I don't think that this check is > really necessary. This is a remain from when XML or TXT files could be used for config. The check avoided that a XML file was feeded to the TXT module or the opposite. It's no longer necesary and I'll remove it. -- ---------------------------------- Regards from Spain. Daniel Varela ---------------------------------- If you think education is expensive, try ignorance. -Derek Bok (Former Harvard President) |
From: Daniel V. S. <dv...@ar...> - 2001-11-06 17:19:16
|
Hello Andrew > > Please tell me if you found a different behaviour, cos it surely could be > > a bug. > > I tried setting: > > daemon.init-db-connections=1 > daemon.min-db-connections=1 > daemon.max-db-connections=1 > > And connecting several times in quick succession. I saw a lot more > failures than I was hoping for. Watching the process of finding a > connection also appeared to have almost no wait: > ... > Conn 0, NConns 1. > (5126, 07:50:19.049346) Connection 0::0 is NOT free!!!. > (5126, 07:50:19.049394) Pool 0 won't give us a connection (try 9)!!! > (5126, 07:50:19.049445) Impossible to get a connection after 10 > tries!!! > (5126, 07:50:19.049494) We have not been able to get a connection. > Closing client connection. Have you also set all the thread parameters to 1?. If you've got more threads than connections this is what you likely get. BTW, there is another bug if you set everything to 1 (the "manager" object consumes the only thread preventing any further request processing...., so better try 2 in threads and 1 in connections). I did this with 10 simultaneous clients without any apparent problem (total serialization). Well maybe the wait time should be increased, but this is a situation that we never should reach, with correct configuration. > > What I was expecting to see was that the connections were serialised, so > that the time to respond should have increased to include the time to > wait for previous connections to finish. > > So it looks like a bug... > > Ideally I would see the number of attempts and the first retry delay as > configurable. I would then multiply the retry wait by 1.5 for each > subsequent retry. This "retry" is currently being handled by the thread pool. In fact the enqueued request is handled exactly in the moment when a thread (and hence, a connection) is freed. No delay. > > > What DBBalancer should also make better is the strategy to adaptively > > modify the number of threads and conns. Now it checks the average length > > of the latest 3 checks of the queue, but, while this avoids overreacting > > to fast bursts of requests, it's is quite slow on adapting. > > Sounds like you are saying that it would not be a good idea to set: > > daemon.reaper-delay=60 Definitely NOT. ;-) > > I had assumed that this only applied to _reaping_, not starting up... Yes, that's an example of BAD NAMING to a parameter. It should be called daemon.manager-delay, but as that functionality changed with time, a bad name remained. I'll change it as soon as we definitely set how the growing/reaping/checking will work. > > I think a straightforward approach would be to start connections > immediately if you find none available but are below > daemon.max-db-connections - this would make things responsive to a > quickly ramping load. I consider reaping those when they haven't been > used as a _much_ lower priority, hence my setting of the reaper delay to > a higher level. That can be a good approach. But I would have to change some things, as currently I do request processing in an "async" way, not in a "sync" one. Maybe a different thread, more frecuent... I don't know > > It's not debugging information, it's management information, so I want > to be able to accumulate it on a busy website over several days before > (perhaps) turning it off. > > Naturally I _don't_ want to be logging every query during that time :-) Yes. I'll have to recheck log message "criticity" (:-m.. does this word exist... ;-)). Regards > > Cheers, > Andrew. -- ---------------------------------- Regards from Spain. Daniel Varela ---------------------------------- If you think education is expensive, try ignorance. -Derek Bok (Former Harvard President) |
From: Daniel V. S. <dv...@ar...> - 2001-11-06 17:19:14
|
On Sun 04 Nov 2001 00:13, you wrote: > The idea I have so far is: > > 1) Have a directory of configuration scripts for the various databases > to be 'balanced'. I would make this directory in /etc/dbbalancer/conf.d > which would conform to the way Debian does these sorts of things. > > 2) My init script would then go through each configuration file in the > directory, starting a DBBalancer daemon for each one. I see a problem with this one. The "reader" or "writer" operation is not thought to be extracted from the configuration file, as this file should be shared between a reader and a writer. The difference was in the "-r" or "-w" parameter. Maybe it could be better to use different config files for the reader and the writer, but they share almost all parameters (except for the port)... We have to find the best solution for this... > > 3) The process ID for each process would be written in > /var/run/dbbalancer/<confname> I'll have to make this path configurable, just like the UNIX socket path has to be. > > 4) When run with a 'stop' parameter, the init script would kill each > process. > > Anyone have any comments on that approach? If we find a way for reader/writer thing, I agree > > > Also, a few of things that would be good to see in the current > DBBalancer to support this sort of operation: > > 1) Less logging. Currently DBBalancer logs every connection - this > seems a bit excessive for a website receiving a hundred thousand hits > each day. Although it might be fine to have this level of logging as a > default, it would be nice to be able to reduce it further. That's easy with ACE. I'll put that on 0.4.1. > > 2) 'Detach and run as daemon' option. DBBalancer really is a service, > and it should detach itself from the console and run in background. > This should probably be the default operation, although while we > consider things to be 'alpha' perhaps it should only be an option. We can make it detach only when debug is disabled. Or maybe better set a new parameter. I've looked to "postmaster.c" code ... > > 3) Logging through syslog. In normal operation I am likely to have a > number of DBBalancer daemons operating at the same time, in background, > it will be desirable to collect their error messages in one place. I > would tend towards specifying a log facility in the configuration file, > and using syslog. This is also easy with ACE. I only have to figure "how" ;-) > > With these enhancements, along with fixes to the little niggles that > have come up in the last couple of days with 0.4, I believe we are > probably ready to call it a 'beta', and I will put packages into the > 'unstable' branch of Debian. > > Comments? Well. I fully agree with the last three. The others are also good, but maybe I have to change the way "readers" and "writers" are differentiated. Not a big problem, anyway. > > Regards, > Andrew. -- ---------------------------------- Regards from Spain. Daniel Varela ---------------------------------- If you think education is expensive, try ignorance. -Derek Bok (Former Harvard President) |
From: Daniel V. S. <dv...@ar...> - 2001-11-06 17:19:12
|
Hello Andrew I would like to know a little more about your setup. Are you comparing DBBalancer with PHP "persistent", pconnect()? When you use DBBalancer, do you use also pconnect() or connect()? My very informal tests gave several different results, ranging from a 700% gain in very short querys to an actual loss of performance in the case of the ones that returned a very large result set. I tested C programs (libpq) and TCL ones with libpgtcl. My test programs are in the "tests" subdirectory. They all do: start measure loop N times connect query disconnect. end loop end measure. On Mon 05 Nov 2001 12:09, you wrote: > Hi All, > > This is way preliminary, but it looks so positive I just had to put it > up here... > > |----------+------+-------+-------+---------+--------+--------+ > | > | | Avg | StDev | Max | Min | Median | Sample | > | > |----------+------+-------+-------+---------+--------+--------+ > |Persistent| 0.056| 0.081| 12.674| 0.000361| 0.051 | 74371 | > |----------+------+-------+-------+---------+--------+--------+ > |DBBalancer| 0.020| 0.011| 0.758| 0.000417| 0.019 | 14684 | > > +-------------------------------------------------------------+ > > > The application in question is fairly tuned for performance, managing to > get this particular component (the bit that gets a reasonable number of > hits) down to around three simple queries. > > The performance statistics are measured by wrapping each query, so do > not include any component of execution time for the script (or even the > connection startup time) - just the queries themselves. This doesn't make much sense. How can execution times be faster without counting the connection startup time.... Here is where the gain is supposed to be. Did you try also counting this time? > > Regards, > Andrew. It is good to start seeing some real world results. And it is better to see that they're good :-)) Regards -- ---------------------------------- Regards from Spain. Daniel Varela ---------------------------------- If you think education is expensive, try ignorance. -Derek Bok (Former Harvard President) |
From: Andrew M. <an...@ca...> - 2001-11-06 00:52:09
|
On Tue, 2001-11-06 at 11:56, Daniel Varela Santoalla wrote: > Hello Andrew > > I would like to know a little more about your setup. > Are you comparing DBBalancer with PHP "persistent", pconnect()? > When you use DBBalancer, do you use also pconnect() or connect()? I was using pg_pconnect() before, and when I switched to the DBBalancer connection pool I switched to pg_connect(). > My very informal tests gave several different results, ranging from a 700% > gain in very short querys to an actual loss of performance in the case of the > ones that returned a very large result set. I tested C programs (libpq) and My live application does a single "SELECT myfunction(parameters);" and that function (which is written in PL/PgSQL) will return a single TEXT value of less than 100 bytes. Internally the PL/PgSQL function does two SELECTs, the first will return no rows, and the second will return a single row. It will then do a single INSERT into a table which is cleaned periodically by a background process. As you might guess from my description, this particular process has been carefully put together for maximum performance, and I want it to be able to survive extreme loads, hopefully one or two orders of magnitude greater than current. This isn't really a benchmark, it's a real-world measurement of application performance. As such it is perhaps lesss applicable to other people, but it certainly applies to me :-) Cheers, Andrew. > On Mon 05 Nov 2001 12:09, you wrote: > > Hi All, > > > > This is way preliminary, but it looks so positive I just had to put it > > up here... > > > > |----------+------+-------+-------+---------+--------+--------+ > > | > > | | Avg | StDev | Max | Min | Median | Sample | > > | > > |----------+------+-------+-------+---------+--------+--------+ > > |Persistent| 0.056| 0.081| 12.674| 0.000361| 0.051 | 74371 | > > |----------+------+-------+-------+---------+--------+--------+ > > |DBBalancer| 0.020| 0.011| 0.758| 0.000417| 0.019 | 14684 | > > > > +-------------------------------------------------------------+ > > > > > > The application in question is fairly tuned for performance, managing to > > get this particular component (the bit that gets a reasonable number of > > hits) down to around three simple queries. > > > > The performance statistics are measured by wrapping each query, so do > > not include any component of execution time for the script (or even the > > connection startup time) - just the queries themselves. > > This doesn't make much sense. How can execution times be faster without > counting the connection startup time.... Here is where the gain is supposed > to be. Did you try also counting this time? > > > > > Regards, > > Andrew. > > It is good to start seeing some real world results. And it is better to see > that they're good :-)) > > Regards > > -- > > ---------------------------------- > Regards from Spain. Daniel Varela > ---------------------------------- > > If you think education is expensive, try ignorance. > -Derek Bok (Former Harvard President) > -- -------------------------------------------------------------------- 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 |
From: Andrew M. <an...@ca...> - 2001-11-06 00:24:10
|
On Tue, 2001-11-06 at 09:23, Daniel Varela Santoalla wrote: > > > > I tried setting: > > > > daemon.init-db-connections=1 > > daemon.min-db-connections=1 > > daemon.max-db-connections=1 > > > > And connecting several times in quick succession. I saw a lot more > > failures than I was hoping for. Watching the process of finding a > > connection also appeared to have almost no wait: > > > ... > > > Conn 0, NConns 1. > > (5126, 07:50:19.049346) Connection 0::0 is NOT free!!!. > > (5126, 07:50:19.049394) Pool 0 won't give us a connection (try 9)!!! > > (5126, 07:50:19.049445) Impossible to get a connection after 10 > > tries!!! > > (5126, 07:50:19.049494) We have not been able to get a connection. > > Closing client connection. > > Have you also set all the thread parameters to 1?. If you've got more threads > than connections this is what you likely get. BTW, there is another bug if > you set everything to 1 (the "manager" object consumes the only thread > preventing any further request processing...., so better try 2 in threads and > 1 in connections). I did this with 10 simultaneous clients without any > apparent problem (total serialization). > > Well maybe the wait time should be increased, but this is a situation that we > never should reach, with correct configuration. Right, so if there are hard dependencies between these parameter settings, perhaps they should be one parameter setting... The threads for the above were set to: daemon.init-threads=5 daemon.min-threads=5 daemon.max-threads=30 because I was testing exactly this sort of behaviour. On the other hand, I have a resource-scarce computer where I have a choice of having 50 concurrent database clients operating, or waiting 50 milliseconds for one to become available. If my client connects in to DBBalancer and there is no connection currently available to the database (all available connections are in use) then I really would like to try simply waiting for one to become available, as one strategy. As load increases it becomes much more predictable on a statistical basis, so this becomes an increasingly reasonable approach. > > Ideally I would see the number of attempts and the first retry delay as > > configurable. I would then multiply the retry wait by 1.5 for each > > subsequent retry. > > This "retry" is currently being handled by the thread pool. In fact the > enqueued request is handled exactly in the moment when a thread (and hence, a > connection) is freed. No delay. Right, so I guess I'm not reporting a bug, I'm requesting an enhancement! I would like it though :-) > > I think a straightforward approach would be to start connections > > immediately if you find none available but are below > > daemon.max-db-connections - this would make things responsive to a > > quickly ramping load. I consider reaping those when they haven't been > > used as a _much_ lower priority, hence my setting of the reaper delay to > > a higher level. > > That can be a good approach. But I would have to change some things, as > currently I do request processing in an "async" way, not in a "sync" one. > Maybe a different thread, more frecuent... I don't know. Again, I like the way Apache behaves on this sort of situation - all connections come in to the manager and are handed off to the next available server. If no servers are available, and we aren't already running more than the maximum, it will start another one. As servers are started, Apache insists on delaying X seconds between them, and it keeps increasing X when it receives a lot of requests at once. It doesn't actually close the connection with a failure unless it exceeds the maximum though. > > Naturally I _don't_ want to be logging every query during that time :-) > > Yes. I'll have to recheck log message "criticity" (:-m.. does this word > exist... ;-)). "criticality" :-) 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 |
From: Andrew M. <an...@ca...> - 2001-11-06 00:03:11
|
On Tue, 2001-11-06 at 09:40, Daniel Varela Santoalla wrote: > On Sun 04 Nov 2001 00:13, you wrote: > > > The idea I have so far is: > > > > 1) Have a directory of configuration scripts for the various databases > > to be 'balanced'. I would make this directory in /etc/dbbalancer/conf.d > > which would conform to the way Debian does these sorts of things. > > > > 2) My init script would then go through each configuration file in the > > directory, starting a DBBalancer daemon for each one. > > I see a problem with this one. The "reader" or "writer" operation is not > thought to be extracted from the configuration file, as this file should be > shared between a reader and a writer. The difference was in the "-r" or "-w" > parameter. Maybe it could be better to use different config files for the > reader and the writer, but they share almost all parameters (except for the > port)... We have to find the best solution for this... Good point. Would it be possible to add a parameter into the configuration file which overrode the default, but was in turn overridden by the command line? Alternatively, I could have my script use something of the configuration file name, so that files xxxxx.conf were readers and xxxxx-w.conf were writes. Crude, but workable. One gotcha I found writing my script is that DBBalancer checks that it's configuration file ends in ".conf" - I don't think that this check is really necessary. > > 3) The process ID for each process would be written in > > /var/run/dbbalancer/<confname> > > I'll have to make this path configurable, just like the UNIX socket path has > to be. I have the above scheme working under Debian by specifying the pidfile name as a parameter to the start-stop-daemon command. It works now, but there would be differences if the Daemon was writing it's own pidfile. > Well. I fully agree with the last three. The others are also good, but maybe > I have to change the way "readers" and "writers" are differentiated. Not a > big problem, anyway. I can't wait :-) Thanks, 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 |
From: Andrew M. <an...@ca...> - 2001-11-05 11:10:06
|
Hi All, This is way preliminary, but it looks so positive I just had to put it up here... |----------+------+-------+-------+---------+--------+--------+ | | Avg | StDev | Max | Min | Median | Sample | |----------+------+-------+-------+---------+--------+--------+ |Persistent| 0.056| 0.081| 12.674| 0.000361| 0.051 | 74371 | |----------+------+-------+-------+---------+--------+--------+ |DBBalancer| 0.020| 0.011| 0.758| 0.000417| 0.019 | 14684 | +-------------------------------------------------------------+ So connection pooling with DBBalancer appears to be giving me a 270% increase in performance for the queries in my application. I've attached an HTML table with further breakdown, showing how with DBBalancer installed today I beat the performance on every measure (except minimum) for any of the last seven days. Cool. The application in question is fairly tuned for performance, managing to get this particular component (the bit that gets a reasonable number of hits) down to around three simple queries. The performance statistics are measured by wrapping each query, so do not include any component of execution time for the script (or even the connection startup time) - just the queries themselves. Regards, 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 |
From: Andrew M. <an...@ca...> - 2001-11-04 19:09:57
|
On Mon, 2001-11-05 at 01:15, Daniel Varela Santoalla wrote: > > > > In the event that all back-end connections are in use, > > it would be reasonable to put the request into a queue, > > holding it in abeyance for a [configurable] period of > > time before finally giving up and returning the > > connection failure to the client. > > Well, I think that's what happens now, not at the connection level but at the > thread pool level. Given that the thread number is equal to the connections > number (which is the logical approach), if all the connections are busy is > because all the threads are also busy. Then it is DBThreadPool who enqueues > (via its activation_queue_ attribute) all new requests. Of course this > doesn't work if there's a bigger number of threads than connections, but this > situation should never happen unless configured so, because even the growing > and shrinking of pools go synchronized (thread and conns at the same time and > equivalent number). > > Please tell me if you found a different behaviour, cos it surely could be a > bug. I tried setting: daemon.init-db-connections=1 daemon.min-db-connections=1 daemon.max-db-connections=1 And connecting several times in quick succession. I saw a lot more failures than I was hoping for. Watching the process of finding a connection also appeared to have almost no wait: (1024, 07:50:19.047101) Connection received. (1024, 07:50:19.047286) Waiting for a connection to server socket. (5126, 07:50:19.047384) Pool 0 is going to be asked for a connection... (5126 07:50:19.047446) DBPool::getPooledConnection(): Checking Pool 0, Conn 0, NConns 1. (5126, 07:50:19.047505) Connection 0::0 is NOT free!!!. (5126, 07:50:19.047557) Pool 0 won't give us a connection (try 0)!!! (5126, 07:50:19.047607) Pool 0 is going to be asked for a connection... (5126 07:50:19.047657) DBPool::getPooledConnection(): Checking Pool 0, Conn 0, NConns 1. (5126, 07:50:19.047709) Connection 0::0 is NOT free!!!. (5126, 07:50:19.047758) Pool 0 won't give us a connection (try 1)!!! (5126, 07:50:19.047808) Pool 0 is going to be asked for a connection... (5126 07:50:19.047858) DBPool::getPooledConnection(): Checking Pool 0, Conn 0, NConns 1. (5126, 07:50:19.047910) Connection 0::0 is NOT free!!!. (5126, 07:50:19.047959) Pool 0 won't give us a connection (try 2)!!! (5126, 07:50:19.048009) Pool 0 is going to be asked for a connection... (5126 07:50:19.048059) DBPool::getPooledConnection(): Checking Pool 0, Conn 0, NConns 1. (5126, 07:50:19.048111) Connection 0::0 is NOT free!!!. (5126, 07:50:19.048160) Pool 0 won't give us a connection (try 3)!!! (5126, 07:50:19.048210) Pool 0 is going to be asked for a connection... (5126 07:50:19.048260) DBPool::getPooledConnection(): Checking Pool 0, Conn 0, NConns 1. (5126, 07:50:19.048312) Connection 0::0 is NOT free!!!. (5126, 07:50:19.048361) Pool 0 won't give us a connection (try 4)!!! (5126, 07:50:19.048411) Pool 0 is going to be asked for a connection... (5126 07:50:19.048460) DBPool::getPooledConnection(): Checking Pool 0, Conn 0, NConns 1. (5126, 07:50:19.048512) Connection 0::0 is NOT free!!!. (5126, 07:50:19.048561) Pool 0 won't give us a connection (try 5)!!! (5126, 07:50:19.048611) Pool 0 is going to be asked for a connection... (5126 07:50:19.048661) DBPool::getPooledConnection(): Checking Pool 0, Conn 0, NConns 1. (5126, 07:50:19.048713) Connection 0::0 is NOT free!!!. (5126, 07:50:19.048762) Pool 0 won't give us a connection (try 6)!!! (5126, 07:50:19.048812) Pool 0 is going to be asked for a connection... (5126 07:50:19.048862) DBPool::getPooledConnection(): Checking Pool 0, Conn 0, NConns 1. (5126, 07:50:19.048914) Connection 0::0 is NOT free!!!. (5126, 07:50:19.048963) Pool 0 won't give us a connection (try 7)!!! (5126, 07:50:19.049013) Pool 0 is going to be asked for a connection... (5126 07:50:19.049093) DBPool::getPooledConnection(): Checking Pool 0, Conn 0, NConns 1. (5126, 07:50:19.049145) Connection 0::0 is NOT free!!!. (5126, 07:50:19.049194) Pool 0 won't give us a connection (try 8)!!! (5126, 07:50:19.049244) Pool 0 is going to be asked for a connection... (5126 07:50:19.049294) DBPool::getPooledConnection(): Checking Pool 0, Conn 0, NConns 1. (5126, 07:50:19.049346) Connection 0::0 is NOT free!!!. (5126, 07:50:19.049394) Pool 0 won't give us a connection (try 9)!!! (5126, 07:50:19.049445) Impossible to get a connection after 10 tries!!! (5126, 07:50:19.049494) We have not been able to get a connection. Closing client connection. (4101, 07:50:19.082427) 1 descriptors modified. (4101, 07:50:19.082540) Received 47 bytes from BE socket. HEXDUMP 47 bytes 50 62 6c 61 6e 6b 00 54 00 01 64 65 74 61 69 6c Pblank.T..detail 5f 68 69 74 00 00 00 00 17 00 04 ff ff ff ff 44 _hit...........D 80 00 00 00 05 31 43 53 45 4c 45 43 54 00 5a .....1CSELECT.Z (4101, 07:50:19.082700) Sent 47 bytes to FE socket. ************** handleConnectionLoop (it: 56) ************* (4101, 07:50:19.089890) 1 descriptors modified. (4101, 07:50:19.090006) Data in FE socket. (4101) End of connection intercepted. (4101, 07:50:19.090106) Received 2 bytes from FE socket. (4101, 07:50:19.090180) Connection: 0::0 has finished. Now FREE! What I was expecting to see was that the connections were serialised, so that the time to respond should have increased to include the time to wait for previous connections to finish. As you can see from the above example the _total_ wait for 10 attempts was 0.00184 of a second: (5126, 07:50:19.047505) Connection 0::0 is NOT free!!!. (5126, 07:50:19.049346) Connection 0::0 is NOT free!!!. Had we been able to wait for only 0.05 of a second we would have seen: (4101, 07:50:19.090180) Connection: 0::0 has finished. Now FREE! So it looks like a bug... Ideally I would see the number of attempts and the first retry delay as configurable. I would then multiply the retry wait by 1.5 for each subsequent retry. > What DBBalancer should also make better is the strategy to adaptively modify > the number of threads and conns. Now it checks the average length of the > latest 3 checks of the queue, but, while this avoids overreacting to fast > bursts of requests, it's is quite slow on adapting. Sounds like you are saying that it would not be a good idea to set: daemon.reaper-delay=60 I had assumed that this only applied to _reaping_, not starting up... I think a straightforward approach would be to start connections immediately if you find none available but are below daemon.max-db-connections - this would make things responsive to a quickly ramping load. I consider reaping those when they haven't been used as a _much_ lower priority, hence my setting of the reaper delay to a higher level. > > Hand in hand with this, it would be good to get > > statistics of connections handled / connections queued > > / connections dropped dumped to syslog every > > [configurable] seconds. These statistics would enable > > the system admin to tune the numbers of client and > > server connections. > > Some of these are already available. In fact, in DEBUG mode, DBThreadPool > dumps the length and average (3 last checks) length of its queue. Anyway they > should be augmented with more data, that's true. It's not debugging information, it's management information, so I want to be able to accumulate it on a busy website over several days before (perhaps) turning it off. Naturally I _don't_ want to be logging every query during that time :-) 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 |