温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

php memcached 一致性hash

发布时间:2020-07-09 10:58:55 阅读:710 作者:birdinroom 栏目:web开发
PHP开发者专用服务器限时活动,0元免费领,库存有限,领完即止! 点击查看>>
<?php
/**
 * 一致性hahs实现类
 * 
 */
class FlexiHash{
/**
 * var int
 * 虚拟节点
 */
private $_replicas 200;
/**
 * 使用hash方法
 */
private $_hasher null;
/**
 * 真实节点计数器
 * 
 */
private $_targetCount 0;
/**
 * 位置对应节点,用户lookup中根据位置确定要访问的节点
 */
private $_positionToTarget array();
/**
 * 节点对应位置,用于删除节点
 */
private $_targetToPositions array();
/**
 * 是否已排序
 */
private $_positionToTargetSorted false;
/**
 * @ $hasher hash方法
 * @ $replicas 虚拟节点的个数
 * 
 * 确定要使用的hash方法和虚拟的节点数,虚拟节点越多,分布越均匀,但程序的分布式运算越慢
 */
public function __construct(FlexiHash_Hasher $hasher=null$replicas null){
// hash方法
$this->_hasher = $hasher?$hashernew FlexiHash_Crc32Hasher();
// 虚拟节点的个数
if (!empty($replicas)){
$this->_replicas = $replicas;
}
}
/**
 * 增加节点,根据虚拟节点数,把节点分布到更多的虚拟位置上
 */
public function addTarget($target){
if (isset($this->_targetToPositions[$target])) {
throw new FlexiHash_Exception("Target $target already exists.");
}
$this->_targetToPositions[$target] = array();
for ($i 0$i $this->_replicas; $i++) {
// 根据规定的方法hash
$position $this->_hasher->hash($target.$i);
// 虚拟节点对应的真实的节点
$this->_positionToTarget[$position] = $target;
// 真实节点包含的虚拟节点
$this->_targetToPositions[$target][] = $position;
}
$this->_positionToTargetSorted = false;
// 真实节点个数
$this->_targetCount++;
return $this;
}
/**
 * 添加多个节点
 * 
 */
public function addTargets($targets){
foreach ($targets as $target){
$this->addTarget($target);
}
return $this;
}
/**
 * 移除某个节点
 * 
 */
public function removeTarget($target){
if (!isset($this->_targetToPositions[$target])){
throw new FlexiHash_Exception("target $target does not exist\n");
}
foreach($this->_targetToPositions[$targetas $position){
unset($this->_positionToTarget[$position]);
}
unset($this->_targetToPositions[$target]);
$this->_targetCount--;
return $this;
}
/**
 * 获取所有节点
 * 
 */
public function getAllTargets(){
return array_keys($this->_targetToPositions);
}
/**
 * 根据key查找hash到的真实节点
 * 
 */
public function lookup($resource){
$targets $this->lookupList($resource1);
if (empty($targets)){
throw new FlexiHash_Exception("no targets exist");
}
return $targets[0];
}
/**
 * 查找资源存在的节点
 * 
 * 描述:根据要求的数量,返回与$resource哈希后数值相等或比其大并且是最小的数值对应的节点,若不存在或数量不够,则从虚拟节点排序后的前一个或多个
 */
public function lookupList($resource$requestedCount){
if (!$requestedCount) {
throw new FlexiHash_Exception('Invalid count requested');
}
if (empty($this->_positionToTarget)) {
return array();
}
// 直接节点只有一个的时候
if ($this->_targetCount == 1 ){
return array_unique(array_values($this->_positionToTarget));
}
// 获取当前key进行hash后的值
$resourcePosition $this->_hasher->hash($resource);
$results array();
$collect false;
$this->_sortPositionTargets();
// 查找与$resourcePosition 相等或比其大并且是最小的数
foreach($this->_positionToTarget as $key => $value){
if (!$collect && $key $resourcePosition){
$collect true;
}
if ($collect && !in_array($value$results)){
$results[] = $value;
}
// 找到$requestedCount 或个数与真实节点数量相同
if (count($results) == $requestedCount || count($results) == $this->_targetCount){
return $results;
}
}
// 如数量不够或者未查到,则从第一个开始,将$results中不存在前$requestedCount-count($results),设置为需要的节点
foreach ($this->_positionToTarget as $key => $value){
if (!in_array($value$results)){
$results[] = $value;
}
if (count($results) == $requestedCount || count($results) == $this->_targetCount){
return $results;
}
}
return $results;
}
/**
 * 根据虚拟节点进行排序
 */
private function _sortPositionTargets(){
if (!$this->_positionToTargetSorted){
ksort($this->_positionToTarget, SORT_REGULAR);
$this->_positionToTargetSorted = true;
}
}
}// end class
/**
 * hash方式
 */
interface FlexiHash_Hasher{
public function hash($string);
}
class FlexiHash_Crc32Hasher implements FlexiHash_Hasher{
public function hash($string){
return sprintf("%u",crc32($string));
}
}
class FlexiHash_Md5Hasher implements FlexiHash_Hasher{
public function hash($string){
return substr(md5($string), 08);
}
}
class FlexiHash_Exception extends Exception{
}
$runData['BEGIN_TIME'] = microtime(true);
$key="lihuibin";
for($i=0;$i<10;$i++) {
$targetsArray array(
"127.0.0.1:11211",
"127.0.0.1:11212",
"127.0.0.1:11213",
"127.0.0.1:11214",
#"127.0.0.1:11218"
);
$flexiHashObj new FlexiHash(new FlexiHash_Crc32Hasher(),1);
$result $flexiHashObj->addTargets($targetsArray);
$key=$key."$i";
$targets $flexiHashObj->lookup($key);
var_dump($targets);
#$key = md5(mt_rand());
#$targets = $flexiHashObj->lookup($key);
#var_dump($targets);
}
echo "一致性hash:";
var_dump(number_format(microtime(true) - $runData['BEGIN_TIME'],6));
exit;
$runData['BEGIN_TIME'] = microtime(true); 
$mnew Memcache;
$m->connect('127.0.0.1'11211); 
for($i=0;$i<10000;$i++) {
$key md5(mt_rand());
$b $m->set($keytime(), 010);
}
echo "单台机器:";
var_dump(number_format(microtime(true) - $runData['BEGIN_TIME'],6));
?>

亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI

开发者交流群×