The Power of Two Random Choices
1. 介绍
常见的Load balance算法想必大家都不陌生,Random、Round-robin、Least connection、Consistent hash等应该都耳熟能详,这些算法都在实践中有广泛的应用,例如Nginx、Haproxy等负载均衡模块都有相应算法的实现。本文将和大家分享一种全新的Load balance算法:Power of Two Random Choices[1],也算是Fast 2019 best paper解读《Distcache: Provable load balancing for large-scale storage systems with distributed caching》 的续篇,DistCache利用Power of two random choices实现Cache Query的Load balance:就是在查询Cache中item的时候,从命中的2个Cache节点中选择负载较低的Cache节点来服务;实现简单,效果却不简单。除此之外,新版本的Nginx和Haproxy最近都增加了对Power of Two Random Choices算法的支持[8、9],可见一斑。
本文将从Power of Two Random Choices算法的起源说起(也就是数学里面经典的Balls into Bins问题[4、5]),向大家展示Power of Two Random Choices算法背后的数学原理。并介绍其在解决Hash冲突中的应用,想必能进一步加深大家对Cuckoo Hash、BloomFilter等使用多个hash function做法的理解。
2. Balls into Bins
首先看数学一个经典的Balls into Bins问题[4]:
假如顺序地将n个Balls投入到n个bins(垃圾桶),策略是从n个bin中随机独立均匀地选择任意一个bin
那么当抛球结束的时候,以非常高的概率( 也就是以概率1-o(1)
),n个bin中最大负载为(1+o(1))logn/loglogn
个balls。注意o(1)
指的是高阶无穷小,可以直接忽略掉。
这实际上就是一个无状态的Load balance问题,考虑一个负载均衡器(LB)将n个请求随机等概率的发送给n个Server,那么就可以知道Server上最大的可能负载会是多少。
3. Power of two random choices
如果选择上做一个小改动,也就是今天要说的Power of two random choices[1]:
假如顺序地将n个Balls投入到n个bins(垃圾桶),策略是从n个bin中随机独立均匀地选择d个bin,然后选择Ball最少的bin放入
那么当抛球结束的时候,将以非常高的概率( 也就是以概率1-o(1)
),n个bin中最大负载为(1+o(1))loglogn/logd+O(1)
个balls。
现在情况Balls的数量往往远大于Bins的数量,所以扩展一下[5]:
假如顺序地将m个Balls投入到n个bins(垃圾桶),策略是从n个bin中随机独立均匀地选择d个bin,然后选择Ball最少的bin放入,其中m>=n,d>=2
下面给出一个一组计算的算例,分别m=n={2^2,2^3,2^4......,2^64},其中红色为普通的Balls into Bins问题的最大负载,蓝色为Power of two random choices d=2情况下的最大负载:
通过上图可以发现,Power of two random choices负载均衡的效果是不错的。尽管上面的模型太过理想,假定了所有的key都是必须均匀分布,每个request的size都是相同,和实际生产环境相差巨大,但仍然不妨碍我们认定这种做法的有效性。
4. App
(1)Load balance
得益于Power of Two Random Choices的实现简单和效果良好,开源的NGINX在版本1.15.1中开始支持[8],Haproxy也在2.0版本中开始支持,且将其替换成了默认的随机算法[9],文献[9]中Haproxy有一些对比测试,大家可以参考。
(2)Hash
如果使用这种方法来解决Hash冲突,以开链(separate chaining)法为例,如果每次选择哈希映射的桶时,通过两个hash function随机挑出两个桶,并从中选择链表长度相对更短的桶插入[10](如下图),根据Power of Two Rand Choices理论,那么每个hash bucket的开链长度肯定会更加均衡。
实际上回过头来看Cuckoo Hash、BloomFilter设计多个hash function是有道理的。
如上图,是一个Cuckoo Hash一种典型实现,通过两个hash函数来映射key,且每个bucket都可以存放多个items,实际上根据Power of Two Random Choices的原理,这样,可以使得每个bucket的冲突更加均衡,从而可以在设计Cuckoo hash的时候设置较小的Bucket容量,避免空间浪费,或者换一个角度,可以延迟resize hash的发生。
5. Summary
Power of two random choices尽管是一种理想的理论模型,但是方法和思路仍然可以作为生产实践的指导,这也大概是理论研究的意义所在。
(需要特别声明的是,限于本人是个数学渣渣,所以第2、3小节数学分析大家悠着点看,有任何错误的地方,轻喷)。
鸣谢
非常感谢
@林谨
对文章[6]中存在问题的指出,让学习到了两个非常有意思东西:(1)Small cache, big effect[7];(2)Power of two random choices[1]。关于Fast2019 DistCache更深入的解读可以参考
@林谨
的博文[2],娓娓道来,非常深入,值得拥有。
Notes
限于作者水平,难免在理解和描述上有疏漏或者错误的地方,欢迎共同交流;部分参考已经在正文和参考文献列表中注明,但仍有可能有疏漏的地方,有任何侵权或者不明确的地方,欢迎指出,必定及时更正或者删除;文章供于学习交流,转载注明出处
参考
[1]. Mitzenmacher M. The power of two choices in randomized load balancing[J]. IEEE Transactions on Parallel and Distributed Systems, 2001, 12(10): 1094-1104.
[2]. FAST 2019 DistCache. https://jimchenglin.github.io/2019/04/15/FAST-2019-DistCache/
[3]. [1]. Liu Z, Bai Z, Liu Z, et al. Distcache: Provable load balancing for large-scale storage systems with distributed caching[C]//17th {USENIX} Conference on File and Storage Technologies ({FAST} 19). 2019: 143-157.
[4]. 皇甫先鹏, 罗雪山. 基于非对称 balls-into-bins 的高效平衡负载分配模型[J]. 国防科技大学学报, 2013, 35(3): 67-71.
[5]. Balls into bins problem. https://en.wikipedia.org/wiki/Balls_into_bins_problem
[6]. Load balancing for large-scale storage systems. https://zhuanlan.zhihu.com/p/64265624
[7]. Fan B, Lim H, Andersen D G, et al. Small cache, big effect: Provable load balancing for randomly partitioned cluster services[C]//Proceedings of the 2nd ACM Symposium on Cloud Computing. ACM, 2011: 23.
[8]. NGINX and the “Power of Two Choices” Load-Balancing Algorithm. https://www.nginx.com/blog/nginx-power-of-two-choices-load-balancing-algorithm/
[9]. Test Driving “Power of Two Random Choices” Load Balancing. https://www.haproxy.com/blog/power-of-two-load-balancing/
[10]. 随机的力量(1) - The power of random two choices. https://blog.csdn.net/three_body/article/details/49538777
The Power of Two Random Choices相关推荐
- python random.sample()和random.choices()
python random.sample()和random.choices() s = random.sample(list, k) sample 是相当于不放回抽样.如果列表中的数据不重复,抽取数据 ...
- 随机的力量(1) - The power of random two choices
我们都知道对于哈希函数来说,有一个绕不开的话题就是冲突. 当N个object通过随机函数映射到N个桶的时候,可能由于冲突而出现Hash(x) = Hash(y)的情况.经典的处理哈希冲突的方法包括链表 ...
- The evolution of cluster scheduler architectures--转
原文地址:http://www.firmament.io/blog/scheduler-architectures.html cluster schedulers are an important c ...
- 服务器开发设计之算法宝典
作者:lynhlzou,腾讯 IEG 后台开发工程师 孙子云:"上兵伐谋,其次伐交,其次伐兵,其下攻城",最上乘行军打仗的方式是运用谋略,下乘的方式才是与敌人进行惨烈的厮杀.同样的 ...
- random模块下的常用函数Python choices()方法练习
random int #random.randint 返回a和b之间的整数,包前不包后 a = 1 b = 10 import random random.randint(a,b) >>& ...
- Python学习:random模块下的choices()函数详解
1.random.choice(seq)函数 从非空序列中随机选取一个数据并返回,该序列可以是list.tuple.str.set. 举例: import random print(random.ch ...
- Python choices()函数详解、random模块下的常用函数
random模块下的方法详解: 1.random.random() 随机生成一个[0,1)之间的浮点数. 2.random.randint(a,b) 随机生成[a,b]范围内一个整数. 3.rando ...
- Python random 随机函数(random、uniform、randint、choice、choices、randrange、shuffle、sample)
注意:当前使用环境为 Python 3.11.0 1.random.random() 用于生成一个 0 到 1 的随机符点数: 0 <= n < 1.0. # 代码 import rand ...
- random模块——生成伪随机数
查看模块包含的全部属性和函数: __all__变量代表了该模块开放的公开接口 import random random.__all__ random.seed(a=None,version=2):指定 ...
最新文章
- 云上人替代方案训练代码
- 如何在Linux上找到包含特定文本的所有文件?
- stm32怎么查看什么原因引起的nmi_为什么会有口臭,口臭是什么原因引起的,口臭是怎么回事...
- 有关机械手臂控制中的两个重要输入参数
- linux从别的主机下载,从局域网内的其他Linux主机下载文件
- php获得表单数值,php 表单数据的获取代码
- office2007过期后没有输入序列号对话框的激活方法
- python代码实现自动登录
- 如何从任何Mac或Windows PC为iOS打印启用AirPrint
- 安卓手机root推荐,导出安卓分区镜像
- TeXLive2021+TeXStudio安装及配置,亲测有效!
- 批量保存网页_一键保存网页图片!macOS自带神器,比《快捷指令》还好用
- Python接口自动化
- [ERROR] No plugin found for prefix ‘mybatis-generator‘ in the current project and in the plugin grou
- 特斯拉又发生车祸!电池夜间还自燃3次
- 计算机评语公式怎么输,excel公式写评语
- springboot基于webrtc和janus的视频会议流程图
- 《伟大是熬出来的》冯仑与年轻人闲话人生之三
- 面试公司Offer——我的Python求职之路
- git重新设置用户名密码