Software Optimisation Never END – Asymmetric Load Balancing Algoritm, Review

4 years ago, I published a PHP solution on the blog for choosing the right server from a servers list, based on the available bandwidth configured: Asymmetric Load Balancing Server Solution.

The algorithm can be used in Load Balancing proxy servers, for CDNs as well as for any other needs where a balanced distribution of resources is required;

Recently I am working on a cache plugin written in PHP, developed for any kind of web pages (non CMS) as well as for Wordpress: page, object and database.

You must be wondering why I don’t choose a plugin that is already free?

Because most of them are too complex, and they have long lost their perspective on simplicity, utility and performance!

And when I came to the implementation of a solution for CDN, I remembered the php function published over 2 years ago … but after so long it seems that my brain has advanced more in the optimization segment, the old solution seemed to me “heavy”.. So after less than 5 minutes I realized that the method of choosing a server was still very good, but there was still room for optimization!

So, below is a new version for Asymmetric Load Balancing Server, much faster and even simpler!  (2024 Update as Class)


  1. class ByREV_Asym_LB_Server{
  2. public $Server_List = [];
  3. private $Server_LBS = [];
  4. private $Sum_Bandwidth = 0;
  5. private function prepareLBS()
  6. {
  7. // Sort server list in ascending order, based on the bandwidth.
  8. // Mandatory requirement for Load Balanced algorithm to work!
  9. asort($this->Server_List);
  10. $this->Server_LBS = [];
  11. $segment_bandwidth = 0;
  12. foreach ($this->Server_List as $server=>$bandwidth) {
  13. $segment_bandwidth+= $bandwidth;
  14. $this->Server_LBS[$server] = $segment_bandwidth;
  15. }
  16. $this->Sum_Bandwidth = end( $this->Server_LBS );
  17. }
  18. // Preferentially and pseudorandomly choose a server from the list based on a criterion like:
  19. // bandwidth, average latency, computing power, response time, number of requests per minute.
  20. public function getServer()
  21. {
  22. // Choose a server from the list
  23. $rand_bandwidth = mt_rand(1, $this->Sum_Bandwidth);
  24. // Scan list until find one
  25. foreach ($this->Server_LBS as $server=>$bandwidth) {
  26. if ($rand_bandwidth <= $bandwidth)
  27. break;
  28. }
  29. // Returns the data for the chosen server
  30. return $server;
  31. }
  32. public function __construct(Array $Servers=[])
  33. {
  34. $this->Server_List = $Servers;
  35. // prepare server list for Load Balanced algorithm and save for later use.
  36. $this->prepareLBS();
  37. }
  38. }
  39. /* ~~~~~~~~~~~~~~~~~~ Use Case ~~~~~~~~~~~~~~~~~~~~~ */
  40. $srv_cdn = [
  41. 'cdn1.cdnserverxyz.com' => 15,
  42. 'cdn2.cdnserverxyz.com' => 30,
  43. 'cdn3.cdnserverxyz.com' => 120,
  44. 'cdn4.cdnserverxyz.com' => 75,
  45. 'cdn5.cdnserverxyz.com' => 10,
  46. ];
  47. $LBS = new ByREV_Asym_LB_Server($srv_cdn);
  48. echo $LBS;
class ByREV_Asym_LB_Server{
  
  public $Server_List = [];
  private $Server_LBS = [];
  private $Sum_Bandwidth = 0;

  private function prepareLBS() 
  {
        // Sort server list in ascending order, based on the bandwidth. 
        // Mandatory requirement for Load Balanced algorithm to work!
        asort($this->Server_List);                      

        $this->Server_LBS = [];
        $segment_bandwidth = 0;
        foreach ($this->Server_List as $server=>$bandwidth) {
            $segment_bandwidth+= $bandwidth;
            $this->Server_LBS[$server] = $segment_bandwidth;
        }
        
        $this->Sum_Bandwidth = end( $this->Server_LBS );    
  }

  // Preferentially and pseudorandomly choose a server from the list based on a criterion like:
  // bandwidth, average latency, computing power, response time, number of requests per minute.
  public function getServer() 
  {
      // Choose a server from the list
      $rand_bandwidth = mt_rand(1,  $this->Sum_Bandwidth);
      
      // Scan list until find one
      foreach ($this->Server_LBS as $server=>$bandwidth) {
          if ($rand_bandwidth <= $bandwidth)
              break;
      }

      // Returns the data for the chosen server
      return $server;
  }

  public function __construct(Array $Servers=[]) 
  {
      $this->Server_List = $Servers;

      // prepare server list for Load Balanced algorithm and save for later use.      
      $this->prepareLBS();
  }
}

/* ~~~~~~~~~~~~~~~~~~ Use Case ~~~~~~~~~~~~~~~~~~~~~ */

$srv_cdn = [
  'cdn1.cdnserverxyz.com' => 15,  
  'cdn2.cdnserverxyz.com' => 30,
  'cdn3.cdnserverxyz.com' => 120,
  'cdn4.cdnserverxyz.com' => 75,
  'cdn5.cdnserverxyz.com' => 10,
];

$LBS = new ByREV_Asym_LB_Server($srv_cdn);

echo $LBS;

 

Execution speed tests performed in PHP 7.4.2 showed that the above version is 40% faster than the one published 2 years ago.

  1. ------ Speed Test ------
  2. CPU: (Ryzen 4800H), ~ 10% load
  3. test: 10000000 req
  4. time: 1.2596859931946 s
  5. req/s: 7.94 milions
  6. ------------------------
------ Speed Test ------
CPU: (Ryzen 4800H), ~ 10% load
test: 10000000 req
time: 1.2596859931946 s
req/s: 7.94 milions
------------------------

 

Conclusion: Software Optimization Never END!

byrev Written by:

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *