(十一) Nepxion-Thunder分布式RPC集成框架 - 负载均衡和同步中心

Nepxion-Thunder(QQ 群 471164539)发布在https://github.com/Nepxion/

 
负载均衡和同步中心只应用于Netty和Hessian

 

  • loadbalance - 负载均衡
    consistenthash - 一致性Hash算法
    random - 随机算法
    roundrobin - 轮询算法
  • consistency - 同步中心

 1. 负载均衡

负载均衡接口LoadBalanceExecutor.java,根据提供的接口名负载均衡到某一个ApplicationEntity(服务host和port)。代码如下:

public interface LoadBalanceExecutor extends ThunderDelegate {  
    // 负载均衡
    ConnectionEntity loadBalance(String interfaze) throws Exception;
}
负载均衡抽象类AbstractLoadBalanceExecutor.java
  • 一致性Hash算法
    一致性哈希算法是分布式系统中常用的算法。比如,一个分布式的存储系统,要将数据存储到具体的节点上,如果采用普通的hash方法,将数据映射到具体的节 点上,如key%N,key是数据的key,N是机器节点数,如果有一个机器加入或退出这个集群,则所有的数据映射都无效了,如果是持久化存储则要做数据 迁移,如果是分布式缓存,则其他缓存就失效了。
    因此,引入了一致性哈希算法:



    把数据用hash函数(如MD5),映射到一个很大的空间里,如图所示。数据的存储时,先得到一个hash值,对应到这个环中的每个位置,如k1对应到了图中所示的位置,然后沿顺时针找到一个机器节点B,将k1存储到B这个节点中。

    如果B节点宕机了,则B上的数据就会落到C节点上,如下图所示: 


     

    这样,只会影响C节点,对其他的节点A,D的数据不会造成影响。然而,这又会造成一个“雪崩”的情况,即C节点由于承担了B节点的数据,所以C节点的负载会变高,C节点很容易也宕机,这样依次下去,这样造成整个集群都挂了。

    为此,引入了“虚拟节点”的概念:即把想象在这个环上有很多“虚拟节点”,数据的存储是沿着环的顺时针方向找一个虚拟节点,每个虚拟节点都会关联到一个真实节点,如下图所使用:


     

    图中的A1、A2、B1、B2、C1、C2、D1、D2都是虚拟节点,机器A负载存储A1、A2的数据,机器B负载存储B1、B2的数据,机器C负载存储C1、C2的数据。由于这些虚拟节点数量很多,均匀分布,因此不会造成“雪崩”现象。

    Thunder实现的一致性Hash算法,基于MemCache Spy的ketama源码改造而来的,具体实现不介绍了,可以参考它的源码。这里讲解把
    ketama应用于Thunder的一致性hash。代码如下:
    由初始化的服务列表(ApplicationEntity)构造KetamaNodeLocator,算法是DefaultHashAlgorithm.KETAMA_HASH。当本地服务列表和远程服务列表不一致时,执行locator.updateLocator
    locator.getPrimary(UUID.randomUUID().toString())是核心部分,用随机字符串去碰撞一致性Hash环里的节点,最终达到负载均衡

  • 随机算法
    随机从一群服务中挑选一个可用服务返回
  • 轮询算法
    把一群有序服务,从头到尾方式访问,如果达到尾部后,再回到头部方法,周而复始的循环

 2. 同步中心

同步中心接口ConsistencyExecutor.java,实现本地服务列表和远程注册中心保持同步一致。代码如下:

public interface ConsistencyExecutor extends ThunderDelegate {
    // 接受注册中心上下线事件,本地缓存与注册中心保持一致
    void consist(ServiceInstanceEvent event) throws Exception;
}
 接口中的update方法,将被注册中心的ZookeeperInstancesWatcher.java所调用

猜你喜欢

转载自nepxion.iteye.com/blog/2260172