Henri Asseily wrote:
Take the example of the pod:
$DATABASE::conf{'test'} = {
max_retries => 2,
db_stack => [
[ 'dbi:Sybase:server=prod1;database=test', 'user1', 'pass1', $attrib ],
[ 'dbi:Sybase:server=prod2;database=test', 'user2', 'pass2', $attrib ],
[ 'dbi:Sybase:server=prod3;database=test', 'user3', 'pass3', $attrib ],
], ...
Assume his 'test' handle is a read-only handle.
The stack definition shows that you have 3 read-only servers: prod1,
prod2 and prod3.
The particular process that uses this stack will start with prod1, and
if it fails max_retries times, it will switch to the next one in the
stack, prod2, and so on.
If you want to have your application to be load-balanced across all the
read-only databases, you can do it in many ways, but ultimately it boils
down to having your children processes hitting different databases, and
having stacks that are as unique as possible (so that if a db server
fails, all its dependents don't fail over to the same secondary).
Here's a complex example:
In the case above, say you have 20 children for those 3 databases.
The different stack permutations are:
1: prod1,prod2,prod3
2: prod1,prod3,prod2
3: prod2,prod1,prod3
4: prod2,prod3,prod1
5: prod3,prod1,prod2
6: prod3,prod2,prod1
Either dynamically or statically create these 6 permutations and put
them in @all_db_stacks:
Then when one of your 20 children starts up, it will take a stack.
Either have each take the next stack down, or randomly take a stack. One
example under Apache if you don't want to have a shared global is to
grab the child's process id and get its modulus by the size of
@all_db_stack:
$stack_number = $$ % scalar(@all_db_stacks)
And so in the example config above:
db_stack => $all_db_stacks[$stack_number]
Couldn't an option be added as an alternative to db_stack that indicates
a desire for random ordering, thereby eliminating the need to precreate
all possible permutations? I'm imaging something like this (modified
version of your example):
$DATABASE::conf{'test'} = {
max_retries => 2,
db_pool => [
[ 'dbi:Sybase:server=prod1;database=test', 'user1', 'pass1', $attrib ],
[ 'dbi:Sybase:server=prod2;database=test', 'user2', 'pass2', $attrib ],
[ 'dbi:Sybase:server=prod3;database=test', 'user3', 'pass3', $attrib ],
], ...
So, db_stack maintains ordering, while db_pool tells DBIx::HA to
randomize the list of servers.
-ofer