How To Split Randomly But Unevenly – PHP Code For Load UNBalancing

Splitting Across DIFFERENT Data Servers

So far, we’ve talked about identical servers with identical contents – pick one, pack any, they’re all the same – so random works well there.

But what if we want specific servers? For example, say Server 0 has all the data for customers ‘A’-‘G’, Server 1 has them from ‘H’-”R’, and so on?

That’s where we combine the solutions above:

$server=array(0,1,1,1,1,1,2,2);
$range=count($server)-1;
$seed='M'; // customer's first letter
$i=hexdec(sub_str(md5($seed),0,8))%$range;

Using md5(), we can use a seed based on a specific feature (in this case, the customer’s initial letter). It will go consistently to the same server, but the md5() hash will do a fine job of spreading the hits more evenly.

And what if we need to add/delete servers?

If you don’t change the LENGTH of the $server array, then swapping servers in/out is just a matter of changing the server numbers in $server, so going from

$server=array(0,1,1,1,1,1,2,2);

to

$server=array(1,1,1,1,1,1,2,2);

pulls out server 0. But if you change the number of entries, then the modulo $range will come up with a different value, and ALL servers will have to redo their data (instead of the single one).

This is important to remember. In our example, Server 1 just had to do a bit more work to cover for Server 0 – Server 2 was unaffected. If you changed the array size, both could be affected (and it would get worse as you add servers).

So if you need a static sized array for this reason, I’d recommend a much longer array to give you more to work with; as well, you’ll probably want a few handler functions to make it easier to add and remove items, and make changes by affecting as few table entries as possible.

Redux, In C

Of course, this isn’t just for servers – I originally wrote this code for unbalanced random numbers. In games, sometimes I wanted one number skewed more than another. In C, the code looks like this:

int i=0;
int x=0;
int server[]={10,50,20};
int count =0;
for (i=0;i<sizeof(server)/sizeof(server[0]);++i)
  count+=server[i];
x=rand()%count;
i=-1;
while (x-=server[++$i])>=0 ) 
  {;}

And in C++ of course it would be a fancy class, with the array count stored rather than created for each call.

I’ve used this and variations of it for some time, and it’s allowed me to pick one or more items unevenly. Be they servers or the size of the monster in a game, it can also help you pick unevenly but ‘randomly’.

Comments are closed.