如何用PHP实现分布算法之一致性哈希算法


Posted in PHP onMay 26, 2021

传统算法缺陷

对于服务器分布,我们要考虑的东西有如下三点:数据平均分布,查找定位准确,降低宕机影响。

传统算法一般是将数据的键用算法映射出数字,对其用服务器数量取模,并根据结果选择要存储的服务器。其能达到数据平均分布和查找定位准确的要求,并且优点是算法简单,存取时的计算量都比较小(在数据非常大时才会明显)。

但其有一个致命缺点,即一个服务器宕机后的影响很大,我们可以推算一下一台服务器宕机后的影响:

  • 原有数据大部分丢失:服务器数量减少一台,取模数减1导致取模值错乱,如果以前有N台服务器,那么宕机后数据只有1/(n*(n-1))的数据能够被准确查找到。
  • 负载无法均衡导致集体宕机:如果没有及时处理宕机的服务器,那么他的存储任务将会被顺序积累给它的下一个服务器,那么下一个服务器也会很快被压致宕机,如此一来,服务器组很快会集体宕机。

算法思想

一致性哈希算法是使用一定的哈希算法,将大量的数据平均映射到不同的存储目标上,在保证其查找准确性的同时,还要考虑其中一个存储目标失效时,其他存储目标对其责任存储内容的负载均衡。

一致性哈希算法的实现思想不难理解,如图:

如何用PHP实现分布算法之一致性哈希算法

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实现分布算法之一致性哈希算法

结果如下:

如何用PHP实现分布算法之一致性哈希算法

总结

算法的实现到此,我们还可以对算法进行优化,如在服务器数量和每个服务器节点数都很多的情况下,对查找结点的过程进行优化,因为排序好的,可以用二分法进行查找,加快查询效率,这些,仁智各见吧。

另外,虽然nginx服务器有一致性算法的插件,memcache和redis也都有相应的插件,MySQL的中间件有相应的集成,但是了解一致性哈希算法也很有意义。而且,我们也可以对其灵活使用,如对文件等进行分布式管理等等。

以上就是如何用PHP实现分布算法之一致性哈希算法的详细内容,更多关于用PHP实现分布算法之一致性哈希算法的资料请关注三水点靠木其它相关文章!

PHP 相关文章推荐
类的另类用法--数据的封装
Oct 09 PHP
用文本文件制作留言板提示(下)
Oct 09 PHP
《PHP边学边教》(02.Apache+PHP环境配置――上篇)
Dec 13 PHP
Windows下XDebug 手工配置与使用说明
Jul 11 PHP
PHP里的中文变量说明
Jul 23 PHP
PHP substr 截取字符串出现乱码问题解决方法[utf8与gb2312]
Dec 16 PHP
php中strlen和mb_strlen用法实例分析
Nov 12 PHP
PHP常用排序算法实例小结【基本排序,冒泡排序,快速排序,插入排序】
Feb 07 PHP
thinkPHP5.0框架API优化后的友好性分析
Mar 17 PHP
利用php-cli和任务计划实现订单同步功能的方法
May 03 PHP
php取出数组单个值的方法
Mar 12 PHP
使用swoole 定时器变更超时未支付订单状态的解决方案
Jul 24 PHP
如何用PHP实现多线程编程
May 26 #PHP
如何用PHP websocket实现网页实时聊天
详解PHP用mb_string处理windows中文字符
May 26 #PHP
详解PHP服务器如何在有限的资源里最大提升并发能力
详解PHP设计模式之依赖注入模式
阿里云服务器搭建Php+Apache运行环境的详细过程
php+laravel 扫码二维码签到功能
You might like
超人钢铁侠联手合作?美漫作家呼吁DC漫威合作联动以抵抗疫情
2020/04/09 欧美动漫
推荐个功能齐全的发送PHP邮件类
2007/01/03 PHP
PHP生成HTML静态页面实例代码
2008/08/31 PHP
php fckeditor 调用的函数
2009/06/21 PHP
仿Aspnetpager的一个PHP分页类代码 附源码下载
2012/10/08 PHP
phpmyadmin显示utf8_general_ci中文乱码的问题终级篇
2013/04/08 PHP
PHP类的特性实例分析
2016/09/28 PHP
php执行多个存储过程的方法【基于thinkPHP】
2016/11/08 PHP
JavaScript 脚本将当地时间转换成其它时区
2009/03/19 Javascript
JS request函数 用来获取url参数
2010/05/17 Javascript
深入理解JavaScript作用域和作用域链
2011/10/21 Javascript
页面按钮禁用与解除禁用的方法
2014/02/19 Javascript
JavaScript实现DIV层拖动及动态增加新层的方法
2015/05/12 Javascript
浅析Node.js 中 Stream API 的使用
2015/10/23 Javascript
js+css实现回到顶部按钮(back to top)
2016/03/02 Javascript
javascript显示倒计时控制按钮的简单实现
2016/06/07 Javascript
使用JS中的exec()方法构造正则表达式验证
2016/08/01 Javascript
使用Vue开发自己的Chrome扩展程序过程详解
2019/06/21 Javascript
微信小程序 轮播图实现原理及优化详解
2019/09/29 Javascript
微信小程序实现横向滚动导航栏效果
2019/12/12 Javascript
微信小程序实现自定义动画弹框/提示框的方法实例
2020/11/06 Javascript
sqlalchemy对象转dict的示例
2014/04/22 Python
python中的内置函数getattr()介绍及示例
2014/07/20 Python
Python列表生成式与生成器操作示例
2018/08/01 Python
python ChainMap的使用和说明详解
2019/06/11 Python
用Python写一个自动木马程序
2019/09/17 Python
解决Opencv+Python cv2.imshow闪退问题
2020/04/24 Python
Python如何操作docker redis过程解析
2020/08/10 Python
html5中canvas学习笔记1-画板的尺寸与实际显示尺寸
2013/01/06 HTML / CSS
Amara美国站:英国高端家居礼品网站,世界各地的奢侈家具品牌
2017/07/26 全球购物
韩国流行时尚女装网站:Dintchina(中文)
2018/07/19 全球购物
搞笑的爱情检讨书
2014/10/01 职场文书
春秋淹城导游词
2015/02/11 职场文书
Keras在mnist上的CNN实践,并且自定义loss函数曲线图操作
2021/05/25 Python
win11如何查看端口是否被占用? Win11查看端口是否占用的技巧
2022/04/05 数码科技
什么是clearfix (一文搞清楚css清除浮动clearfix)
2023/05/21 HTML / CSS