分布式缓存 - 第五周作业

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

还未添加个人简介

评论

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