分布式缓存 - 第五周作业
发布于: 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 加入
还未添加个人简介
评论