一致性Hash算法及Java实践

目录

一、案例背景

1.1 系统简介

1.2 遇到问题

1.3 初步优化

1.4 继续优化

二、使用一致性Hash解决问题

三、一致性Hash介绍

3.1 理论简介

3.2 设计实现

四、对一致性Hash的理解

4.1 应用场景

4.2 环的Hash数量的选择

4.3 虚拟节点的作用

4.4 Hash算法的选择

4.5 一致性Hash的替代

五、案例

5.1 需求

5.2 算法 

5.3 测试 

5.5 多次实验结果


一、案例背景

1.1 系统简介

  首先看一下系统架构,方便解释:

  页面给用户展示的功能就是,可以查看任何一台机器的某些属性(以下简称系统信息)。

  消息流程是,页面发起请求查看指定机器的系统信息到后台,后台可以查询到有哪些server在提供服务,根据负载均衡算法(简单的轮询)指定由哪个server进行查询,并将消息发送到Kafka,然后所有的server消费Kafka的信息,当发现消费的信息要求自己进行查询时,就连接指定的machine进行查询,并将结果返回回去。

  Server是集群架构,可能动态增加或减少。

  至于架构为什么这么设计,不是重点,只能说这是符合当时环境的最优架构。

1.2 遇到问题

  遇到的问题就是慢,特别慢,经过初步核实,最耗时的事是server连接machine的时候,基本都要5s左右,这是不能接受的。

1.3 初步优化

  因为耗时最大的是server连接machine的时候,所以决定在server端缓存machine的连接,经过测试如果通过使用的连接缓存进行查询,那么耗时将控制在1秒以内,满足了用户的要求,不过还有一个问题因此产生,那就是根据现有负载均衡算法,假如server1已经缓存了到machine1的连接,但是再次查询时,请求就会发送到下一个server,如server2,这就导致了两个问题,一是,重新建立了连接耗时较长,二是,两个server同时缓存着到machine1的连接,造成了连接浪费。

1.4 继续优化

  一开始想到最简单的就是将查询的machine进行hash计算,并除sever的数量取余,这样保证了查询同一个machine时会要求同一个server进行操作,满足了初步的需求。但是因为server端是集群,机器有可能动态的增加或减少,假如根据hash计算,指定的 machine会被指定的server连接,如下图:

  然后又增加了一个server,那么根据当前的hash算法,server和machine的连接就会变成如下:

  可以发现,四个machine和server的连接关系发生变化了,这将导致4次连接的初始化,以及四个连接的浪费,虽然server集群变动的几率很小,但是每变动一次将有一半的连接作废掉,这还是不能接受的,当时想的最理想的结果是:

  • 当新增机器的时候,原有的连接分一部分给新机器,但是除去分出的连接以外保持不变
  • 当减少机器的时候,将减少机器的连接分给剩下的机器,但剩下机器的原有连接不变

  简单来说,就是变动不可避免但是让变动最小化。根据这种思想,就想到了一致性hash,觉得这个应该可以满足要求。

二、使用一致性Hash解决问题

  一致性Hash的定义或者介绍在第三节,现在写出一致性Hash的Java的解决方法。只写出示例实现代码,首先最重要的就是Hash算法的选择,根据现有情况以及已有Hash算法的表现,选择了FNV Hash算法,以下是其实现:

public static int FnvHash(String key) {
  final int p = 16777619;
  long hash = (int) 2166136261L;
  for (int i = 0,n = key.length(); i < n; i++){
    hash = (hash ^ key.charAt(i)) * p;
  }
  hash += hash << 13;
  hash ^= hash >> 7;
  hash += hash << 3;
  hash ^= hash >> 17;
  hash += hash << 5;
  return ((int) hash & 0x7FFFFFFF);
}

  然后是对能提供服务的server进行预处理:

public static ConcurrentSkipListMap<Integer, String> init(){
  //创建排序Map方便后面的计算
  ConcurrentS
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值