分布式缓存的一致性 Hash 算法
一、使用一致性 Hash 算法的原因
简单的路由算法可以使用余数 Hash:用服务器数据除缓存数据 KEY 的 Hash 值,余数为服务器列表下标编码。这种算法可以满足大多数的缓存路由需求。但是,当分布式缓存集群需要扩容的时候,事情就变得棘手了。举个例子:很容易可以计算出,3台缓存服务器扩容至4台服务器,大约有 75%(3/4)被缓存了的数据不能正确命中,随着服务器集群规模的增大,这个比例线性上升。当100台服务器的集群中加入一台新服务器,不能命中的概率是 99%(N/N+1)。这种结果显然是不能接受的。
一种解决办法是在网站访问量最少的时候扩容缓存服务器集群,这时候数据库的负载冲击最小。然后通过模拟请求的方法逐渐预热缓存,使缓存服务器中的数据重新分布。但这种方案对业务场景有要求,还需要技术团队通宵加班。当然还有比流行的方案:一致性Hash 算法。
二、分布式缓存的一致性 Hash 算法
一致性 Hash 算法通一个叫作一致性 Hash 环的数据结构实现 KEY 到缓存服务器的 Hash 映射,如下图:
具体算法过程为:先构造一个长度为 整数环(这个环被称作一致性 Hash环)根据节点名称的 Hash 值(其分布范围为[0,-1])将缓存服务器节点放置在这个 Hash 环上。然后根据需要缓存的数据的 KEY 值计算得到其 Hash 值(其分布范围也同样为[0,-1]),然后在 Hash 环上顺时针查找距离这个 KEY 的 Hash 值最近的缓存服务器节点,完成 KEY 到服务器的 Hash 映射查找。
在缓存服务器集群需要扩容的时候,只需要将新加入的节点名称(Cache 服务器5)的 Hash 值放入一致性 Hash 环中,由于 KEY 是顺时针查找距离其最近的节点,因此新加入的节点只影响整个环中的一小段,如下图:
上图中,加入新节点 NODE5 后,原来的 KEY 大部分还能继续计算到原来的节点,只有节点4的部分数据重新计算到了节点5。这样就能保证大部分被缓存的数据还可以继续命中。3台服务器扩容至4台服务器,可以继续命中原有缓存数据的概率为 75%,远高于余数哈希的 25%,而且随着集群规模越大,继续命中原有缓存数据的概率也逐渐增大,100台服务器扩容增加1台,继续命中的概率 99%。虽然仍有小部分数据缓存在服务器中不能被读到,但是这个比例足够小,通过访问数据库获取也不会对数据库造成致命的负载压力。
具体应用中,这个长度为 的一致性 Hash 环通常使用二叉查找树实现,Hash 查找过程实际上是在二叉查找树中查找不小于查找树的最小数值。当然这个二叉树的最右边叶子节点和最左边的叶子节点相连接,构成环。
三、分布式缓存的一致性 Hash 算法存在的问题
新加入的节点 NODE5 只影响了原有节点 NODE4,也就是说一部分原来需要访问 NODE4 的缓存数据现在访问 NODE5(概率上是50%)。但是原来的其它节点不受影响,这就意味着其它节点缓存数据量和负载压力是 NODE4 和 NODE5 的两倍。如果所有节点的硬件和性能一样,那么这个结果显然不是我们需要的。
四、分布式缓存的一致性 Hash 算法问题解决方案
计算机领域有句话:计算机的任何问题都可以通过增加一个虚拟层来解决。计算机硬件,计算机网络,计算机软件都一样。计算机的 7层协议,每一层都可以看做是下一层的虚拟层;计算机操作系统可以看做是计算机硬件的虚拟层;Java 虚拟机可以看做是操作系统的虚拟层;分层的计算机软件架构事实上也是利用虚拟层的概念。解决上述问题就可以使用虚拟层的手段;将每台物理缓存服务器虚拟为一组虚拟缓存服务器,将虚拟服务器的 Hash 值放置在 Hash 环上,KEY 在环上先找到虚拟服务器节点,再得到物理服务器的信息。这样新加入物理服务器节点时,是将一组虚拟节点加入环中,如果虚拟节点的数目足够多,这组虚拟节点将会影响同样多数目的已经在环上存在的虚拟结点,这些已经存在的虚拟节点有对应不同的物理节点。最终的结果是:新加入一台缓存服务器,将会较为均匀地影响原来集群中已经存在的服务器,也就是说分摊原有缓存服务器集群中所有服务器的小部分负载,其总的影响范围和上面讨论过的相同。如下图:
新加入的节点 Node3 对应的一组虚拟节点为 V31,V32,V33 加入到一致性 Hash 环上后,影响 V01,V12,V22 三个虚拟节点,而这三个虚拟节点分别对应 Node0,Node1,Node2 三个物理节点。最终 Node3 加入后会影响到集群中已存在的三个物理节点,在理想情况下,每个物理节点受影响的数据量为其节点缓存数据量的 1/4(X/(N+X)),N为原有物理节点,X为新加入的物理节点,也就是集群中已经被缓存的数据有 75% 可以被继续命中,和未使用虚拟节点的一致性 Hash 算法结果相同。
虽然每个物理节点对应的虚拟节点越多,各个物理节点之间的负载越均衡,新加入物理服务器对原有的物理服务器的影响越保持一致(这就是一致性 Hash 这个名称的由来)。在实践中,一台物理服务器虚拟为多少个虚拟服务器节点比较合适呢?太多会影响性能,太少会导致负载不均衡,一般来说,经验值是150,当然根据集群规模和负载均衡的精度需求,这个值应该根据具体情况具体对待。
----关注公众号,获取更多内容----
分布式缓存的一致性 Hash 算法的更多相关文章
- 分布式缓存设计:一致性Hash算法
缓存作为数据库前的一道屏障,它的可用性与缓存命中率都会直接影响到数据库,所以除了配置主从保证高可用之外还需要设计分布式缓存来扩充缓存的容量,将数据分布在多台机器上如果有一台不可用了对整体影响也比较小. ...
- 分布式缓存的一致性Hash算法 2 32
w 李智慧
- 分布式缓存技术memcached学习(四)—— 一致性hash算法原理
分布式一致性hash算法简介 当你看到“分布式一致性hash算法”这个词时,第一时间可能会问,什么是分布式,什么是一致性,hash又是什么.在分析分布式一致性hash算法原理之前,我们先来了解一下这几 ...
- 分布式缓存技术memcached学习系列(四)—— 一致性hash算法原理
分布式一致性hash算法简介 当你看到"分布式一致性hash算法"这个词时,第一时间可能会问,什么是分布式,什么是一致性,hash又是什么.在分析分布式一致性hash算法原理之前, ...
- 分布式缓存一致性hash算法理解
今天阅读了一下大型网络技术架构这本苏中的分布式缓存一致性hash算法这一节,针对大型分布式系统来说,缓存在该系统中必不可少,分布式集群环境中,会出现添加缓存节点的需求,这样需要保障缓存服务器中对缓存的 ...
- Nginx+Memcache+一致性hash算法 实现页面分布式缓存(转)
网站响应速度优化包括集群架构中很多方面的瓶颈因素,这里所说的将页面静态化.实现分布式高速缓存就是其中的一个很好的解决方案... 1)先来看看Nginx负载均衡 Nginx负载均衡依赖自带的 ngx_h ...
- 分布式缓存一致性hash算法
当服务器不多,并且不考虑扩容的时候,可直接使用简单的路由算法,用服务器数除缓存数据KEY的hash值,余数作为服务器下标即可. 但是当业务发展,网站缓存服务需要扩容时就会出现问题,比如3台缓存服务器要 ...
- 一致性Hash算法在Redis分布式中的使用
由于redis是单点,但是项目中不可避免的会使用多台Redis缓存服务器,那么怎么把缓存的Key均匀的映射到多台Redis服务器上,且随着缓存服务器的增加或减少时做到最小化的减少缓存Key的命中率呢? ...
- 分布式一致性hash算法
写在前面 在学习Redis的集群内容时,看到这么一句话:Redis并没有使用一致性hash算法,而是引入哈希槽的概念.而分布式缓存Memcached则是使用分布式一致性hash算法来实现分布式存储. ...
- 7.redis 集群模式的工作原理能说一下么?在集群模式下,redis 的 key 是如何寻址的?分布式寻址都有哪些算法?了解一致性 hash 算法吗?
作者:中华石杉 面试题 redis 集群模式的工作原理能说一下么?在集群模式下,redis 的 key 是如何寻址的?分布式寻址都有哪些算法?了解一致性 hash 算法吗? 面试官心理分析 在前几年, ...
随机推荐
- python + appium 常用公共方法封装
appium 程序下载安装见之前的帖子:https://www.cnblogs.com/gancuimian/p/16536322.html appium 环境搭建见之前的帖子:https://www ...
- linux 基础命令 apt
Linux apt 命令 apt(Advanced Packaging Tool)是一个在 Debian 和 Ubuntu 中的 Shell 前端软件包管理器. apt 命令提供了查找.安装.升级.删 ...
- 项目实训DAY 11-12 学习
在神经网络可视化工具中,选择了三种,NNSVG,PlotNeuralNet,GraphCore 前两者应该比较好实现,例子都跑通了,对于定制的代码读起来也不难.PNN的示例图如下 最后一个虽然有实例图 ...
- AX2012 快速清空整个log表数据
如果当一个log表的数据非常大的时又需要清理时,如果允许删除全部数据,在AX里,可以 将log表的TableType调整为[TempDB], 保存同步后再将TableType设置回[Regular]即 ...
- Leetcode457
A very absurd description for this problem, but people can get the idea by looking at the examples.. ...
- SQL之查询
1. SQL之模糊查询 例如查询姓名时,不用输入全名,仅仅输入其中的一部分 语法: select 列名 from 表名 where 列名 like 匹配串 其中 匹配串用英文的单引号括起来 四种匹配模 ...
- C++与C语言中struct 与typedef struct 应用区别(摘自csdn mpp_king)
typedef是类型定义的意思.typedef struct 是为了使用这个结构体方便.具体区别在于:若struct node {}这样来定义结构体的话.在申请node 的变量时,需要这样写,stru ...
- Navicat15激活
1.下载Navicat for MySQL 15 https://www.navicat.com.cn/download/navicat-for-mysql 2.下载激活工具 注意:因某些限制,下载链 ...
- CF1338E JYPnation
题意:给定一个竞赛图,且其中不包含任意一组三元环 $(a, b, c)$,满足 $a \to d$,$b \to d$,$c \to d$,求每个点两两之间的距离之和(若无法达到即为 $614n$). ...
- Q:windows系统如何开机启动批处理脚本
方法1 1.win+r输入gpedit.msc进入本地策略管理器 2.点击windows设置下的脚本(启动/关机),然后双击启动. 3.点击添加,然后点击浏览,选择批处理文件然后点击确定. 方法2 也 ...