分布式缓存 - 第五周作业
发布于: 2020 年 07 月 03 日
作业一
主要思路
1、添加 node 的时候生成 200 个虚拟节点,保存至数组中并进行排序,数组 key=hashcode,value=node
2、当执行 set 方法时,遍历虚拟节点数组,比较 set 的 key 值对应的 hashcode 与数组中的 key,找到最近的 node 节点并执行 node 中的 set 方法,节点存储数据 count 加 1
 
 interface ISet {    public function set($key, $value);}
class Node implements ISet{    private $name;
    private $ip;
    private $count = 0;
    /**     * Node constructor.     * @param $name     * @param $ip     */    public function __construct($name, $ip)    {        $this->name = $name;        $this->ip = $ip;    }
    public function set($key, $value)    {        $this->count++;    }
    /**     * @return mixed     */    public function getName()    {        return $this->name;    }
    /**     * @return mixed     */    public function getIp()    {        return $this->ip;    }
    /**     * @return int     */    public function getCount(): int    {        return $this->count;    }}
abstract class  Cluster implements ISet {    /**     * @var Node[]     */    protected $nodes=[];
    public abstract function addNode(Node $node);
    public function set($key, $value){        $this->getNode($key)->set($key, $value);    }
    /**     * @return Node     */    public abstract function getNode($key);
    /**     * @return Node[]     */    public function getNodes(){        return $this->nodes;    }
}
class ConsistencyHashCluster extends Cluster {
    private $virNodes = [];
    private $virCount = 200;
    public function addNode(Node $node)    {        $nodeHashKey = $node->getIp().'_'.$node->getName();        for ($i=0;$i<$this->virCount;$i++) {            $virHashKey = $nodeHashKey.$i;            $hashCode = $this->hashCode($virHashKey);            $this->virNodes[$hashCode] = $node;        }
        $this->nodes[$this->hashCode($nodeHashKey)] = $node;        ksort($this->nodes);        ksort($this->virNodes);
    }
    /**     * @param $key     * @return Node     */    public function getNode($key){        $node = current($this->nodes);        $hashCode = $this->hashCode($key);        foreach ($this->virNodes as $k =>$value) {            if ($hashCode <= $k) {                $node = $value;                break;            }        }        return $node;    }
    private function hashCode($key)    {        if (empty($key))            return '';        $str = strtoupper($key);        $mdv = md5($str);        $mdv1 = substr($mdv, 0, 16);        $mdv2 = substr($mdv, 16, 16);        $crc1 = abs(crc32($mdv1));        $crc2 = abs(crc32($mdv2));        return bcmul($crc1, $crc2);    }
}复制代码
 作业二
//添加10 个节点$consistencyHashCluster = new ConsistencyHashCluster();for ($i=1;$i<=10;$i++) {    $consistencyHashCluster->addNode(new Node('node'.$i, '192.168.31.'.$i));}  //set100万数据for ($i=1;$i<=1000000;$i++) {    $consistencyHashCluster->set(md5(uniqid(microtime(true),true)), $i);} // 将各个节点存储的数据放入数组中$list = [];foreach ($consistencyHashCluster->getNodes() as $node) {   echo $node->getName().' 存入数据: '.$node->getCount().' 个';    $list[] = $node->getCount();}  echo '标准差:'.(getVariance(100000, $list)).PHP_EOL;
function getVariance($avg, $list, $isSwatch  = FALSE) {    $arrayCount = count($list);    if($arrayCount == 1 && $isSwatch == TRUE){        return FALSE;    }elseif($arrayCount > 0 ){        $total_var = 0;        foreach ($list as $lv)            $total_var += pow(($lv - $avg), 2);        if($arrayCount == 1 && $isSwatch == TRUE)            return FALSE;        return $isSwatch?sqrt($total_var / (count($list) - 1 )):sqrt($total_var / count($list));    }    else        return FALSE;}复制代码
 结果
平均值:10W
node4 存入数据: 94333 个
node6 存入数据: 90069 个
node7 存入数据: 104582 个
node9 存入数据: 115093 个
node5 存入数据: 103757 个
node10 存入数据: 94318 个
node8 存入数据: 94348 个
node1 存入数据: 111336 个
node2 存入数据: 93728 个
node3 存入数据: 98436 个
标准差:7925.7004485408
划线
评论
复制
发布于: 2020 年 07 月 03 日阅读数: 55
孙志平
关注
还未添加个人签名 2018.05.08 加入
还未添加个人简介











 
    
评论