PHP 一致性hash实现
<?php function mHash($key) { $md5 = substr(md5($key), 0, 8); $seed = 31; $hash = 0; for($i = 0; $i < 8; $i++){ $hash = $hash * $seed + ord($md5{$i}); $i++; } return $hash & 0x7FFFFFFF; } class FlexiHash { private $serverList = array(); private $serverKeys = array(); private $isSorted = false; function addServer($server) { $hash = mHash($server); if (!isset($this->serverList[$hash])) { $this->serverList[$hash] = $server; } $this->isSorted = false; return true; } function removeServer($server) { $hash = mHash($server); if (isset($this->serverList[$hash])) { unset($this->serverList[$hash]); } $this->isSorted = false; return true; } function lookup($key) { $hash = mHash($key); if (!$this->isSorted) { krsort($this->serverList, SORT_NUMERIC); $this->isSorted = true; $this->serverKeys = array_keys($this->serverList); } foreach ($this->serverList as $pos => $server) { if ($hash >= $pos) return $server; } return $this->serverList[$this->serverKeys[count($this->serverList) - 1]]; } } $hserver = new FlexiHash(); $hserver->addServer('192.168.1.1'); $hserver->addServer('192.168.1.2'); $hserver->addServer('192.168.1.3'); $hserver->addServer('192.168.1.4'); $hserver->addServer('192.168.1.5'); $hserver->addServer('192.168.1.6'); echo "<pre>"; for($i=0; $i < 10000; $i++) { $t = $hserver->lookup('key'.$i); $arr[] = $t; } print_r($arr);