你好,我是Weiki,欢迎来到猿java。

前言

在实际的开发工作中,我们经常会遇到单个集群的性能瓶颈问题,比如Redis的主从模式,MySQL的主从模式,因为写操作只能在主节点,所以主节点的写性能将会是整个集群的写能力瓶颈,如何解决这个问题?

答案:分集群,突破单集群的性能限制

开发经验丰富一些的小伙伴肯定马上会想到增加一个 Proxy 层,由 Proxy 层处理来自客户端的读写请求,然后由Proxy对 Key 做哈希把请求路由到对应的集群。比如Codis就是基于这种Proxy方式,下文就介绍2种经典的hash路由算法。

Hash算法

假设有 A、B、C 三个节点,当用户的请求过来时,可以在Proxy代理层,对某个设定的key进行hash计算,然后用hash(key)对节点总数做取模操作,这样相同key的请求总是能路由到相同的节点上,如下图:

hash集群
假如,随着业务的发展,用户量越来越大,原来的A,B,C3个节点无法承受用户端的流量压力,这时需要增加一个节点,如下图:

扩容

从上图我们可以看出,当增加一个节点D时,原来的路由算法需要从 hash(key)%3 变成 hash(key)%4,那么会出现什么问题?

假如 hash(key) = 100,hash(key)%3 = 1, hash(key)%4=0,此时 计算的结果值就发生了变化,对于同一个请求,扩容前路由到序号1节点(节点B),扩容后路由到序号0节点(A节点),寻址发生变化,请求在节点B能获取数据,在A节点获取失败,则这种扩容方式降导致请求获取数据失败,带来的问题将是灾难性的。

缩容

同理:比如因为疫情,用户量越来越少,原本需要3个节点,现在2个节点就能满足需求,需要进行缩容,如下图:

缩容,同样会出现扩容时寻址失败的问题,可以采取迁移数据的方式来解决:

比如:

扩容操作,扩容前路由到A节点,扩容后路由到B节点,可以把数据从A节点迁移到B节点,满足新的路由方式;

缩容操作,同理。

但是当数据量比较大的时候迁移数据的也是需要代价的,有没有更好的方式来降低这种数据迁移?

** 答案:一致性hash

一致性hash算法

一致性hash算法也是采用取模运算,但与hash不同的是,哈希算法是对节点的总数进行取模运算,当节点的数量发生变化时,取模的结果会发生变化,而一致哈希算法是对 2^32-1 这个固定的数值进行取模运算,所以hash(key)算法不变,取模的结果就不变。

实际上,一致性hash是将整个哈希值空间组织成一个虚拟的圆环,也就是哈希环,如下图:

假如有A,B,C3个节点,当需要对 key 的值进行读写操作时,可以按照下面 2 步进行寻址:

  • 对key 进行 c-hash() 计算,并确定此 key 在环上的位置;
  • 从key所在的这个位置沿着哈希环顺时针"行走",遇到的第一节点就是 key 对应的节点;

如下图: hash(keyA)%232寻址到节点A,hash(keyB)%232寻址到节点B,hash(keyC)%2^32寻址到节点C

扩容

当增加一个集群D,keyC原本是寻址路由到节点C,现在寻址路由到节点D,因此受影响的key是节点B到节点D之间的所有请求,其他的key不受影响。

缩容

当缩容节点C时,keyC 原本寻址路由到节点C,按照一致性hash的原理,顺时针寻找到最近的一个节点A,所以节点B到节点C之间的key将受到影响,寻址路由到新的节点A。

通过上面对一致性hash扩缩容的分析可以知道,当对节点进行扩缩容时,受影响的key是局部的,需要迁移的数据也可控,而且可以推到出随着节点的增多,受影响的key会成反比下降。

公平性

如下图,当hash换上的节点分布不均匀时,节点A承受了70%的流量,而节点B,C只承受了30%的流量,这样就会导致数据访问的冷热不均,造成不公平,如何解决?

答案: 虚拟节点

如下图:在节点C和节点A中增加了一个虚拟节点X,真实指向节点B,这样keyD原本路由到节点A,现在路由到节点B,这样就解决了数据访问的冷热不均造成的不公平问题。

总结

  • hash算法是对节点总数进行取模进行寻址路由,因此,对于扩缩容频繁,或者数据量比较大的业务场景可能会出现大量的数据迁移,不太适用。
  • 一致性hash是一种特殊的hash算法,节点增减变化只影响到部分数据的路由寻址,因此只需要迁移部分数据,就能实现集群的稳定。
  • 一致性hash算法,当节点数较少时,可能会出现节点在哈希环上分布不均匀的情况,最终导致业务对节点的访问冷热不均,可以通过引入更多的虚拟节点来解决。
  • 一致性hash算法具有较好的容错性和可扩展性

最后

如果你觉得本博文对你有帮助,感谢转发给更多的好友,我们将为你呈现更多的干货, 欢迎关注公众号:猿java

为什么有了哈希算法还需要一致性哈希?相关推荐

  1. 先来先服务算法代码_一致性哈希算法编写

    今天我想先给大家科普下一致性哈希算法这块,因为我下一篇文章关于缓存的高可用需要用到这个,但是又不能直接在里面写太多的代码以及关于一致性hash原理的解读,这样会失去对于缓存高可用的理解而且会造成文章很 ...

  2. 一致性哈希 数据迁移 mysql_一致性哈希算法解决分布式数据扩容

    一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法,设计目标是为了解决因特网中的热点(Hot spot)问题,初衷和CARP十分类似.一致性哈希修正了CARP使用的简 单哈 ...

  3. 什么是哈希算法?什么是哈希冲突以及怎样解决哈希冲突?

    哈希(Hash)算法,即散列函数.它是一种单向密码体制,即它是一个从明文到密文的不可逆的映射,只有加密过程,没有解密过程.同时,哈希函数可以将任意长度的输入经过变化以后得到固定长度的输出.哈希函数的这 ...

  4. 一致性哈希 php redis,使用一致性哈希实现Redis分布式部署

    像Memcache以及其它一些内存K/V数据库一样,Redis本身不提供分布式支持,所以在部署多台Redis服务器时,就需要解决如何把数据分散到各个服务器的问题,并且在服务器数量变化时,能做到最大程度 ...

  5. 使用哈希算法进行文件一致性校验

    文件一致性校验原因: 为了确保你得到的文件是正确的版本,而没有被注入病毒和木马程序.例如我们经常在网上下载软件,而这些软件已经被注入了一些广告和病毒等,如果不进行文件与原始发布商的一致性校验的话,可能 ...

  6. java 一致性hash算法 均衡分发_Dubbo一致性哈希负载均衡的源码和Bug,了解一下?...

    本文是对于Dubbo负载均衡策略之一的一致性哈希负载均衡的详细分析.对源码逐行解读.根据实际运行结果,配以丰富的图片,可能是东半球讲一致性哈希算法在Dubbo中的实现最详细的文章了. 文中所示源码,没 ...

  7. 面试时遇到一致性哈希算法这样回答会让面试官眼前一亮

    [CSDN 编者按]很多人都知道什么是哈希函数,在后端面试和开发中会遇到"一致性哈希",那什么是一致性哈希呢,当面试官问到你又该如何给出漂亮的回答. 作者 | 丁威       责 ...

  8. 一致性哈希算法 mysql_一致性哈希算法,在分布式开发中你必须会写,来看完整代码...

    今天我想先给大家科普下一致性哈希算法这块,因为我下一篇文章关于缓存的高可用需要用到这个,但是又不能直接在里面写太多的代码以及关于一致性hash原理的解读,这样会失去对于缓存高可用的理解而且会造成文章很 ...

  9. 哪种一致性哈希算法才是解决分布式缓存问题的王者?

    哪种一致性哈希算法才是解决分布式缓存问题的王者? 一致性哈希是由Karger等人于1997年提出的一种特殊的哈希算法,目的是解决分布式缓存的问题,现在在分布式系统中有着广泛的应用.本文将对ketama ...

  10. 一致性哈希算法--数据库应用

    背景   在分布式数据库中,尤其是Share nothing的MPP架构中,为了充分利用每台服务器的资源,通常会将超大表数据进行分片分布到多个数据节点中,提升数据库的查询性能.   分区并不是生成新的 ...

最新文章

  1. 微程序控制器原理(增量方式和断定方式结合法)
  2. Megastore:为交互式服务提供可扩展的高可用性存储
  3. 【PHP】详解 $_SERVER 函数中QUERY_STRING和REQUEST_URI、SCRIPT_NAME、PHP_SELF区别
  4. LeetCode 132. 分割回文串 II(DP)
  5. Hive的使用之控制台
  6. 中国电子学会scratch等级考试二级
  7. 9:16 2009-7-30 范型,IList 做为参数
  8. 数据库笔记08:实现索引
  9. 内核与ramdisk到底是什么关系
  10. 文件夹去掉git版本控制_git 从版本控制中删除文件及.gitignore的用法
  11. 机器学习算法总结之支持向量机(三)
  12. python-78:对日期格式进行处理
  13. 【语音识别】基于matlab GUI HMM 0~9数字和汉字语音识别(带面板)【含Matlab源码 1716期】
  14. 优必选悟空智能机器人怎么读绘本_优必选发布悟空机器人及操作系统ROSA,关于估值这么回应…...
  15. 数据算法_数据结构和常用算法
  16. JDK API下载
  17. 黑客帝国_屏幕保护程序
  18. 数据库实验 实验三 数据查询
  19. 开关switch系列:android Switch显示文字
  20. 查看电脑ip地址是否被占用

热门文章

  1. eboot.php如何转成iso,如何转换成iso格式
  2. 计算机设备布局图,电脑主板插槽对应哪些硬件?详细的主板布局图解
  3. 阿里云部署RSSHub踩坑笔记
  4. [高级]pdf生成(可水印)、pdf预览(可分页)、pdf打印:全栈一条龙方案
  5. 【制作脑图】万彩脑图大师教程 | 展开/折叠分支
  6. QQ桌球瞄准器开发(5)使用注册表保存配置
  7. bzoj 2959: 长跑
  8. 研究生学习生活日记——slow down
  9. Java线程何时放弃CPU时间片
  10. linux MySQL .sock_Linux 下找不到 mysql.sock 的解决方法