静态Hash解决数据颠簸问题
在做服务器负载均衡时候可供选择的负载均衡的算法有很多,包括: 轮循算法(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算法为例说明(参考memcached的分布式算法 )。
由于hash算法结果一般为unsigned int型,因此对于hash函数的结果应该均匀分布在[0,232 -1]间,如果我们把一个圆环用232 个点来进行均匀切割,首先按照hash(key)函数算出服务器(节点)的哈希值, 并将其分布到0~232 的圆上。
用同样的hash(key)函数求出需要存储数据的键的哈希值,并映射到圆上。然后从数据映射到的位置开始顺时针查找,将数据保存到找到的第一个服务器(节点)上。
Consistent Hashing原理示意图
1. 新增一个节点:只有在圆环上新增节点到逆时针方向的第一个节点之间的数据会受到影响(增加节点顺时针的第一个节点的信息需要迁移到增加节点上)。
2. 删除一个节点:只有在圆环上原来删除节点到 逆时针 方向的第一个节点之间的数据会受到影响(删除节点的信息需要迁移到顺时针的第一个节点上) ,因此通过Consistent Hashing很好地解决了负载均衡中由于新增节点、删除节点引起的hash值颠簸问题。
Consistent Hashing添加服务器示意图
虚拟节点(virtual nodes): 之所以要引进虚拟节点是因为在服务器(节点)数较少的情况下(例如只有3台服务器),通过hash(key)算出节点的哈希值在圆环上并不是均匀分布的(稀疏的),仍然会出现各节点负载不均衡的问题。虚拟节点可以认为是实际节点的复制品(replicas),本质上与实际节点实际上是一样的(key并不相同)。引入虚拟节点后,通过将每个实际的服务器(节点)数按照一定的比例(例如200倍)扩大后并计算其hash(key)值以均匀分布到圆环上。在进行负载均衡时候,落到虚拟节点的哈希值实际就落到了实际的节点上。由于所有的实际节点是按照相同的比例复制成虚拟节点的,因此解决了节点数较少的情况下哈希值在圆环上均匀分布的问题。
虚拟节点对Consistent Hashing结果的影响
从上图可以看出,在节点数为10个的情况下,每个实际节点的虚拟节点数为实际节点的100-200倍的时候,结果还是很均衡的。
2、Consistent Hashing算法实现:
文章Consistent Hashing 中描述了Consistent Hashing的Java实现,很简洁。
- import java.util.Collection;
- import java.util.SortedMap;
- import java.util.TreeMap;
- public class ConsistentHash<T> {
- private final HashFunction hashFunction;
- private final int numberOfReplicas;
- private final SortedMap<Integer, T> circle = new TreeMap<Integer, T>();
- public ConsistentHash(HashFunction hashFunction, int numberOfReplicas,
- Collection<T> nodes) {
- this.hashFunction = hashFunction;
- this.numberOfReplicas = numberOfReplicas;
- for (T node : nodes) {
- add(node);
- }
- }
- public void add(T node) {
- for (int i = 0; i < numberOfReplicas; i++) {
- circle.put(hashFunction.hash(node.toString() + i), node);
- }
- }
- public void remove(T node) {
- for (int i = 0; i < numberOfReplicas; i++) {
- circle.remove(hashFunction.hash(node.toString() + i));
- }
- }
- public T get(Object key) {
- if (circle.isEmpty()) {
- return null;
- }
- int hash = hashFunction.hash(key);
- if (!circle.containsKey(hash)) {
- SortedMap<Integer, T> tailMap = circle.tailMap(hash);
- hash = tailMap.isEmpty() ? circle.firstKey() : tailMap.firstKey();
- }
- return circle.get(hash);
- }
- }
静态Hash解决数据颠簸问题相关推荐
- hive解决数据倾斜问题_Hive数据倾斜和解决办法
转自:https://blog.csdn.net/xinzhi8/article/details/71455883 操作: 关键词 情形 后果 Join 其中一个表较小,但是key集中 分发到某一个或 ...
- Hive 性能优化(全面)解决数据倾斜等问题
Hive性能优化(全面) 1.介绍 首先,我们来看看Hadoop的计算框架特性,在此特性下会衍生哪些问题? 数据量大不是问题,数据倾斜是个问题. jobs数比较多的作业运行效率相对比较低,比如即使有几 ...
- Hive性能优化(全面)解决数据倾斜等问题
Hive性能优化(全面) 1.介绍 首先,我们来看看Hadoop的计算框架特性,在此特性下会衍生哪些问题? 数据量大不是问题,数据倾斜是个问题. jobs数比较多的作业运行效率相对比较低,比如即使有几 ...
- Android产品研发(十)--尽量不使用静态变量保存数据
转载请标明出处:一片枫叶的专栏 上一篇文章中我们讲解了Android开发过程中几种常见网络协议:xml,json,protobuf等,以及它们各自的优缺点,一般而言当我们的App涉及到了网络传输时都会 ...
- 【javaWeb微服务架构项目——乐优商城day11】——利用RabbitMQ实现搜索和静态页的数据同步
文章目录 0.学习目标 1.RabbitMQ 1.1.搜索与商品服务的问题 1.2.消息队列(MQ) 1.2.1.什么是消息队列 1.2.2.AMQP和JMS 1.2.3.常见MQ产品 1.2.4.R ...
- 影像组学视频学习笔记(30)-SMOTE解决数据不平衡的问题、Li‘s have a solution and plan.
本笔记来源于B站Up主: 有Li 的影像组学系列教学视频 本节(30)主要介绍: SMOTE解决数据不平衡的问题 SMOTE基本介绍 SMOTE (Synthetic Minority Over-sa ...
- 独家 | 识别并解决数据质量问题的数据科学家指南
作者:Arunn Thevapalan 翻译:陈超校对:王紫岳本文约3000字,建议阅读9分钟 本文介绍了Python中的Ydata-quality库如何应用于数据质量诊断,并给出数据实例进行详细的一 ...
- IBM 数据科学平台三大特性解决数据科学家协作问题
虽然数据科学是一个比较火爆的话题,也受到越来越多重视,但是企业内部数据科学现状却是:不同数据分析人员使用着包括Python.R.Spark在内的多种开源产品,并且版本不一:不同开源技术的使用导致数据资 ...
- 【Spark篇】---Spark解决数据倾斜问题
[Spark篇]---Spark解决数据倾斜问题 参考文章: (1)[Spark篇]---Spark解决数据倾斜问题 (2)https://www.cnblogs.com/LHWorldBlog/p/ ...
最新文章
- 机器学习驱动技术是生物学进步的下一个突破
- python条件控制语句_Python课堂笔记 条件控制语句
- 看完这一系列,彻底搞懂 Gradle
- NC107617 poj3020 Antenna Placement
- java等待_Java学习:等待唤醒机制
- DrawerLayout 使用
- jqueryAjax的使用
- WorkSbell第10周2017
- spring3.0学习之环境搭建
- Android学习路线图
- 2021年计算机网络常见面试题
- Apache Spark源码剖析
- win10下SVN图标不显示
- 最新正则表达式验证手机号和邮箱
- 资金管理的意义与如何制定资金管理计划
- 物联网应用网站——用户手册
- ECMAScript 语法
- 如何用python制作云词图
- 勒索病毒2019年常见的后缀有ITLOCK/AOL/VC/phobos/ETH/x3m/qwex/H
- 什么是招标控制价?与标底价有什么区别
热门文章
- 四大CPU体系结构:ARM、X86/Atom、MIPS、PowerPC
- [Android通信]基于socket的聊天app(七):好友分组
- ffmpeg视频转码工具安装
- java 使用浏览器下载图片
- .NET平台系列22:.NET Core/.NET5/.NET6 对比 .NET Framework
- php的表单提交之上传文件
- vue项目的搭建和常见问题的解决
- GPRS上网打开普通页面的流量
- 去南宁市图书馆泡了一晚上~编写文件粉碎机之惑
- 手机音质变差_手机听歌音质差?这些音质大坑你跳了几个