- interface hash{function _hash($key);// 计算键名对应的 32 位数值
- }
- interface distribution{
- function lookup($node);// 查看落点
- }
- class Consistent implements hash,distribution{
- protected $_nodes = array();
- public function _hash($key)
- {
- return sprintf("%u",crc32($key));
- }
- public function lookup($key)
- {
- $point = $this->_hash($key);
- $node = current($this->_nodes);// 将最小的 key 所对应的值付给 node
- foreach($this->_nodes as $k => $v){
- if($k>=$point){
- $node = $v;
- break;
- }
- }
- return $node;
- }
- public function addNodes($node)
- {
- // 记录服务器节点
- $this->_nodes[$this->_hash($node)] = $node;
- $this->sortNodes();
- }
- public function sortNodes()
- {
- ksort($this->_nodes,SORT_REGULAR);
- }
- public function getNodes()
- {
- return $this->_nodes;
- }
- }
- $con = new Consistent();
- $con->addNodes('a');
- $con->addNodes('b');
- $con->addNodes('c');
- echo '现有服务器节点有:';
- print_r($con->getNodes());
- echo 'name 的落点为'. $con->_hash('titleasdas') . "<br />";
- echo '应该写在'.$con->lookup('titleasdas')."服务器上";
以上代码简单的实现了分布数据到不同的服务器上. 不过缺点很明显. 用这个实现的分布式当其中服务器 down 后, 排在这台服务器后面的那台服务器需要承担这台服务器的全部工作量. 于是, 下面加强了一下.
- interface hash{
- function _hash($key);// 计算键名对应的 32 位数值
- }
- interface distribution{
- function lookup($node);// 查看落点
- }
- class Consistent implements hash,distribution{
- protected $_positions = array();
- protected $_nodes = array();
- protected $_mul = 64;
- public function _hash($key)
- {
- return sprintf("%u",crc32($key));
- }
- public function lookup($key)
- {
- $point = $this->_hash($key);
- $node = current($this->_positions);// 将最小的 key 所对应的值付给 node
- foreach($this->_positions as $k => $v){
- if($k>=$point){
- $node = $v;
- break;
- }
- }
- return $node;
- }
- public function addPos($node)
- {
- // 记录服务器节点
- for($i=0;$i<$this->_mul;$i++){
- $pos = $this->_hash($node.'-'.$i);
- $this->_positions[$pos] = $node;
- }
- $this->sortPos();
- }
- public function sortPos()
- {
- ksort($this->_positions,SORT_REGULAR);
- }
- public function getPos()
- {
- return $this->_positions;
- }
- }
- $con = new Consistent();
- $con->addPos('a');
- $con->addPos('b');
- $con->addPos('c');
- echo '现有服务器节点有:';
- print_r($con->getPos());
- echo 'name 的落点为'. $con->_hash('titleasdas') . "<br />";
- echo '应该写在'.$con->lookup('titleasdas')."服务器上";
将每台服务器生成 64 个不同的节点. 然后进行排序. 这样多台服务器就均衡无序的分布在不同的节点位置. 当其中某台服务器 down 后也不会出现其中一台服务器全部承担那台服务器的压力的情况发生.
对于分布式算法理解尚有不足, 以上观点若有错误之处还望前辈们不吝指教, 十分感谢.
来源: http://www.bubuko.com/infodetail-2580310.html