写点什么

分布式缓存 - 第五周作业

用户头像
孙志平
关注
发布于: 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


用户头像

孙志平

关注

还未添加个人签名 2018.05.08 加入

还未添加个人简介

评论

发布
暂无评论
分布式缓存 - 第五周作业