一致性Hash的原理是什么

发布时间:2021-06-30 17:32:39 作者:chen
来源:亿速云 阅读:136

本篇内容主要讲解“一致性Hash的原理是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“一致性Hash的原理是什么”吧!

一、前言

在解决分布式系统中负载均衡的问题时候可以使用Hash算法让固定的一部分请求落到同一台服务器上,这样每台服务器固定处理一部分请求(并维护这些请求的信息),起到负载均衡的作用。

但是普通的余数hash(hash(比如用户id)%服务器机器数)算法伸缩性很差,当新增或者下线服务器机器时候,用户id与服务器的映射关系会大量失效。一致性hash则利用hash环对其进行了改进。

二、一致性Hash概述

为了能直观的理解一致性hash原理,这里结合一个简单的例子来讲解,假设有4台服务器,地址为ip1,ip2,ip3,ip4。

如上图可知user1,user2的请求会落到服务器ip2进行处理,User3的请求会落到服务器ip3进行处理,user4的请求会落到服务器ip4进行处理,user5,user6的请求会落到服务器ip1进行处理。

下面考虑当ip2的服务器挂了的时候会出现什么情况?
当ip2的服务器挂了的时候,一致性hash环大致如下图:

一致性Hash的原理是什么

image.png

根据顺时针规则可知user1,user2的请求会被服务器ip3进行处理,而其它用户的请求对应的处理服务器不变,也就是只有之前被ip2处理的一部分用户的映射关系被破坏了,并且其负责处理的请求被顺时针下一个节点委托处理。

下面考虑当新增机器的时候会出现什么情况?
当新增一个ip5的服务器后,一致性hash环大致如下图:

一致性Hash的原理是什么

image.png

根据顺时针规则可知之前user5的请求应该被ip1服务器处理,现在被新增的ip5服务器处理,其他用户的请求处理服务器不变,也就是新增的服务器顺时针最近的服务器的一部分请求会被新增的服务器所替代。

三、一致性hash的特性

服务器ip1,ip2,ip3经过hash后落到了一致性hash环上,从图中hash值分布可知ip1会负责处理大概80%的请求,而ip2和ip3则只会负责处理大概20%的请求,虽然三个机器都在处理请求,但是明显每个机器的负载不均衡,这样称为一致性hash的倾斜,虚拟节点的出现就是为了解决这个问题。

五、虚拟节点

当服务器节点比较少的时候会出现上节所说的一致性hash倾斜的问题,一个解决方法是多加机器,但是加机器是有成本的,那么就加虚拟节点,比如上面三个机器,每个机器引入1个虚拟节点后的一致性hash环的图如下:

一致性Hash的原理是什么

image.png

其中ip1-1是ip1的虚拟节点,ip2-1是ip2的虚拟节点,ip3-1是ip3的虚拟节点。
可知当物理机器数目为M,虚拟节点为N的时候,实际hash环上节点个数为M*N。比如当客户端计算的hash值处于ip2和ip3或者处于ip2-1和ip3-1之间时候使用ip3服务器进行处理。

六、均匀一致性hash

上节我们使用虚拟节点后的图看起来比较均衡,但是如果生成虚拟节点的算法不够好很可能会得到下面的环:

一致性Hash的原理是什么

image.png

可知每个服务节点引入1个虚拟节点后,情况相比没有引入前均衡性有所改善,但是并不均衡。

均衡的一致性hash应该是如下图:

一致性Hash的原理是什么

image.png

均匀一致性hash的目标是如果服务器有N台,客户端的hash值有M个,那么每个服务器应该处理大概M/N个用户的。也就是每台服务器负载尽量均衡

七、总结

在分布式系统中一致性hash起着不可忽略的地位,无论是分布式缓存,还是分布式Rpc框架的负载均衡策略都有所使用。

================================================================

服务端处理客户端写入请求的伪代码:

public void handleWrite(WriteMessage wm){

    //从写入消息中获取key
    String key=wm.getKey();
    
    //计算实际处理该写入消息的节点编号
    int handlerID=key.hashCode() % ClusterNodeNum;
    
    //判断写入消息是否由本服务器处理
    if(MyClusterID==handleID){
        
        //该写入消息由本服务器处理,写入磁盘
        writeMessage(wm);
    }else{
        //将写入消息发送给对应的服务器处理
        sendMessage(handleID,wm);
    }
    
    //通知客户端写入成功
    sendtoClient("write success");

}


服务端处理客户端读取请求的伪代码:

public void handleRead(ReadMessage rm){

    //从读取消息中获取key
    String key=rm.getKey();
    
    //计算实际处理该读取消息的节点编号
    int handlerID=key.hashCode() % ClusterNodeNum;
    
    //用于存储读取的数据
    String readData="";
    
    //判断读取消息是否由本服务器处理
    if(MyClusterID==handleID){
        
        //该读取消息由本服务器处理,写入磁盘
        readData=readMessage(rm);
    }else{
        //将读取消息发送给对应的服务器处理
        readData=readMessage(handleID,rm);
    }
    
    //通知客户端读取成功
    sendtoClient(readData);

}


客户端调动服务器端的伪代码:

public static void main(String[] args){

    Random rnd=new Random();
    
    //所有服务器列表
    String[] servers=new String[]("192.168.10.0","192.168.10.1","192.168.10.2","192.168.10.3","192.168.10.4");
    
    //随机算法选择一个服务器,进行负载均衡
    Client client = new Client(servers[rnd.nextInt(servers.length)]);

    //向服务器写入数据
    client.write(new WriteMessage("key1","value1"));
    
    //从服务器读取数据
    String value=client.read(new ReadMessage("key1"));
}

到此,相信大家对“一致性Hash的原理是什么”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

推荐阅读:
  1. IsPostBack的原理是什么
  2. Elasticsearch的原理是什么

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

hash

上一篇:Java中怎么将xml转换为Json

下一篇:springboot2.1.6集成elasticsearch6.4.3如何实现全文搜索

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》