点击上方 "程序员小乐"关注, 星标或置顶一起成长

每天凌晨00点00分, 第一时间与你相约

每日英文

If you concentrate on the ONE thing in your life that makes you truly happy... everything else in your life will fall into place.

如果人只关注着真正带给自己快乐的事,那其余一切,就都清晰明了了。

每日掏心话

任何经历,都是一种积累;积累越多,人就越成熟。经历越多,生命就越有长度;经历越广,生命就越有厚度;

来自:MarkLux | 责编:乐乐

链接:marklux.cn/blog/90

程序员小乐(ID:study_tech)第 837 次推文 图片来自百度

往日回顾:Springboot + Vue + shiro 实现前后端分离、权限控制

正文

简介

一致性Hash是一种特殊的Hash算法,由于其均衡性、持久性的映射特点,被广泛的应用于负载均衡领域,如nginx和memcached都采用了一致性Hash来作为集群负载均衡的方案。
本文将介绍一致性Hash的基本思路,并讨论其在分布式缓存集群负载均衡中的应用。同时也会进行相应的代码测试来验证其算法特性,并给出和其他负载均衡方案的一些对比。

一致性Hash算法简介

在了解一致性Hash算法之前,先来讨论一下Hash本身的特点。普通的Hash函数最大的作用是散列,或者说是将一系列在形式上具有相似性质的数据,打散成随机的、均匀分布的数据。
比如,对字符串abc和abcd分别进行md5计算,得到的结果如下:

可以看到,两个在形式上非常相近的数据经过md5散列后,变成了完全随机的字符串。负载均衡正是利用这一特性,对于大量随机的请求或调用,通过一定形式的Hash将他们均匀的散列,从而实现压力的平均化。(当然,并不是只要使用了Hash就一定能够获得均匀的散列,后面会分析这一点。)
举个例子,如果我们给每个请求生成一个Key,只要使用一个非常简单的Hash算法Group = Key % N来实现请求的负载均衡,如下:

(如果将Key作为缓存的Key,对应的Group储存该Key的Value,就可以实现一个分布式的缓存系统,后文的具体例子都将基于这个场景)
不难发现,这样的Hash只要集群的数量N发生变化,之前的所有Hash映射就会全部失效。如果集群中的每个机器提供的服务没有差别,倒不会产生什么影响,但对于分布式缓存这样的系统而言,映射全部失效就意味着之前的缓存全部失效,后果将会是灾难性的。
一致性Hash通过构建环状的Hash空间代替线性Hash空间的方法解决了这个问题,如下图:

整个Hash空间被构建成一个首尾相接的环,使用一致性Hash时需要进行两次映射。
第一次,给每个节点(集群)计算Hash,然后记录它们的Hash值,这就是它们在环上的位置。
第二次,给每个Key计算Hash,然后沿着顺时针的方向找到环上的第一个节点,就是该Key储存对应的集群。
分析一下节点增加和删除时对负载均衡的影响,如下图:

可以看到,当节点被删除时,其余节点在环上的映射不会发生改变,只是原来打在对应节点上的Key现在会转移到顺时针方向的下一个节点上去。增加一个节点也是同样的,最终都只有少部分的Key发生了失效。不过发生节点变动后,整体系统的压力已经不是均衡的了,下文中提到的方法将会解决这个问题。

问题与优化

最基本的一致性Hash算法直接应用于负载均衡系统,效果仍然是不理想的,存在诸多问题,下面就对这些问题进行逐个分析并寻求更好的解决方案。

数据倾斜

如果节点的数量很少,而hash环空间很大(一般是 0 ~ 2^32),直接进行一致性hash上去,大部分情况下节点在环上的位置会很不均匀,挤在某个很小的区域。最终对分布式缓存造成的影响就是,集群的每个实例上储存的缓存数据量不一致,会发生严重的数据倾斜。

缓存雪崩

如果每个节点在环上只有一个节点,那么可以想象,当某一集群从环中消失时,它原本所负责的任务将全部交由顺时针方向的下一个集群处理。例如,当group0退出时,它原本所负责的缓存将全部交给group1处理。这就意味着group1的访问压力会瞬间增大。
设想一下,如果group1因为压力过大而崩溃,那么更大的压力又会向group2压过去,最终服务压力就像滚雪球一样越滚越大,最终导致雪崩。

引入虚拟节点

解决上述两个问题最好的办法就是扩展整个环上的节点数量,因此我们引入了虚拟节点的概念。一个实际节点将会映射多个虚拟节点,这样Hash环上的空间分割就会变得均匀。
同时,引入虚拟节点还会使得节点在Hash环上的顺序随机化,这意味着当一个真实节点失效退出后,它原来所承载的压力将会均匀地分散到其他节点上去。
如下图:

代码测试

现在我们尝试编写一些测试代码,来看看一致性hash的实际效果是否符合我们预期。
首先我们需要一个能够对输入进行均匀散列的Hash算法,可供选择的有很多,memcached官方使用了基于md5的KETAMA算法,但这里处于计算效率的考虑,使用了FNV1_32_HASH算法,如下:public class HashUtil {
/**
* 计算Hash值, 使用FNV1_32_HASH算法
* @param str
* @return
*/
public static int getHash(String str) {
final int p = 16777619;
int hash = (int)2166136261L;
for (int i = 0; i < str.length(); i++) {
hash =( hash ^ str.charAt(i) ) * p;
}
hash += hash << 13;
hash ^= hash >> 7;
hash += hash << 3;
hash ^= hash >> 17;
hash += hash << 5;
if (hash < 0) {
hash = Math.abs(hash);
}
return hash;
}
}
实际使用时可以根据需求调整。
接着需要使用一种数据结构来保存hash环,可以采用的方案有很多种,最简单的是采用数组或链表。但这样查找的时候需要进行排序,如果节点数量多,速度就可能变得很慢。
针对集群负载均衡状态读多写少的状态,很容易联想到使用二叉平衡树的结构去储存,实际上可以使用TreeMap(内部实现是红黑树)来作为Hash环的储存结构。
先编写一个最简单的,无虚拟节点的Hash环测试: public class ConsistentHashingWithoutVirtualNode {
/**
* 集群地址列表
*/
private static String[] groups = {
"192.168.0.0:111

压力测试过负载均衡_一致性 Hash 在负载均衡中的应用相关推荐

  1. hash地址_一致性Hash在负载均衡中的应用

    作者:marklux 原文:http://marklux.cn/blog/90 简介 一致性Hash是一种特殊的Hash算法,由于其均衡性.持久性的映射特点,被广泛的应用于负载均衡领域,如nginx和 ...

  2. crc32算法_一致性hash算法负载均衡

    有没有好奇过redis.memcache等是怎么实现集群负载均衡的呢? 其实他们都是通过一致性hash算法实现节点调度的. 讲一致性hash算法前,先简述一下求余hash算法: hash(object ...

  3. 一致性 Hash 在负载均衡中的应用

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:干掉 Navicat:这个 IDEA 的兄弟真香!个人原创100W+访问量博客:点击前往,查看更多 转自:Mar ...

  4. 聊聊一致性Hash在负载均衡中的应用

    作者:marklux http://marklux.cn/blog/90 简介 一致性Hash是一种特殊的Hash算法,由于其均衡性.持久性的映射特点,被广泛的应用于负载均衡领域,如nginx和mem ...

  5. 一致性Hash在负载均衡中的应用

    简介 一致性Hash是一种特殊的Hash算法,由于其均衡性.持久性的映射特点,被广泛的应用于负载均衡领域,如nginx和memcached都采用了一致性Hash来作为集群负载均衡的方案.本文将介绍一致 ...

  6. 详解【负载均衡】(负载均衡算法、一致性hash、负载均衡架构分析)

    作者:duktig 博客:https://duktig.cn 优秀还努力.愿你付出甘之如饴,所得归于欢喜. 本文源码参看:https://github.com/duktig666/distribute ...

  7. nginx负载均衡之一致性Hash方式

    ip_hash方式 关于nginx的负载均衡,大家都知道有一个ip_hash的方式,就是将客户端的ip取hash值,然后根据服务器 的数量取模,得出的值就是最后被路由到的服务器(服务器从0开始数),但 ...

  8. hash oracle 分表_一致性Hash算法在数据库分表中的实践

    最近有一个项目,其中某个功能单表数据在可预估的未来达到了亿级,初步估算在90亿左右.与同事详细讨论后,决定采用一致性Hash算法来完成数据库的自动扩容和数据迁移.整个程序细节由我同事完成,我只是将其理 ...

  9. hash算法_一致性hash算法简介

    一致性hash算法有什么用?我们为什么需要一致性hash算法?这两个问题的答案可以看这篇文章 分布式系统路由算法简介. 了解了一致性hash算法出现的背景,我们来看看什么是一致性hash算法.一致性h ...

最新文章

  1. layui 日历选中日期,自动填充
  2. 将中文日期转换成自己想要的格式如:2018年09月29日转换成2018-09-29
  3. BEC攻击危害惊人 3年造成23亿美元损失
  4. 《梦断代码》读后笔记_2
  5. 优先队列如何按照pair 的第二关键字排序(对比vector按照pair第二关键字排序)
  6. 成功解决pywintypes.com_error: (-2147352573, ‘找不到成员。‘, None, None)
  7. Oracle分组取出每组的第一笔数据
  8. 集合遍历[设计模式总结] 9. 迭代器模式
  9. find函数matlab_Matlab 数值数据
  10. 计算机应用基础计算配置教案,[定稿]计算机应用基础教案_Windows_XP版V8.1(全文完整版)...
  11. 对Web设计有用的10组免费漂亮的图标
  12. NLP(三) 预处理
  13. RecyclerView混合布局
  14. VisualStudio2017编写masm32汇编程序以及语法高亮配置
  15. ong拼音汉字_汉语拼音ang-ong(教案)
  16. unity 接入移动MM (3.1.10)
  17. VS2019提示“未能完成操作,不支持此接口”
  18. Linux文件裸写,linux环境先mkfs后写裸盘
  19. SpringBoot整合Dubbo
  20. sql Server STUFF()函数

热门文章

  1. 2022谈谈海信电视/U盘装软件
  2. TX9118 同步升压IC
  3. gamma校正 matlab,Gamma校正 ——图像灰度变化 OpenCV (十)
  4. System Verilog学习笔记—接口interface
  5. cad lisp程序大集,超经典CAD lisp程序集锦、CAD快捷键大全
  6. 超频 电压 测试软件,超频测试及总结
  7. 刷qcn工具|大部分机型qcn文件集合|亲测有效
  8. Jmeter最新安装配置
  9. 计算机审计oa操作规程,OA自动化自动化和计算机系统审计.pdf
  10. leetcode-77-组合