日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > php >内容正文

php

php 一致性hash,【转载】memcache分布式 [一致性hash算法] 的php实现

發(fā)布時(shí)間:2025/4/17 php 55 豆豆
生活随笔 收集整理的這篇文章主要介紹了 php 一致性hash,【转载】memcache分布式 [一致性hash算法] 的php实现 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

最近在看一些分布式方面的文章,所以就用php實(shí)現(xiàn)一致性hash來(lái)練練手,以前一般用的是最原始的hash取模做分布式,當(dāng)生產(chǎn)過(guò)程中添加或刪除一臺(tái)memcache都會(huì)造成數(shù)據(jù)的全部失效,一致性hash就是為了解決這個(gè)問(wèn)題,把失效數(shù)據(jù)降到最低,相關(guān)資料可以google一下!

php實(shí)現(xiàn)效率有一定的缺失,如果要高效率,還是寫擴(kuò)展比較好

經(jīng)測(cè)試,5個(gè)memcache,每個(gè)memcache生成100個(gè)虛擬節(jié)點(diǎn),set加get1000次,與單個(gè)memcache直接set加get慢5倍,所以效率一般,有待優(yōu)化!

實(shí)現(xiàn)過(guò)程:

memcache的配置 ip+端口+虛擬節(jié)點(diǎn)序列號(hào) 做hash,使用的是crc32,形成一個(gè)閉環(huán)。

對(duì)要操作的key進(jìn)行crc32

二分法在虛擬節(jié)點(diǎn)環(huán)中查找最近的一個(gè)虛擬節(jié)點(diǎn)

從虛擬節(jié)點(diǎn)中提取真實(shí)的memcache ip和端口,做單例連接

/**

*?一致性哈希memcache分布式,采用的是虛擬節(jié)點(diǎn)的方式解決分布均勻性問(wèn)題,查找節(jié)點(diǎn)采用二分法快速查找

*?the?last?known?user?to?change?this?file?in?the?repository??

*?@author?nash.xiong?

*?@copyright?Copyright???2003-2012?phpd.cn

*?@license

*/

class?memcacheHashMap?{

private?$_node?=?array();

private?$_nodeData?=?array();

private?$_keyNode?=?0;

private?$_memcache?=?null;

//每個(gè)物理服務(wù)器生成虛擬節(jié)點(diǎn)個(gè)數(shù)?[注:節(jié)點(diǎn)數(shù)越多,cache分布的均勻性越好,同時(shí)set?get操作時(shí),也更耗資源,10臺(tái)物理服務(wù)器,采用200較為合理]

private?$_virtualNodeNum?=?200;

private?function?__construct()?{

/*?放入配置文件?*/

$config?=?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:11215'

);

if?(!$config)?throw?new?Exception('Cache?config?NULL');

foreach?($config?as?$key?=>?$value)?{

for?($i?=?0;?$i?_virtualNodeNum;?$i++)?{

$this->_node[sprintf("%u",?crc32($value?.?'_'?.?$i))]?=?$value?.?'_'?.?$i;

}

}

ksort($this->_node);

}

private?function?__clone(){}

/**

*?單例,保證只有一個(gè)實(shí)例

*/

static?public?function?getInstance()?{

static?$memcacheObj?=?null;

if?(!is_object($memcacheObj))?{

$memcacheObj?=?new?self();

}

return?$memcacheObj;

}

/**

*?根據(jù)key做一致性hash后連接到一臺(tái)物理memcache服務(wù)器

*?@param?string?$key

*/

private?function?_connectMemcache($key)?{

$this->_nodeData?=?array_keys($this->_node);

$this->_keyNode?=?sprintf("%u",?crc32($key));

$nodeKey?=?$this->_findServerNode();

//如果超出環(huán),從頭再用二分法查找一個(gè)最近的,然后環(huán)的頭尾做判斷,取最接近的節(jié)點(diǎn)

if?($this->_keyNode?>?end($this->_nodeData))?{

$this->_keyNode?-=?end($this->_nodeData);

$nodeKey2?=?$this->_findServerNode();

if?(abs($nodeKey2?-?$this->_keyNode)?_keyNode))??$nodeKey?=?$nodeKey2;

}

var_dump($this->_node[$nodeKey]);

list($config,?$num)?=?explode('_',?$this->_node[$nodeKey]);

if?(!$config)?throw?new?Exception('Cache?config?Error');

if?(!isset($this->_memcache[$config]))?{

$this->_memcache[$config]?=?new?Memcache;

list($host,?$port)?=?explode(':',?$config);

$this->_memcache[$config]->connect($host,?$port);

}

return?$this->_memcache[$config];

}

/**

*?采用二分法從虛擬memcache節(jié)點(diǎn)中查找最近的節(jié)點(diǎn)

*?@param?unknown_type?$m

*?@param?unknown_type?$b

*/

private?function?_findServerNode($m?=?0,?$b?=?0)?{

$total?=?count($this->_nodeData);

if?($total?!=?0?&&?$b?==?0)?$b?=?$total?-?1;

if?($m?

$avg?=?intval(($m+$b)?/?2);

if?($this->_nodeData[$avg]?==?$this->_keyNode)?return?$this->_nodeData[$avg];

elseif?($this->_keyNode?_nodeData[$avg]?&&?($avg-1?>=?0))?return?$this->_findServerNode($m,?$avg-1);

else?return?$this->_findServerNode($avg+1,?$b);

}

if?(abs($this->_nodeData[$b]?-?$this->_keyNode)?_nodeData[$m]?-?$this->_keyNode))??return?$this->_nodeData[$b];

else?return?$this->_nodeData[$m];

}

public?function?set($key,?$value,?$expire?=?0)?{

return?$this->_connectMemcache($key)->set($key,?json_encode($value),?0,?$expire);

}

public?function?add($key,?$value,?$expire?=?0)?{

return?$this->_connectMemcache($key)->add($key,?json_encode($value),?0,?$expire);

}

public?function?get($key)?{

return?json_decode($this->_connectMemcache($key)->get($key),?true);

}

public?function?delete($key)?{

return?$this->_connectMemcache($key)->delete($key);

}

}

$runData['BEGIN_TIME']?=?microtime(true);

//測(cè)試一萬(wàn)次set加get

for($i=0;$i<10000;$i++)?{

$key?=?md5(mt_rand());

$b?=?memcacheHashMap::getInstance()->set($key,?time(),?10);

}

var_dump(number_format(microtime(true)?-?$runData['BEGIN_TIME'],6));

$runData['BEGIN_TIME']?=?microtime(true);?$m=?new?Memcache;

$m->connect('127.0.0.1',?11211);

for($i=0;$i<10000;$i++)?{

$key?=?md5(mt_rand());

$b?=?$m->set($key,?time(),?0,?10);

}

var_dump(number_format(microtime(true)?-?$runData['BEGIN_TIME'],6));

//測(cè)試結(jié)果,采用一致性哈希分布效率比原生單臺(tái)速度相差5倍左右

總結(jié)

以上是生活随笔為你收集整理的php 一致性hash,【转载】memcache分布式 [一致性hash算法] 的php实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。