当前位置:首页 > PHP教程 > php高级应用 > 列表

Memcached分布式部署方案设计(含PHP代码)

发布:smiling 来源: PHP粉丝网  添加日期:2015-04-15 11:03:10 浏览: 评论:0 

一台Memcache通常不能满足我们的需求,这就需要分布式部署。Memcached分布式部署方案通常会采用两种方式,一种是普通Hash分布,一种是一致性Hash分布,本篇将以PHP作为客户端,来分析两种方案.

一、普通Hash分布:

  1. <?php 
  2. function test($key='name'){ 
  3.     $md5 = substr(md5($key), 0, 8); 
  4.     $seed = 31; 
  5.     $hash = 0; 
  6.     for($i=0; $i<8; $i++){ 
  7.         $hash = $hash * $seed + ord($md5[$i]); 
  8.     } 
  9.     return $hash & 0x7FFFFFFF; 
  10. $memcacheList = array
  11.         array('host'=>'192.168.1.2''port'=>6379), 
  12.         array('host'=>'192.168.1.3''port'=>6379), 
  13.         array('host'=>'192.168.1.4''port'=>6379), 
  14.         array('host'=>'192.168.1.5''port'=>6379), 
  15. ); 
  16. $key = 'username'
  17. $value = 'lane'
  18. //根据KEY获取hash 
  19. $hash = $this->test($key); 
  20. $count = count($memcacheList); 
  21. $memcache = $memcacheList[$hash % $count]; 
  22. $mc = new Memcached($memcache); 
  23. $mc->set($key$value); 
  24. ?> 

代码很简单,一个Hash函数,根据所需要的key,将他md5后取前8位,然后经过Hash算法返回一个整数,将这个整数对服务器总数求模,得到的就是服务器列表的编号,这种方式的缺点是服务器数量改变后,同一个key不同hash,将取不到值了.

二、一致性Hash分布

一致性Hash尽管也会造成数据的丢失,但是损失是最小的,将2的32次方-1想象成一个圆环,服务器列表在上面排列,根据key通过hash算法求得在圆环上的位置,那么所需要的服务器的位置在key的位置前面最近的一个(顺时针).

  1. <?php 
  2. class FlexiHash{ 
  3.     //服务器列表 
  4.     private $serverList = array(); 
  5.     //是否排序 
  6.     private $isSort = false; 
  7.     /** 
  8.      * Description: Hash函数,将传入的key以整数形式返回 
  9.      * @param string $key 
  10.      * @return int 
  11.      */ 
  12.     private function myHash($key){ 
  13.         $md5 = substr(md5($key), 0, 8); 
  14.         $seed = 31; 
  15.         $hash = 0; 
  16.         for($i=0; $i<8; $i++){ 
  17.             $hash = $hash * $seed + ord($md5[$i]); 
  18.         } 
  19.         return $hash & 0x7FFFFFFF; 
  20.     } 
  21.     /** 
  22.      * Description: 添加新服务器 
  23.      * @param $server 
  24.      */ 
  25.     public function addServer($server){ 
  26.         $hash = $this->myHash($server); 
  27.         if(!isset($this->serverList[$hash])){ 
  28.             $this->serverList[$hash] = $server
  29.         } 
  30.         $this->isSort = false; 
  31.         return true; 
  32.     } 
  33.     /** 
  34.      * Description: 删除指定服务器 
  35.      * @param $server 
  36.      * @return bool 
  37.      */ 
  38.     public function removeServer($server){ 
  39.         $hash = $this->myHash($server); 
  40.         if(isset($this->serverList[$hash])){ 
  41.             unset($this->serverList[$hash]); 
  42.         } 
  43.         $this->isSort = false; 
  44.         return true; 
  45.     } 
  46.     /** 
  47.      * Description: 根据要操作的KEY返回一个操作的服务器信息 
  48.      * @param $key 
  49.      * @return mixed 
  50.      */ 
  51.     public function lookup($key){ 
  52.         //将指定的KEYhash出一个整数 
  53.         $hash = $this->myHash($key); 
  54.         if($this->isSort !== true){ 
  55.             krsort($this->serverList); 
  56.             $this->isSort = false; 
  57.         } 
  58.         foreach($this->serverList as $key=>$server){ 
  59.             if($key <= $hash){ 
  60.                 return $server
  61.             } 
  62.         } 
  63.         return array_pop($this->serverList); 
  64.     }  //开源软件:phpfensi.com 
  65. //使用方法 
  66. $mc = new FlexiHash(); 
  67. $mc->addServer('192.168.1.2'); 
  68. $mc->addServer('192.168.1.3'); 
  69. $mc->addServer('192.168.1.4'); 
  70. $mc->addServer('192.168.1.5'); 
  71. echo 'KEY=key1时,操作的服务器为:'.$mc->lookup('key1').'<br>'
  72. echo 'KEY=key1时,操作的服务器为:'.$mc->lookup('key2').'<br>'
  73. echo 'KEY=key1时,操作的服务器为:'.$mc->lookup('key3').'<br>'
  74. echo 'KEY=key1时,操作的服务器为:'.$mc->lookup('key4').'<br>'
  75. echo 'KEY=key1时,操作的服务器为:'.$mc->lookup('key5').'<br>'
  76. ?>

Tags: Memcached分布式 PHP代码

分享到: