|
NAMEResourcePool::LoadBalancer - A load balancer across ResourcePool'sSYNOPSISuse ResourcePool::LoadBalancer; my $loadbalancer = ResourcePool::LoadBalancer->new("key", MaxTry => 10); $loadbalancer->add_pool($some_ResourcePool); $loadbalancer->add_pool($some_other_ResourcePool); $loadbalancer->add_pool($third_ResourcePool); my $resource = $loadbalancer->get(); # get a resource from one pool # according to the policy #[...] # do something with $resource $loadbalancer->free($resource); # give it back to the pool $loadbalancer->fail($resource); # give back a failed resource DESCRIPTIONThe ResourcePool::LoadBalancer is a generic way to spread requests to different ResourcePool's to increase performance and/or availability.Besides the construction the interface of ResourcePool::LoadBalancer is the same as the interface of ResourcePool. This makes it very simple to change a program which uses ResourcePool to use the ResourcePool::LoadBalancer by just changing the construction (which is hopefully kept at a central point in your program). ResourcePool::LoadBalancer->new($key, @Options)Creates a new ResourcePool::LoadBalancer. This method takes one key to identify the load balancer (used by ResourcePool::Singleton). It is recommended to use some meaningful string as key, since this is used when errors are reported. This key is internally used to distinguish between different pool types, e.g. if you have two ResourcePool::LoadBalancer one for DBI connections to different servers and use parallel another ResourcePool::LoadBalancer for Net::LDAP connections.
Regardless of the used Policy, the load balancer will always try to find a valid resource for you. All resources do fail over if required. Default: LeastUsage
$lb->add_pool($resourcepool, @options)Adds a ResourcePool object to the load balancer. You must call this method multiple times to add more pools. You can add as many ResourcePool's as you want.There are two options which affect the way the load balancer selects the ResourcePool's.
$lb->getReturns a resource. This resource has to be given back via the free() or fail() method. The get() method calls the get() method of the ResourcePool and might therefore return undef if no valid resource could be found in ALL ResourcePool's. In that case the load balancer will suspend the ResourcePool which returned the invalid resource and try the other (non suspended) ResourcePool's (see >). If it is not possible to find a valid resource in ANY configured ResourcePool, the load balancer will sleep (see >) and repeat this procedure up to > times. If, after all, the load balancer was not able to obtain a valid resource the get() method will return undef.According to the > and > settings the get() call might block the programs execution if it is not able to find a valid resource right now. Provided that you use the default settings for > and > a call to get() will block at least for 15 seconds before returning undef. Please see the TIMEOUTS section in the ResourcePool documentation for some other effects which might affect the time which get() blocks before it returns undef. Returns: undef $lb->free($resource)Marks a resource as free. Basically the same as the free() method of the ResourcePool.Returns: Return value is true on success or false if the resource doesn't belong to this load balancer. $lb->fail($resource)Marks the resource as bad. Basically the same as the fail() method of the ResourcePool.Returns: Return value is true on success or false if the resource doesn't belong to this load balancer. EXAMPLESA basic example...use ResourcePool; use ResourcePool::Factory::Net::LDAP; use ResourcePool::LoadBalancer; ### LoadBalancer setup # create a pool to a ldap server my $factory1 = ResourcePool::Factory::Net::LDAP->new("ldap.you.com"); my $pool1 = ResourcePool->new($factory1); # create a pool to another ldap server my $factory2 = ResourcePool::Factory::Net::LDAP->new("ldap2.you.com"); my $pool2 = ResourcePool->new($factory2); # create a empty loadbalancer with a FailBack policy my $loadbalancer = ResourcePool::LoadBalancer->new("LDAP", Policy => "FailBack"); # add the first pool to the LoadBalancer # since this LoadBalancer was configured to use the FailBack # policy, this is the primary used pool $loadbalancer->add_pool($pool1); # add the second pool to the LoadBalancer. # This pool is only used when first pool fails $loadbalancer->add_pool($pool2); ### LoadBalancer usage (no difference to ResourcePool) for (my $i = 0; $i < 1000000 ; $i++) { my $resource = $loadbalancer->get(); # get a resource from one pool # according to the policy if (defined $resource) { eval { #[...] # do something with $resource $loadbalancer->free($resource); # give it back to the pool }; if ($@) { # an exception happened $loadbalancer->fail($resource); # give back a failed resource } } else { die "The LoadBalancer was not able to obtain a valid resource\n"; } } Please notice that the get()/ free() stuff in this example in INSIDE the loop. This is very important to make sure the load balancing and fail over works. As for the ResourcePool the smartness of the load balancer lies in the get() method, so if you do not call the get() method regular you can not expect the load balancer to handle load balancing or fail over. The example above does not do any load balancing since the policy was set to FailBack. If you would change this to RoundRobin or LeastUsage you would spread the load across both servers. You can directly copy and past the example above and try to run it. If you do not change the hostnames you will just see how it fails, but even this will tell you a lot about how it works. Give it a try. Now lets make a slightly more complex configuration. Imagine you have three ldap servers: one master where you do your write access, two replicas where you do the read access. Now we want ResourcePool::LoadBalancer to implement a load balancing across the two replicas but we want it to use the master also for read access if both replicas are not available. This setup is simple if you keep in mind what I have said about the ResourcePool::LoadBalancer interface: "Beside the construction the interface of ResourcePool::LoadBalancer is the same as the interface of ResourcePool. This means that it is possible to make a nested load balancer chain. use ResourcePool; use ResourcePool::Factory::Net::LDAP; use ResourcePool::LoadBalancer; ### LoadBalancer setup # create a pool to the master my $masterfactory = ResourcePool::Factory::Net::LDAP->new("master"); my $master = ResourcePool->new($masterfactory); # create pools to the replicas my $replica1factory = ResourcePool::Factory::Net::LDAP->new("replica1"); my $replica1 = ResourcePool->new($replica1factory); my $replica2factory = ResourcePool::Factory::Net::LDAP->new("replica2"); my $replica2 = ResourcePool->new($replica2factory); # create the loadbalancer to spread load across the two replicas # using the default Policy LeastUsage my $replicaLB = ResourcePool::LoadBalancer->new("LDAP-Replica"); $replicaLB->add_pool($replica1); $replicaLB->add_pool($replica2); # create a superior loadbalancer which handles the FailBack to the # master if both replicas fail. my $loadbalancer = ResourcePool::LoadBalancer->new("LDAP", Policy => "FailBack"); $loadbalancer->add_pool($replicaLB); # HERE IS THE MAGIC $loadbalancer->add_pool($master); ### LoadBalancer usage is the same as above, therefore skipped here You should keep in mind that this configuration causes a multiplication of the timeout's which are done because of the > settings. In the example above the sleeps sum up to 60 seconds. SEE ALSOResourcePool, ResourcePool::BigPicture, ResourcePool::UMLAUTHORCopyright (C) 2001-2009 by Markus Winand <mws@fatalmind.com> This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
Visit the GSP FreeBSD Man Page Interface. |