dubbo源码解析-详解LoadBalance

前言

终于到了集群容错中的最后一个关键词,也就是LoadBalance(负载均衡),负载均衡必然会涉及一些算法.但是也不用太担心,算法这个词虽然高大上,但是算法也有简单和复杂之分.既然是源码解析类的文章,那么就有义务让看不懂代码的看文章总结都能明白原理的义务.所以本篇尽量用一些简单的数学式子和流程图和大家一起梳理一下这些集群容错算法.

为了方便大家找到前几篇dubbo集群容错的文章,这里做一下小的目录跳转,后面会再弄一篇专门的目录:

dubbo源码解析-集群容错架构设计

dubbo源码解析-directory

dubbo源码解析-router

dubbo源码解析-cluster

插播面试题

为了能够带着面试题去看文章,我把这个插播面试题的环节放在了前面比较显眼的位置

谈谈dubbo中的负载均衡算法及特点

最小活跃数算法中是如何统计这个活跃数的

简单谈谈你对一致性哈希算法的认识

直入主题

我们还是按照惯例来看看接口的继承图

下面就对这四种负载均衡策略依次解析

RandomLoadBalance(随机)

引用文档介绍

随机,按权重设置随机概率。

在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。

这个随机的策略是默认的策略,但是这个随机和我们理解上的随机还是不一样的,因为他还有个概念叫weight(权重),这个"权重"的概念Android的同学一定不会陌生,因为在LinearLayout布局中就有这个概念,在前端的CSS框架Bootstrap的栅格和也有类似概念.说白了,这里说的权重就是用来控制这个随机的概率的,我们来看代码实现.

如果暂时没明白没关系,可以看看下面的流程图和数学分析

流程图

数学分析

假设有四个集群节点A,B,C,D,对应的权重分别是1,2,3,4,那么请求到A节点的概率就为1/(1+2+3+4) = 10%.B,C,D节点依次类推为20%,30%,40%.

敲黑板划重点

虽然这个随机算法理解起来是比较容易的,面试一般不会问这个,但是假如我们要实现类似的功能,他这个代码实现的思路还是很优雅的,非常具有借鉴意义.他这个实现思路从纯数学角度是很好理解的,我们还是按照上面数学分析中的前提条件.我们知道总权重为10(1+2+3+4),那么怎么做到按权重随机呢?根据10随机出一个整数,假如为随机出来的是2.然后依次和权重相减,比如2(随机数)-1(A的权重) = 1,然后1(上一步计算的结果)-2(B的权重) = -1,此时-1 < 0,那么则调用B,其他的以此类推

RoundRobinLoadBalance(轮询)

引用文档介绍

轮循,按公约后的权重设置轮循比率。

存在慢的提供者累积请求的问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。

这个可以先网上搜索一下权重轮询调度算法,因为Nginx的负载均衡默认就是轮询,所以我打算后面专门写一篇详细讲一下这个算法.

LeastActiveLoadBalance(最少活跃数)

引用文档介绍

最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。

使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。

看完文档可能还是不明白究竟是什么意思,那我举个例子.每个服务有一个活跃计数器,那么我们假如有A,B两个提供者.计数均为0.当A提供者开始处理请求,该计数+1,此时A还没处理完,当处理完后则计数-1.而B请求接收到请求处理得很快.B处理完后A还没处理完,所以此时A,B的计数为1,0.那么当有新的请求来的时候,就会选择B提供者(B的活跃计数比A小).这就是文档说的,使慢的提供者收到更少请求

那么我们来看代码实现

看不懂代码没关系,我讲一下他的思路,这部分代码概括起来就两部分,一部分是活跃数和权重的统计,另一部分是选择invoker.也就是他把最小活跃数的invoker统计到leastIndexs数组中,如果权重一致(这个一致的规则参考上面的随机算法)或者总权重为0,则均等随机调用,如果不同,则从leastIndexs数组中按照权重比例调用(还是和随机算法中的那个依次相减的思路一样).还不明白没关系,看下面的流程图和数学分析

流程图

数学分析

假设A,B,C,D节点的最小活跃数分别是1,1,2,3,权重为1,2,3,4.则leastIndexs(该数组是最小活跃数组,因为A,B的活跃数是1,均为最小)数组内容为[A,B].A,B的权重是1和2,所以调用A的概率为 1/(1+2) = 1/3,B的概率为 2/(1+2) = 2/3

敲黑板划重点

活跃数的变化是在com.alibaba.dubbo.rpc.filter.ActiveLimitFilter中,如果没有配置dubbo:reference的actives属性,默认是调用前活跃数+1,调用结束-1,鉴于很多人可能没用过这个属性,所以我把文档截图贴出来

另外如果使用该种负载均衡算法,则dubbo:service中还需要配置filter="activelimit"

ConsistentHashLoadBalance(一致性哈希)

引用文档介绍

一致性 Hash,相同参数的请求总是发到同一提供者。

当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。

算法参见:http://en.wikipedia.org/wiki/Consistent_hashing

缺省只对第一个参数 Hash,如果要修改,请配置

<dubbo:parameter key="hash.arguments" value="0,1" 

缺省用 160 份虚拟节点,如果要修改,请配置

<dubbo:parameter key="hash.nodes" value="320" />

该算法的代码实现拿出来讲的话篇幅较大,这个一致性哈希算法在缓存例如redis的面试题中也经常喜欢问到,网上也有很多相关的文章,我这里主要是想用大白话来讲一下,主要讲三个关键词,原理,down机影响,虚拟节点

原理

简单讲就是,假设我们有个时钟,各服务器节点映射放在钟表的时刻上,把key也映射到钟表的某个时刻上,然后key顺时针走,碰到的第一个节点则为我们需要找的# # 服务器节点

还是假如我们有a,b,c,d四个节点(感觉整篇文章都在做这个假如....),把他们通过某种规则转成整数,分别为0,3,6,9.所以按照时钟分布如下图

假设这个key通过某种规则转化成1,那么他顺时针碰到的第一个节点就是b,也就是b是我们要找的节点

那么我们可能就有疑问了,这个某种规则究竟是什么规则?

这个规则你可以自己设计,但是要注意的是,不同的节点名,转换为相同的整数的概率就是衡量这个规则的好坏,如果你能做到不同的节点名唯一对应一个整数,那就是棒棒哒.当然java里面的CRC32这个类你可以了解一下.

说到这里可能又会有另个疑问,时钟点数有限,万一装不下怎么办

其实这个时钟只是方便大家理解做的比喻而已,在实际中,我们可以在圆环上分布[0,2^32-1]的数字,这量级全世界的服务器都可以装得下.

down机影响

通过上图我们可以看出,当b节点挂了之后,根据顺时针的规则,那么目标节点就是c,也就是说,只影响了一个节点,其他节点不受影响.

如果是轮询的取模算法,假设从N台服务器变成了N-1台,那么命中率就变成1/(N-1),因此服务器越多,影响也就越大.

虚拟节点

为什么要有虚拟节点的概念呢?我们还是回到第一个假设,我们还是有a,b,c,d四个节点,他们通过某个规则转化成0,3,6,9这种自然是均匀的.但是万一是0,1,2,3这样,那就是非常不均匀了.事实上, 一般的Hash函数对于节点在圆环上的映射,并不均匀.所以我们需要引入虚拟节点,那么什么是虚拟节点呢?

假如有N个真实节点,把每个真实节点映射成M个虚拟节点,再把 M*N 个虚拟节点, 散列在圆环上. 各真实节点对应的虚拟节点相互交错分布这样,某真实节点down后,则把其影响平均分担到其他所有节点上.

也就是a,b,c,d的虚拟节点a0,a1,a2,b0,b1,b2,c0,c1,c2,d0,d1,d2散落在圆环上,假设C号节点down,则c0,c1,c2的压力分别传给d0,a1,b1,如下图

写在末尾

dubbo系列集群容错的写到这里就基本结束了,下一部分大家是想看服务发布和服务引用还是网络通信,编解码呢?欢迎在简书留言告诉我.如果对你有所帮助,希望点赞,关注支持.鉴于本人才疏学浅,不对的地方还望斧正,也欢迎关注我的简书,名称为肥朝

链接:https://www.jianshu.com/p/53feb7f5f5d9

原文发布于微信公众号 - java进阶架构师(java_jiagoushi)

原文发表时间:2018-08-16

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏芋道源码1024

Dubbo 源码解析 —— LoadBalance

前言 终于到了集群容错中的最后一个关键词,也就是 LoadBalance(负载均衡),负载均衡必然会涉及一些算法.但是也不用太担心,算法这个词虽然高大上,但是算...

3984
来自专栏专知

【最新TensorFlow1.4.0教程01】TF1.4.0介绍与动态图机制 Eager Execution使用

【导读】主题链路知识是我们专知的核心功能之一,为用户提供AI领域系统性的知识学习服务,一站式学习人工智能的知识,包含人工智能( 机器学习、自然语言处理、计算机视...

3998
来自专栏专知

【前沿】Pytorch开源VQA神经网络模块,让你快速完成看图问答

【导读】近期,NLP专家Harsh Trivedi使用Pytorch实现了一个视觉问答的神经模块网络,想法是参考CVPR2016年的论文《Neural Modu...

3018
来自专栏PPV课数据科学社区

手把手教你用1行代码实现人脸识别 -- Python Face_recognition

环境要求: Ubuntu17.10 Python 2.7.14 环境搭建: 1. 安装 Ubuntu17.10 > 安装步骤在这里 2. 安装 Python2....

4388
来自专栏机器之心

资源 | TensorFlow分布式计算机制解读:以数据并行为重

选自clindatsci 作者:Neil Tenenholtz 机器之心编译 参与:Jane W、黄小天 Tensorflow 是一个为数值计算(最常见的是训...

4247
来自专栏北京马哥教育

手把手教你用 1 行命令实现人脸识别

? 人脸识别很难吗? -- Kangvcar 本文导航 ◈ 环境要求00% ◈ 环境搭建03% ◈ 实现人脸识别19% ◈ 示例一(1 行命令实现人脸识别):...

3626
来自专栏小巫技术博客

A008-drawable资源

关于drawable资源笔者之前有写过两篇文章: Android-自定义图像资源的使用(1) Android-自定义图像资源的使用(2) 这里笔者就不做过多的赘...

812
来自专栏专知

【干货】快速上手图像识别:用TensorFlow API实现图像分类实例

【导读】1月17日,Arduino社区的编辑SAGAR SHARMA发布一篇基于TensorFlow API的图像识别实例教程。作者通过TensorFlow A...

9017
来自专栏IT派

干掉照片中那些讨厌的家伙!Mask R-CNN助你一键“除”人!

【导读】:看过英剧《黑镜》吗?圣诞特别版《白色圣诞节》中有这样一个场景:其中一个未来科技有自由屏蔽人像的功能,可以让你屏蔽任何一个不想看见或不喜欢的人,然后留下...

1190
来自专栏实用工具入门教程

如何部署 TensorFlow 服务器

TensorFlow是一款由Google构建的用于训练神经网络的开源机器学习软件。TensorFlow的神经网络以有状态数据流图的形式表示。图中的每个节点表示神...

6133

扫码关注云+社区

领取腾讯云代金券