memcached分布式-一致性哈希

一致性哈希分布式算法

概述
一致性哈希提出了在动态变化的Cache环境中,哈希算法应该满足的4个适应条件:
均衡性:尽可能分布到所有的缓冲中,使得所有的空间得到利用;
单调性:新增缓冲时候,能分配到新的缓冲区。
分散性:尽量避免不一致情况发生,降低分散性。
负载:能最好均匀分布到各个缓冲区。同时清晰路由到某个节点。
分析
当n个memcached服务器中1台down掉了,也就是变成了n-1台。
1/(n-1):将down掉了那一台服务器负载平均分配到其余的服务器上。
场景分析
引入虚拟节点,如3台服务器a,b,c
a1,a2.....a64个节点。b1,b2....b64个节点。c1,c2...c64个节点,混合均匀排序;
(条件:假设前一个节点挂掉会找相邻的节点进行存储。)

keyx在服务器b1,keyy在服务器b2,keyz在服务器节点b64;
假设b服务器down掉,则keyx在a服务器,keyy在b服务器,keyz在a服务器(相邻节点)

虚拟出虚拟越多的虚拟节点这样就能使得所有的缓存key均匀分布并且当一台挂掉会找相邻的节点;
这样概率角度能达到均匀的负载到其他服务器上去。

PHP实现

需要一个函数把字符串转成整数的函数crc32
简单示例
<?php


class Consistent {
    protected $nodes = array();
    protected $virtual = 64;//表示每台服务器有64个虚拟节点
    protected $position = array();//虚拟节点
    /**
     *@function 实现hash,将字符串转成响应整数
     */
    public function _hash($str)
    {
        //把字符串转成32位无符号整数
        return sprintf('%u', crc32($str));

    }
    /**
     *@function 根据key 值来查找到相关的存储节点
     *
     */
    public function lookup($key)
    {
        //算出key值
        $point = $this->_hash($key);
        //沿着节点进行判断该key值应该存储哪个节点
        $node = current($this->nodes);
        foreach($this->position as $key => $val) {
            if($point <= $key) {
                $node = $val;
                break;
            }
        }
        return $node;//返回node节点所处的服务器;
    }
    /**
     *@function 添加一个服务器需要新增64个虚拟节点
     */
    public function addNode($node) {
        //虚拟出64个节点。
       for($i = 0; $i < $this->virtual; $i++) {
            $num = $node .'-'.$i;
            $this->position[$this->_hash($num)] = $node;//新增64个位置
       }
        $this->nodes[] = $node;
        //对新增节点进行排序,整个节点进行排序
       $this->nodeSort();
    }
    /**
     *@function 删除一个服务器节点
     *
     */
    public function delNode($node) {
        //循环所有的虚拟节点位置
        foreach($this->position as $key => $val) {
            if($val == $node) {
                unset($this->position[$key]);
            }
        }
    }


    /**
     *@function 排序大小
     *
     */
    public function nodeSort() {
        ksort($this->position, SORT_REGULAR);
    }
    /**
     *@function 获取所有的节点
     *
     */
    public function getNodes() {
        return $this->nodes;
    }
    /**
     *@function 返回所有的虚拟节点
     *
     */
    public function getVirtual() {
        return $this->position;
    }


}
$con = new Consistent();
$con->addNode('a');//a服务器
$con->addNode('b');//b服务器
$con->addNode('c');//c服务器
print_r($con->getVirtual());
$name = 'linjunbin';
$tital = 'title4';
echo $name.'数字为'.$con->_hash($name).'落在'.$con->lookup($name);
echo '<br>';
echo $tital.'数字为'.$con->_hash($tital).'落在'.$con->lookup($tital);

未完待续….

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值