First, create an interface with 3 methods:
Addserver: Add a server to the server list
Removeserver: Removing a server from the server list
Lookup: Find the appropriate server to store data in the current server list
Interface distribute{ // Locate the appropriate server in the current server list store data public function Lookup ($key); // add a server to the server list Public function addserver ($server); // Remove a server from the server list Public function removeserver ($server);}
Then define an interface to convert the string to an integer:
Interface hash{ publicfunction _hash ($str);}
Creating a class Consistenthash inherits the above two interfaces, it has two member variables:
$serverList: List of saved servers
$isSorted: Records whether the server list is already sequenced
Implementation of the Addserver method:
Public functionAddserver ($server){ $hash=$this->_hash ($server); if(!isset($this->serverlist[$hash])) { //locate a location on the server list by this hash value $this->serverlist[$hash] =$server; } //The list of servers has changed so that it is identified as false $this->issorted =FALSE; return TRUE; }
Implementation of the Removeserver method:
Public functionRemoveserver ($server){ $hash=$this->_hash ($server); if(isset($this->serverlist[$hash])) { unset($this->serverlist[$hash]); } $this->issorted =FALSE; return TRUE; }
The implementation of the lookup method:
Public functionLookup$key){ //calculate the hash value of the server $hash=$this->_hash ($key); //determine if the list of servers is sorted if(!$this-issorted) { //reverse order (replace the server list with a counter-clockwise ring) Krsort($this->serverlist,sort_numeric); $this->issorted =TRUE; } //traverse the list of servers, locate the appropriate server and return foreach($this->serverlist as $pos=$server){ if($hash>=$pos)return $server; } return End($this-serverlist); }
Full code:
<?PHP//Convert a string to an integerInterfacehash{ Public function_hash ($str);}Interfacedistribute{//locate the appropriate server to hold the data in the current server list Public functionLookup$key); //add a server to the server list Public functionAddserver ($server); //remove a server from the server list Public functionRemoveserver ($server);}classConsistenthashImplementsHashdistribute{Private $serverList=Array();//List of saved servers Private $isSorted=FALSE;//record whether the server list is already sequenced Public function_hash ($str){ return sprintf('%u ',CRC32($str));//Converts a string to 32 as an unsigned integer } Public functionLookup$key){ //calculate the hash value of the server $hash=$this->_hash ($key); //determine if the list of servers is sorted if(!$this-issorted) { //reverse order (replace the server list with a counter-clockwise ring) Krsort($this->serverlist,sort_numeric); $this->issorted =TRUE; } //traverse the list of servers, locate the appropriate server and return foreach($this->serverlist as $pos=$server){ if($hash>=$pos)return $server; } return End($this-serverlist); } Public functionAddserver ($server){ $hash=$this->_hash ($server); if(!isset($this->serverlist[$hash])) { //locate a location on the server list by this hash value $this->serverlist[$hash] =$server; } //The list of servers has changed so that it is identified as false $this->issorted =FALSE; return TRUE; } Public functionRemoveserver ($server){ $hash=$this->_hash ($server); if(isset($this->serverlist[$hash])) { unset($this->serverlist[$hash]); } $this->issorted =FALSE; return TRUE; }}$hashserver=NewConsistenthash ();$hashserver->addserver (' 192.168.1.1 ');$hashserver->addserver (' 192.168.1.2 ');$hashserver->addserver (' 192.168.1.3 ');$hashserver->addserver (' 192.168.1.4 ');$hashserver->addserver (' 192.168.1.5 ');Echo' Save Key1 on server: ',$hashserver->lookup (' Key1 '), ' <br/> ';Echo' Save Key2 on server: ',$hashserver->lookup (' Key2 '), ' <br/> ';Echo' =======================<br/><br/> ';$hashserver->removeserver (' 192.168.1.2 ');Echo' Save Key1 on server: ',$hashserver->lookup (' Key1 '), ' <br/> ';Echo' Save Key2 on server: ',$hashserver->lookup (' Key2 '), ' <br/> ';Echo' =======================<br/><br/> ';$hashserver->addserver (' 192.168.1.6 ');Echo' Save Key1 on server: ',$hashserver->lookup (' Key1 '), ' <br/> ';Echo' Save Key2 on server: ',$hashserver->lookup (' Key2 '), ' <br/> ';Echo' =======================<br/><br/> ';
Output:
Save Key1 on server:192.168.1.2save Key2 on server: 192.168.1.5=======================save Key1 on server
:192.168.1.3Save Key2 on server: 192.168.1.5=======================save Key1 on server : 192.168.1.6Save Key2 on server: 192.168.1.5=======================
Conclusion: When the server is increased or decreased, the consistent Hash algorithm will only change the storage server with a small portion of the data, thus reducing the data loss situation.
Memcached Notes and summaries (6) a consistent hash distribution algorithm for PHP implementation Memcached