Memcached分布式部署方案設計(含PHP代碼)

來源:互聯網
上載者:User


一台Memcache通常不能滿足我們的需求,這就需要分布式部署。Memcached分布式部署方案通常會採用兩種方式,一種是普通Hash分布,一種是一致性Hash分布。本篇將以PHP作為用戶端,來分析兩種方案。
    一、普通Hash分布:
<?php
function test($key='name'){
    $md5 = substr(md5($key), 0, 8);
    $seed = 31;
    $hash = 0;
    for($i=0; $i<8; $i++){
        $hash = $hash * $seed + ord($md5[$i]);
    }
    return $hash & 0x7FFFFFFF;
}

$memcacheList = array(
        array('host'=>'192.168.1.2', 'port'=>6379),
        array('host'=>'192.168.1.3', 'port'=>6379),
        array('host'=>'192.168.1.4', 'port'=>6379),
        array('host'=>'192.168.1.5', 'port'=>6379),
);
$key = 'username';
$value = 'lane';
//根據KEY擷取hash
$hash = $this->test($key);
$count = count($memcacheList);
$memcache = $memcacheList[$hash % $count];
$mc = new Memcached($memcache);
$mc->set($key, $value);
?>

代碼很簡單,一個Hash函數,根據所需要的key,將他md5後取前8位,然後經過Hash演算法返回一個整數。將這個整數對伺服器總數求模。得到的就是伺服器列表的編號。這種方式的缺點是伺服器數量改變後,同一個key不同hash,將取不到值了。

二、一致性Hash分布

一致性Hash儘管也會造成資料的丟失,但是損失是最小的。
將2的32次方-1想象成一個圓環,伺服器列表在上面排列。根據key通過hash演算法求得在圓環上的位置,那麼所需要的伺服器的位置在key的位置前面最近的一個(順時針)。

<?php
class FlexiHash{
    //伺服器列表
    private $serverList = array();
    //是否排序
    private $isSort = false;

    /**
     * Description: Hash函數,將傳入的key以整數形式返回
     * @param string $key
     * @return int
     */
    private function myHash($key){
        $md5 = substr(md5($key), 0, 8);
        $seed = 31;
        $hash = 0;
        for($i=0; $i<8; $i++){
            $hash = $hash * $seed + ord($md5[$i]);
        }
        return $hash & 0x7FFFFFFF;
    }

    /**
     * Description: 添加新伺服器
     * @param $server
     */
    public function addServer($server){
        $hash = $this->myHash($server);
        if(!isset($this->serverList[$hash])){
            $this->serverList[$hash] = $server;
        }
        $this->isSort = false;
        return true;
    }

    /**
     * Description: 刪除指定伺服器
     * @param $server
     * @return bool
     */
    public function removeServer($server){
        $hash = $this->myHash($server);
        if(isset($this->serverList[$hash])){
            unset($this->serverList[$hash]);
        }
        $this->isSort = false;
        return true;
    }

    /**
     * Description: 根據要操作的KEY返回一個操作的伺服器資訊
     * @param $key
     * @return mixed
     */
    public function lookup($key){
        //將指定的KEYhash出一個整數
        $hash = $this->myHash($key);
        if($this->isSort !== true){
            krsort($this->serverList);
            $this->isSort = false;
        }
        foreach($this->serverList as $key=>$server){
            if($key <= $hash){
                return $server;
            }
        }
        return array_pop($this->serverList);
    }
}
//使用方法
$mc = new FlexiHash();
$mc->addServer('192.168.1.2');
$mc->addServer('192.168.1.3');
$mc->addServer('192.168.1.4');
$mc->addServer('192.168.1.5');

echo 'KEY=key1時,操作的伺服器為:'.$mc->lookup('key1').'<br>';
echo 'KEY=key1時,操作的伺服器為:'.$mc->lookup('key2').'<br>';
echo 'KEY=key1時,操作的伺服器為:'.$mc->lookup('key3').'<br>';
echo 'KEY=key1時,操作的伺服器為:'.$mc->lookup('key4').'<br>';
echo 'KEY=key1時,操作的伺服器為:'.$mc->lookup('key5').'<br>';
?>

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.