Memcache的一致性哈希的PHP实现方法

本文介绍了memcache的一致性哈希的PHP实现。分享给你供你参考。以下是如下:

最近在一些分布式方面的文章的观点,所以我用PHP哈希实现实践的一致性,在一般使用的是最原始的哈希模分布,当添加或删除后面的生产过程中会导致所有数据失效,哈希的一致性是解决这一问题,失败的数据降到最低,相关信息可以眉目传情!

PHP的实现缺乏效率。如果你想有效率,最好是写作和拓展。

经过测试,5缓存,每个后面的生成100个虚拟节点,设置加get1000倍,比单一的memcache直接套加变慢5倍,所以效率一般,有待优化。

在阅读这篇文章之前,最好先了解两点搜索法。

实施过程:

这是配置一个IP +口+虚拟节点序列号使用CRC32散列,形成闭合回路。

CRC32要操作的关键

二分法查找虚拟节点环中最近的虚拟节点。

从虚拟节点提取房后面的IP和端口,一个连接

复制代码代码如下所示:

< PHP

类memcachehashmap {

私人_node美元=阵();

私人_nodedata美元=阵();

私人_keynode = 0美元;

私人_memcache美元= null;

每一个物理服务器生成的虚拟节点{注:节点数,分布的均匀性好,缓存集和获取,资源消耗较多,10个物理服务器,200个更合理。

私人_virtualnodenum = 200美元;

私有函数__construct(){

$配置=阵列(五 / / Memcache服务器

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

);

如果(!$配置)抛出异常('cache配置空);

foreach(美元美元美元价值配置关键=){

为($我= 0;我_virtualnodenum美元美元;i++){

美元-> _node { sprintf(% U

}

}

Ksort(美元-> _node); / / 1000虚拟节点按升序创建的关键

}

实例化类

静态getInstance(){公共功能

静态memcacheobj美元= null;

如果(!is_object($ memcacheobj)){

memcacheobj美元=新的自我();

}

返回的memcacheobj;

}

根据密钥搜索到达相应的虚拟节点/位置

私有函数_connectmemcache($键){

美元-> _nodedata = array_keys(美元-> _node); / /阵列虚拟节点的所有键

美元-> _keynode = sprintf(%

nodekey美元=(美元-> _findservernode); / /虚拟节点中找到对应的

如果超出环,然后从二分法中找出最新的一个,然后对头和尾环做出判断,取最近的节点。

如果(美元-> _keynode >结束(美元-> _nodedata)){

美元-> _keynode =结束(美元-> _nodedata);

nodekey2美元=美元-> _findservernode();

如果(ABS(nodekey2美元-美元-> _keynode)_keynode))nodekey = nodekey2美元美元;

}

var_dump(美元-> _node { $ nodekey });

列表(合配置,$num)=爆炸('_,美元-> _node { $ nodekey });

如果(!$配置)抛出异常('cache配置错误);

如果(!isset(美元-> _memcache { $配置})){

美元-> _memcache {美元} =新的缓存配置;

列表(主机,端口)=爆炸(:,$配置);

这_memcache美元->配置->连接} { $(美元美元的主机,端口);

}

返回这个-> _memcache { $配置};

}

根据给定的值二分法查找最接近的虚拟节点的位置。

私有函数_findservernode($ M = 0,B = 0美元){

总美元=计数(美元-> _nodedata);

如果(总计)!= 0 $ = = 0)$ = $总- 1;

如果(m $ < b){

美元intval AVG =(($ M + $ B) / 2);

If ($this->_nodeData{$avg} = = $this->_keyNode) return $this->_nodeData{$avg};

(美元-> _keynode _nodedata { $ AVG }($ avg-1 > = 0))返回美元-> _findservernode(百万元,avg-1美元);

否则返回美元-> _findservernode(平均1美元,$);

}

如果(ABS(美元-> _nodedata { $ } $这-> _keynode)_nodedata { $ M } $这-> _keynode))返回美元-> _nodedata { $ b };

否则返回美元-> _nodedata { $ M };

}

公共函数集($键,$,$过期= 0){

返回这个-> _connectmemcache($键)->设置($键,json_encode(价值0美元),,过期);

}

公共函数添加($键,$,$过期= 0){

返回这个-> _connectmemcache($键)->添加($键,json_encode(价值0美元),,过期);

}

公共函数获取($ key){

返回json_decode(美元-> _connectmemcache($键)->得到($键),真的);

}

公共函数删除($ key){

返回这个-> _connectmemcache($键)->删除(为重点);

}

}

rundata美元{ 'begin_time} =瞬时(真);

一万集加测试

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

美元关键= MD5(mt_rand());

$ = memcachehashmap::getInstance()->设置($键,时间(),10);

}

var_dump(number_format(瞬时(真正的)至rundata { 'begin_time},6));

rundata美元{ 'begin_time} =瞬时(true);$ M =新memcache;

$ M ->连接('127.0.0.1 ',11211);

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

美元关键= MD5(mt_rand());

$ $ =设置($键,时间(),0, 10);

}

var_dump(number_format(瞬时(真正的)至rundata { 'begin_time},6));

>



希望本文能对大家的PHP程序设计有所帮助。