Bonjour,
Voici un petit snippet qui permet de facilement et rapidement faire du consistent hashing.
Pour ceux qui découvrent le sujet, vous pouvez faire un tour sur cet article :
http://en.wikipedia.org/wiki/Consistent_hashing
La classe de hashing
<?php
class ConsitentHashing {
private $nodes = array();
private $max;
private $size;
public function __construct( array $nodes, $size = 1024 ) {
$this->nodes = $nodes;
$this->max = count($nodes);
$this->size = $size;
}
public function locate($key, $nodes = 1) {
$point = sprintf('%u', crc32($key)) % $this->size;
if ( $point == 0 ) $point ++;
$node = floor($point / $this->size * $this->max);
return array_slice($this->nodes, $node, $nodes);
}
}
Un petit exemple d'utilisation
C'est à la fois un exemple et un test :
<?php
$h = new ConsitentHashing(array(
array(
'node1'
),
array(
'node2'
),
array(
'node3'
),
array(
'node4'
)
));
for($i = 0; $i < 10; $i++) {
$number = rand(0, 1024);
$node = $h->locate($number);
echo $number . ' - ' . $node[0][0] . "\n";
}
Comment l'utiliser concrétement
Dans le constructeur vous passez les noeuds qui seront distribués sur le ring.
Le contenu de ces noeuds est à votre charge en fonction de la configuration à stocker.
Par exemple vous pouvez y mettre des conf de connexion server :
array(
array(
'host' => '127.0.0.1',
'port' => 1001
),
array(
'host' => '127.0.0.1',
'port' => 1002
),
// etc ...
)
Le $size dans le constructeur est la capacité maximale de votre ring, cette donnée ne pourra que très difficilement changer, donc prévoir grand ...
Pour trouver où on doit chercher une cléf, utilisez locate.
Il vous retournera un tableau avec les noeuds concernés (par défaut 1 seul).
Si vous faites du consistent hashing vaut mieux dupliquer l'emplacement de vos données,
cela va simplifier l'ajout ou la suppression d'un serveur et vous permettra d'avoir un système de failover.
Bonne prog