一致性哈希算法以及其PHP实现详细解析


Posted in PHP onAugust 24, 2013

在做服务器负载均衡时候可供选择的负载均衡的算法有很多,包括:  轮循算法(Round Robin)、哈希算法(HASH)、最少连接算法(Least Connection)、响应速度算法(Response Time)、加权法(Weighted )等。其中哈希算法是最为常用的算法.

典型的应用场景是: 有N台服务器提供缓存服务,需要对服务器进行负载均衡,将请求平均分发到每台服务器上,每台机器负责1/N的服务。

常用的算法是对hash结果取余数 (hash() mod N):对机器编号从0到N-1,按照自定义的hash()算法,对每个请求的hash()值按N取模,得到余数i,然后将请求分发到编号为i的机器。但这样的算法方法存在致命问题,如果某一台机器宕机,那么应该落在该机器的请求就无法得到正确的处理,这时需要将当掉的服务器从算法从去除,此时候会有(N-1)/N的服务器的缓存数据需要重新进行计算;如果新增一台机器,会有N /(N+1)的服务器的缓存数据需要进行重新计算。对于系统而言,这通常是不可接受的颠簸(因为这意味着大量缓存的失效或者数据需要转移)。那么,如何设计一个负载均衡策略,使得受到影响的请求尽可能的少呢?

在Memcached、Key-Value Store、Bittorrent DHT、LVS中都采用了Consistent Hashing算法,可以说Consistent Hashing 是分布式系统负载均衡的首选算法。

1、Consistent Hashing算法描述

下面以Memcached中的Consisten Hashing算法为例说明。
由于hash算法结果一般为unsigned int型,因此对于hash函数的结果应该均匀分布在[0,232-1]间,如果我们把一个圆环用232 个点来进行均匀切割,首先按照hash(key)函数算出服务器(节点)的哈希值, 并将其分布到0~232的圆上。

用同样的hash(key)函数求出需要存储数据的键的哈希值,并映射到圆上。然后从数据映射到的位置开始顺时针查找,将数据保存到找到的第一个服务器(节点)上。

一致性哈希算法以及其PHP实现详细解析 Consistent Hashing原理示意图

新增一个节点的时候,只有在圆环上新增节点逆时针方向的第一个节点的数据会受到影响。删除一个节点的时候,只有在圆环上原来删除节点顺时针方向的第一个节点的数据会受到影响,因此通过Consistent Hashing很好地解决了负载均衡中由于新增节点、删除节点引起的hash值颠簸问题。

一致性哈希算法以及其PHP实现详细解析 Consistent Hashing添加服务器示意图

虚拟节点(virtual nodes):之所以要引进虚拟节点是因为在服务器(节点)数较少的情况下(例如只有3台服务器),通过hash(key)算出节点的哈希值在圆环上并不是均匀分布的(稀疏的),仍然会出现各节点负载不均衡的问题。虚拟节点可以认为是实际节点的复制品(replicas),本质上与实际节点实际上是一样的(key并不相同)。引入虚拟节点后,通过将每个实际的服务器(节点)数按照一定的比例(例如200倍)扩大后并计算其hash(key)值以均匀分布到圆环上。在进行负载均衡时候,落到虚拟节点的哈希值实际就落到了实际的节点上。由于所有的实际节点是按照相同的比例复制成虚拟节点的,因此解决了节点数较少的情况下哈希值在圆环上均匀分布的问题。

一致性哈希算法以及其PHP实现详细解析 

虚拟节点对Consistent Hashing结果的影响

从上图可以看出,在节点数为10个的情况下,每个实际节点的虚拟节点数为实际节点的100-200倍的时候,结果还是很均衡的。

第3段中有这些文字:“但这样的算法方法存在致命问题,如果某一台机器宕机,那么应该落在该机器的请求就无法得到正确的处理,这时需要将当掉的服务器从算法从去除,此时候会有(N-1)/N的服务器的缓存数据需要重新进行计算;”

为何是 (N-1)/N 呢?解释如下:

比如有 3 台机器,hash值 1-6 在这3台上的分布就是:
host 1: 1 4
host 2: 2 5
host 3: 3 6
如果挂掉一台,只剩两台,模数取 2 ,那么分布情况就变成:
host 1: 1 3 5
host 2: 2 4 6

可以看到,还在数据位置不变的只有2个: 1,2,位置发生改变的有4个,占共6个数据的比率是 4/6 = 2/3这样的话,受影响的数据太多了,势必太多的数据需要重新从 DB 加载到 cache 中,严重影响性能

【consistent hashing 的办法】
上面提到的 hash 取模,模数取的比较小,一般是负载的数量,而 consistent hashing 的本质是将模数取的比较大,为 2的32次方减1,即一个最大的 32 位整数。然后,就可以从容的安排数据导向了,那个图还是挺直观的。
以下部分为一致性哈希算法的一种PHP实现。点击下载

PHP 相关文章推荐
第十三节 对象串行化 [13]
Oct 09 PHP
介绍几个array库的新函数 php
Dec 29 PHP
字母顺序颠倒而单词顺序不变的php代码
Aug 08 PHP
PHP 观察者模式的实现代码
May 10 PHP
探讨:如何使用PHP实现计算两个日期间隔的年、月、周、日数
Jun 13 PHP
跟我学Laravel之请求(Request)的生命周期
Oct 15 PHP
php数组排序usort、uksort与sort函数用法
Nov 17 PHP
php中get_cfg_var()和ini_get()的用法及区别
Mar 04 PHP
php自定义函数实现统计中文字符串长度的方法小结
Apr 15 PHP
php 函数使用可变数量的参数方法
May 02 PHP
详解php curl带有csrf-token验证模拟提交方法
Apr 18 PHP
php面试实现反射注入的详细方法
Sep 30 PHP
PHP如何利用P3P实现跨域
Aug 24 #PHP
PHP引用符&的用法详细解析
Aug 22 #PHP
新手菜鸟必读:session与cookie的区别
Aug 22 #PHP
PHP mysql与mysqli事务使用说明 分享
Aug 17 #PHP
php中url传递中文字符,特殊危险字符的解决方法
Aug 17 #PHP
测试PHP连接MYSQL成功与否的代码
Aug 16 #PHP
PHP 通过Socket收发十六进制数据的实现代码
Aug 16 #PHP
You might like
解析mysql 表中的碎片产生原因以及清理
2013/06/22 PHP
PHP执行linux命令常用函数汇总
2016/02/02 PHP
php使用strip_tags()去除html标签仍有空白的解决方法
2016/07/28 PHP
javascript new后的constructor属性
2010/08/05 Javascript
jquer之ajaxQueue简单实现代码
2011/09/15 Javascript
JSON取值前判断
2014/12/23 Javascript
Javascript 拖拽的一些简单的应用(逐行分析代码,让你轻松了拖拽的原理)
2015/01/23 Javascript
深入学习jQuery Validate表单验证
2016/01/18 Javascript
Markdown与Bootstrap相结合实现图片自适应属性
2016/05/04 Javascript
详解JS几种变量交换方式以及性能分析对比
2016/11/25 Javascript
一个例子轻松学会Vue.js
2017/01/02 Javascript
require.js中的define函数详解
2017/07/10 Javascript
微信小程序如何获取openid及用户信息
2018/01/26 Javascript
layer 关闭指定弹出层的例子
2019/09/25 Javascript
jQuery+css实现的点击图片放大缩小预览功能示例【图片预览 查看大图】
2020/05/29 jQuery
[10:42]Team Liquid Vs Newbee
2018/06/07 DOTA
[51:22]Fnatic vs IG 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/18 DOTA
Python基于pygame实现的弹力球效果(附源码)
2015/11/11 Python
Python实现定时精度可调节的定时器
2018/04/15 Python
利用matplotlib为图片上添加触发事件进行交互
2020/04/23 Python
使用Keras中的ImageDataGenerator进行批次读图方式
2020/06/17 Python
css3给背景图片加颜色遮罩的方法
2019/11/05 HTML / CSS
多视角3D逼真HTML5水波动画
2016/03/03 HTML / CSS
美国肌肉和力量商店:Muscle & Strength
2019/06/22 全球购物
双立人加拿大官网:Zwilling加拿大
2020/08/10 全球购物
铭立家具面试题
2012/12/06 面试题
J2ee常用的设计模式?说明工厂模式
2015/05/21 面试题
环境科学专业个人求职信
2013/12/15 职场文书
领导干部培训感言
2014/01/23 职场文书
优秀毕业生找工作自荐信
2014/06/23 职场文书
出售房屋协议书范本
2014/10/06 职场文书
交通运输局四风问题对照检查材料思想汇报
2014/10/09 职场文书
2015年十一国庆节演讲稿
2015/03/20 职场文书
格列佛游记读书笔记
2015/06/30 职场文书
信息技术国培研修日志
2015/11/13 职场文书
pytorch中[..., 0]的用法说明
2021/05/20 Python