Le hachage cohérent est un algorithme d'allocation de données utilisé dans les systèmes distribués, et est souvent utilisé dans l'équilibrage, la mise en cache et les autres scénarios de charge. Il minimise l'impact des nœuds du serveur lors de l'expansion dynamique et du rétrécissement en mappant les nœuds sur un anneau de hachage virtuel.
L'idée principale de l'algorithme de hachage cohérent est de cartographier tous les nœuds participants dans un espace annulaire via une fonction de hachage, et les éléments de données sont également cartographiés sur cet espace en utilisant la même fonction de hachage. Les données seront allouées au premier nœud dans le sens des aiguilles d'une montre.
Dans un hachage cohérent, la fonction de hachage est utilisée pour mapper les nœuds en données dans les valeurs de hachage, généralement des entiers 32 bits ou 64 bits. Fonctions communes telles que CRC32, MD5, SHA1, etc.
Chaque nœud de serveur physique peut correspondre à plusieurs nœuds virtuels pour obtenir une allocation de charge plus équilibrée. Les nœuds virtuels peuvent atténuer le problème de la distribution inégale des nœuds réels et améliorer l'uniformité globale de la distribution.
Lorsque les données doivent être stockées, la valeur de hachage est calculée en fonction de sa valeur clé, puis le premier nœud dans l'anneau qui est supérieur ou égal à cette valeur de hachage est trouvé. Si vous n'êtes pas trouvé, montez au premier nœud. Cette méthode peut éviter la migration de données à grande échelle causée par des changements dans le nombre de nœuds.
Voici un exemple d'une implémentation de hachage cohérente écrite en PHP, montrant comment ajouter, supprimer les nœuds et obtenir des nœuds correspondants:
class ConsistentHash
{
private $nodes = array();
private $position = array();
public function addNode($node)
{
$this->nodes[$node] = true;
$this->updatePosition();
}
public function removeNode($node)
{
unset($this->nodes[$node]);
$this->updatePosition();
}
public function getNode($key)
{
if (empty($this->nodes)) {
return null;
}
$pos = $this->hash($key);
foreach ($this->position as $node => $position) {
if ($pos <= $position) {
return $node;
}
}
return reset($this->position);
}
private function updatePosition()
{
$positions = array();
foreach ($this->nodes as $node => $value) {
for ($i = 0; $i < 3; $i++) {
$positions[$node . '_' . $i] = $this->hash($node . '_' . $i);
}
}
asort($positions);
$this->position = $positions;
}
private function hash($str)
{
return crc32($str);
}
}
// Exemple d'utilisation
$hash = new ConsistentHash();
$hash->addNode('Server1');
$hash->addNode('Server2');
$hash->addNode('Server3');
$server = $hash->getNode('data123');
echo $server; // La sortie peut être Server1
Le code ci-dessus construit une classe de hachage cohérente simple, fournissant les fonctions d'ajouter des nœuds, de supprimer les nœuds et d'obtenir des nœuds alloués en fonction des clés. En introduisant un mécanisme de nœud virtuel, l'allocation équilibrée de la charge est effectivement obtenue.
Le hachage cohérent est une solution d'équilibrage de charge distribuée efficace et stable, particulièrement adaptée aux scénarios du système où les nœuds changent fréquemment. Cet article aide les développeurs à maîtriser l'utilisation de base d'un hachage cohérent à travers des explications théoriques et des exemples de mise en œuvre de PHP. Lors de la conception de grands systèmes distribués, la compréhension et l'application d'algorithmes de hachage cohérents peuvent améliorer considérablement l'évolutivité et la stabilité du système.