51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

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

一台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&lt;8; $i++){
        $hash = $hash * $seed + ord($md5[$i]);
    }
    return $hash &amp; 0x7FFFFFFF;
}

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

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

/**
 * Description: 根据要操作的KEY返回一个操作的服务器信息
 * @param $key
 * @return mixed
 */
public function lookup($key){
    //将指定的KEYhash出一个整数
    $hash = $this-&gt;myHash($key);
    if($this-&gt;isSort !== true){
        krsort($this-&gt;serverList);
        $this-&gt;isSort = true;
    }
    foreach($this-&gt;serverList as $key=&gt;$server){
        if($key &lt;= $hash){
            return $server;
        }
    }
    return array_pop($this-&gt;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>';

标签: 服务器列表,顺时针,客户端

赞(2)
未经允许不得转载:工具盒子 » Memcached分布式部署方案设计(含PHP代码)