Asymmetric Load Balancing Server Solution

There are N servers, each server has a fixed bandwidth available. The idea is that you want mirrored file hosting (CDN) so that a function/script returns a redirect to various servers where the file is duplicated. 

Asymmetric Load Balancing ServersThe redirection rule (server choice) must be controlled by the bandwidth available for a particular server.

The mathematical problem itself is a little more laborious, but the idea is to randomly choose the servers so that after a relatively short period of operation, the traffic consumed on servers is as balanced as possible.

The solution below is the simplest possible, and can be used successfully in almost any situation.

<?php 

$cdn_servers = [];

$cdn_servers[] = array(
  'bandwidth' => 7, 
  'domain' => 'cdn1.cdnserverxyz.com'
);

$cdn_servers[] = array(
  'bandwidth' => 20, 
  'domain' => 'cdn2.cdnserverxyz.com'
);

$cdn_servers[] = array(
  'bandwidth' => 90, 
  'domain' => 'cdn3.cdnserverxyz.com'
);

function getAsym_LB_Server(&$cdn_servers) {
  $total_bandwidth = 0;
  $server_index = [];
  foreach ($cdn_servers as $key=>$server) :	
    $total_bandwidth += $server['bandwidth'];	
    $server_index[$key] = $total_bandwidth;
  endforeach;

  $server_rand = mt_rand(1,$total_bandwidth);

  foreach ($server_index as $key=>$val) :
    if ($val >= $server_rand) {		
      $server_selected = $key;
      break;
    }
  endforeach;	

  return $cdn_servers[$server_selected];
}

$server = getAsym_LB_Server($cdn_servers);

print_r($server);

?>

* The condition is that the files served must be of various sizes and in a sufficiently large number!

UPDATE:
To increase the speed, below I rewrote the getAsym_LB_Server function in a more optimized version in terms of execution speed:

function getAsym_LB_Server(&$cdn_servers) {
  if (empty($GLOBALS['AsymLBServer'])) {
    $total_bandwidth = 0;
    $server_index = [];
    foreach ($cdn_servers as $key=>$server) :	
       $total_bandwidth += $server['bandwidth'];	
       $server_index[$key] = $total_bandwidth;
    endforeach;	
    $GLOBALS['AsymLBServer'] = array($server_index, $total_bandwidth);
  } else {
    $server_index = &$GLOBALS['AsymLBServer'][0];
    $total_bandwidth = $GLOBALS['AsymLBServer'][1];
  }

  $server_rand = mt_rand(1,$total_bandwidth);

  foreach ($server_index as $key=>$val) :
    if ($val >= $server_rand) {		
      $server_selected = $key;
      break;
    }
  endforeach;	

  return $cdn_servers[$server_selected];
}

P.S. The solution can be used for any other type of application: proxy, alternative routes, cache, etc and the advantage is that the solution does not require that the choice of servers be counted / stored somewhere,  it is a plug an play solution!

byrev Written by:

Be First to Comment

Leave a Reply

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