1. 程式人生 > >分散式memcache 一致性雜湊演算法(採用環狀資料結構)

分散式memcache 一致性雜湊演算法(採用環狀資料結構)

 

<?php
 #分散式memcache 一致性雜湊演算法(採用環狀資料結構)
 class ConsistentHashMemcache
 {
     private $virtualNode='';      #用於儲存虛擬節點個數
     private $realNode=array();    #用於儲存真實節點
     private $servers=array();     #用於儲存memcache伺服器資訊
     #private $totalNode=array();   #節點總數
     /**
         * @desc 建構函式
         *
         * @param $servers array    | memcache伺服器的資訊
         * @param $virtualNode int | 虛擬節點個數,預設64個
         */
     public function __construct($servers, $virtualNode=64)
     {
         $this->servers=$servers;
         $this->realNode=array_keys($servers);
         $this->virtualNode=$virtualNode;
     }

     /**
    * @return int 返回32位的數字
    */
     private function hash($str)
     {
         return sprintf('%u',crc32($str));   #將字串轉換為32位的數字 28
     }

     /**
     * @desc 處理節點
     *
     * @param $realNode     array | 真實節點
     * @param $virturalNode int   | 虛擬節點個數
     *
     * @return array 返回所有節點資訊
     */
     private function dealNode($realNode, $virtualNode)
     {
         $totalNode=array();
         foreach ($realNode as $v)
          {
               for($i=0; $i<$virtualNode; $i++)
               {
                   $hashNode=$this->hash($v.'-'.$i);
                   $totalNode[$hashNode]=$v;
               }
         }
         ksort($totalNode);     #按照索引進行排序,升序
         return $totalNode;
     }

     /**
     * @desc 獲取key的真實儲存節點
     *
     * @param $key string | key字串
     *
     * @return string 返回真實節點
     */
     private function getNode($key)
     {

          $totalNode=$this->dealNode($this->realNode, $this->virtualNode);
          #獲取所有虛擬節點
         /* #檢視虛擬節點總數
         echo "<pre>";
         print_r($totalNode);
         echo "</pre>";die;
         */
         $hashNode=$this->hash($key);            #key的雜湊節點
         foreach ($totalNode as $k => $v)        #迴圈總結點環查詢
          {
              if($k >= $hashNode)                 #查詢第一個大於key雜湊節點的值
              {
                  echo $v;
                    return $v;                      #返回真實節點 74
              }
          }
             return reset($totalNode); #假若總節點環的值都比key雜湊節點小,則返回第一個總雜湊環的value值
      }

     /**
     * @desc 返回memcached物件
     *
     * @param $key string | key值
     *
     * @return object
     */
     private function getMemcached($key)
     {
         $node=$this->getNode($key);             #獲取真實節點
         echo  $key.'真實節點:'.$node.'<br/>'; #測試使用,檢視key的真實節點
         $host=$this->servers[$node]['host'];    #伺服器池中某臺伺服器host
         $port=$this->servers[$node]['port'];    #伺服器池中某臺伺服器port
         $m= new memcache();                    #例項化
         $m->addserver($host, $port);            #新增memcache伺服器 94
         return $m;                              #返回memcached物件 95
      }

     /**
     * @desc 設定key-value值
     */
     public function setKey($key, $value)
     {
            $m=$this->getMemcached($key);
            return $m->set($key, $value);
     }

     /**
     * @desc 獲取key中的value
      */
     public function getKey($key)
     {
         $m=$this->getMemcached($key);
         return $m->get($key);
     }
 }

$arr=array(
    array('host'=>'192.168.1.23', 'port'=>'11213'),
    array('host'=>'127.0.0.1', 'port'=>'11211'),
    array('host'=>'192.168.1.195', 'port'=>'11212'),
);
$mod=new ConsistentHashMemcache($arr);
$mod->setKey('梅','11111');

參考文獻:

https://blog.csdn.net/zhq_bo/article/details/71199126