这篇文章主要介绍怎么使用PHP实现分布算法之一致性哈希算法,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!
对于服务器分布,我们要考虑的东西有如下三点:数据平均分布,查找定位准确,降低宕机影响。
传统算法一般是将数据的键用算法映射出数字,对其用服务器数量取模,并根据结果选择要存储的服务器。其能达到数据平均分布和查找定位准确的要求,并且优点是算法简单,存取时的计算量都比较小(在数据非常大时才会明显)。
但其有一个致命缺点,即一个服务器宕机后的影响很大,我们可以推算一下一台服务器宕机后的影响:
原有数据大部分丢失:服务器数量减少一台,取模数减1导致取模值错乱,如果以前有N台服务器,那么宕机后数据只有1/(n*(n-1))的数据能够被准确查找到。
负载无法均衡导致集体宕机:如果没有及时处理宕机的服务器,那么他的存储任务将会被顺序积累给它的下一个服务器,那么下一个服务器也会很快被压致宕机,如此一来,服务器组很快会集体宕机。
一致性哈希算法是使用一定的哈希算法,将大量的数据平均映射到不同的存储目标上,在保证其查找准确性的同时,还要考虑其中一个存储目标失效时,其他存储目标对其责任存储内容的负载均衡。
一致性哈希算法的实现思想不难理解,如图:
1.用一定的哈希算法(哈希函数等)将一组服务器的多个(数目自己设定)节点随机映射分散到0-232之间,由于其随机分布,保证了其数据平均分布的特点;
2.用同一算法计算要存储数据的键,根据服务器节点确定其存储的服务器结点,由于每次用同一算法计算,所以得出的结果是相同的,使其查找定位准确;
3.查找数据时,再次用同一算法计算键,并查找服务器的数据结点;
4.如果有一个服务器宕机,消除其服务器结点,并将数据放在下一个结点上,由于随机节点位置的随机性,所以数据被其他服务器平均负载,也就降低了宕机影响。
需要注意的是,这个环形空间只是一个虚拟空间,只是表示了服务器存储的范围和数据的落点,在进行存储时,我们还要通过查找到的落点,将数据放入对应的服务器进行查改。
编程语言我们使用PHP来实现一致性哈希算法:
我们主要用到以下函数:
int crc32 ( string $str )
生成 str 的 32 位循环冗余校验码多项式。这通常用于检查传输的数据是否完整。
string sprintf ( string $format [, mixed $args [, mixed $... ]] )
通过传入的格式产生字符串的特定格式形态。
实现如下:
class Consistance { protected $num=24; //设定每一个服务器的节点数,数量越多,宕机时服务器负载就会分布得越平均,但也增大数据查找消耗。 protected $nodes=array(); //当前服务器组的结点列表。 //计算一个数据的哈希值,用以确定位置 public function make_hash($data) { return sprintf('%u',crc32($data)); } //遍历当前服务器组的节点列表,确定需要存储/查找的服务器 public function set_loc($data) { $loc=self::make_hash($data); foreach ($this->nodes as $key => $val) { if($loc<=$key) { return $val; } } } //添加一个服务器,将其结点添加到服务器组的节点列表内。 public function add_host($host) { for($i=0;$i<$this->num;$i++) { $key=sprintf('%u',crc32($host.'_'.$i)); $this->nodes[$key]=$host; } ksort($this->nodes); //对结点排序,这样便于查找。 } //删除一个服务器,并将其对应节点从服务器组的节点列表内移除。 public function remove_host($host) { for($i=0;$i<$this->num;$i++) { $key=sprintf('%u',crc32($host.'_'.$i)); unset($this->nodes[$key]); } } }
我们用以下代码进行测试:
结果如下:
以上是“怎么使用PHP实现分布算法之一致性哈希算法”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注亿速云行业资讯频道!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。