当前位置: 首页 > news >正文

一致性hash

在大型web应用中,缓存可算是当今的一个标准开发配置了。在大规模的缓存应用中,应运而生了分布式缓存系统。分布式缓存系统的基本原理,大家也有所耳闻。key-value如何均匀的分散到集群中?说到此,最常规的方式莫过于hash取模的方式。比如集群中可用机器适量为N,那么key值为K的的数据请求很简单的应该路由到hash(K) mod N对应的机器。的确,这种结构是简单的,也是实用的。但是在一些高速发展的web系统中,这样的解决方案仍有些缺陷。随着系统访问压力的增长,缓存系统不得不通过增加机器节点的方式提高集群的相应速度和数据承载量。增加机器意味着按照hash取模的方式,在增加机器节点的这一时刻,大量的缓存命不中,缓存数据需要重新建立,甚至是进行整体的缓存数据迁移,瞬间会给DB带来极高的系统负载,设置导致DB服务器宕机。 那么就没有办法解决hash取模的方式带来的诟病吗?看下文。

一致性哈希(Consistent Hashing):

      选择具体的机器节点不在只依赖需要缓存数据的key的hash本身了,而是机器节点本身也进行了hash运算。

 

(1) hash机器节点

 

首先求出机器节点的hash值(怎么算机器节点的hash?ip可以作为hash的参数吧。。当然还有其他的方法了),然后将其分布到0~2^32的一个圆环上(顺时针分布)。如下图所示:

 

集群中有机器:A , B, C, D, E五台机器,通过一定的hash算法我们将其分布到如上图所示的环上。

 

(2)访问方式

如果有一个写入缓存的请求,其中Key值为K,计算器hash值Hash(K), Hash(K) 对应于图 – 1环中的某一个点,如果该点对应没有映射到具体的某一个机器节点,那么顺时针查找,直到第一次找到有映射机器的节点,该节点就是确定的目标节点,如果超过了2^32仍然找不到节点,则命中第一个机器节点。比如 Hash(K) 的值介于A~B之间,那么命中的机器节点应该是B节点(如上图 )。

 

(3)增加节点的处理

如上图 – 1,在原有集群的基础上欲增加一台机器F,增加过程如下:

计算机器节点的Hash值,将机器映射到环中的一个节点,如下图:

 

增加机器节点F之后,访问策略不改变,依然按照(2)中的方式访问,此时缓存命不中的情况依然不可避免,不能命中的数据是hash(K)在增加节点以前落在C~F之间的数据。尽管依然存在节点增加带来的命中问题,但是比较传统的 hash取模的方式,一致性hash已经将不命中的数据降到了最低。

 

Consistent Hashing最大限度地抑制了hash键的重新分布。另外要取得比较好的负载均衡的效果,往往在服务器数量比较少的时候需要增加虚拟节点来保证服务器能均匀的分布在圆环上。因为使用一般的hash方法,服务器的映射地点的分布非常不均匀。使用虚拟节点的思想,为每个物理节点(服务器)在圆上分配100~200个点。这样就能抑制分布不均匀,最大限度地减小服务器增减时的缓存重新分布。用户数据映射在虚拟节点上,就表示用户数据真正存储位置是在该虚拟节点代表的实际物理服务器上。
下面有一个图描述了需要为每台物理服务器增加的虚拟节点。

 


  

x轴表示的是需要为每台物理服务器扩展的虚拟节点倍数(scale),y轴是实际物理服务器数,可以看出,当物理服务器的数量很小时,需要更大的虚拟节点,反之则需要更少的节点,从图上可以看出,在物理服务器有10台时,差不多需要为每台服务器增加100~200个虚拟节点才能达到真正的负载均衡。

转载于:https://www.cnblogs.com/ghost240/archive/2012/05/30/2526701.html

相关文章:

  • LabView和DLL中的参数问题
  • Oracle高级复制
  • 浅谈回归(二)——Regression 之历史错误翻译
  • JS判断浏览器类型和屏幕分辨率来调用不同的CSS样式
  • CentOS 6.7 如何启用中文输入法
  • Citrix XenDesktop 引发的学案(四)-与“您的虚拟桌面”之间的连接失败,状态(1030)...
  • 云计算成朝阳产业,未来发展已成趋势
  • js去掉html标签和去掉字符串文本的所有的空格
  • 关于Flurry的数据统计
  • 使用wix制作安装包
  • 使用Windows8开发Metro风格应用七
  • 黑马程序猿——15,String,StringBuffer,基本数据类型包装对象
  • linux libpcap的性能问题,请大家注意绕行。
  • LVS与KEEPALIVED实现高性能高可用负载均衡服务器
  • Vue(二)header组件开发
  • download使用浅析
  • express + mock 让前后台并行开发
  • Java 网络编程(2):UDP 的使用
  • NLPIR语义挖掘平台推动行业大数据应用服务
  • vue从入门到进阶:计算属性computed与侦听器watch(三)
  • webpack+react项目初体验——记录我的webpack环境配置
  • Web设计流程优化:网页效果图设计新思路
  • 翻译:Hystrix - How To Use
  • 计算机常识 - 收藏集 - 掘金
  • 开源SQL-on-Hadoop系统一览
  • 学习Vue.js的五个小例子
  • 一份游戏开发学习路线
  • 原生Ajax
  • 运行时添加log4j2的appender
  • python最赚钱的4个方向,你最心动的是哪个?
  • scrapy中间件源码分析及常用中间件大全
  • ​渐进式Web应用PWA的未来
  • $().each和$.each的区别
  • (力扣)1314.矩阵区域和
  • (论文阅读11/100)Fast R-CNN
  • (入门自用)--C++--抽象类--多态原理--虚表--1020
  • (十三)Java springcloud B2B2C o2o多用户商城 springcloud架构 - SSO单点登录之OAuth2.0 根据token获取用户信息(4)...
  • (四) 虚拟摄像头vivi体验
  • (四)linux文件内容查看
  • (算法)求1到1亿间的质数或素数
  • (一一四)第九章编程练习
  • (原创)boost.property_tree解析xml的帮助类以及中文解析问题的解决
  • (原創) 如何使用ISO C++讀寫BMP圖檔? (C/C++) (Image Processing)
  • .htaccess 强制https 单独排除某个目录
  • .NET 常见的偏门问题
  • .NET 中 GetHashCode 的哈希值有多大概率会相同(哈希碰撞)
  • .net 重复调用webservice_Java RMI 远程调用详解,优劣势说明
  • .netcore 如何获取系统中所有session_如何把百度推广中获取的线索(基木鱼,电话,百度商桥等)同步到企业微信或者企业CRM等企业营销系统中...
  • .Net的DataSet直接与SQL2005交互
  • .NET业务框架的构建
  • .pub是什么文件_Rust 模块和文件 - 「译」
  • :not(:first-child)和:not(:last-child)的用法
  • @Autowired 与@Resource的区别
  • @select 怎么写存储过程_你知道select语句和update语句分别是怎么执行的吗?
  • @基于大模型的旅游路线推荐方案